diff --git a/.gn b/.gn index ea10b98c..e24f89e 100644 --- a/.gn +++ b/.gn
@@ -84,13 +84,144 @@ #"//chrome/android/*", # 13 errors "//chrome/app/*", "//chrome/app_shim/*", + #"//chrome/browser/*", # ~1300 errors + #"//chrome/browser:*", # ~600 errors + "//chrome/browser/accessibility/*", "//chrome/browser/android/*", - "//chrome/browser/vr/*", + "//chrome/browser/app_mode/*", + #"//chrome/browser/apps/*", # 2 errors + "//chrome/browser/assist_ranker/*", + "//chrome/browser/autocomplete/*", + "//chrome/browser/autofill/*", + "//chrome/browser/background/*", + "//chrome/browser/background_fetch/*", + "//chrome/browser/background_sync/*", + "//chrome/browser/banners/*", + "//chrome/browser/bitmap_fetcher/*", + "//chrome/browser/bookmarks/*", + "//chrome/browser/browsing_data/*", + "//chrome/browser/budget_service/*", + "//chrome/browser/captive_portal/*", + "//chrome/browser/chooser_controller/*", "//chrome/browser/chromeos/*", + "//chrome/browser/client_hints/*", + "//chrome/browser/clipboard/*", + "//chrome/browser/component_updater/*", + "//chrome/browser/conflicts/*", + "//chrome/browser/consent_auditor/*", + "//chrome/browser/content_settings/*", + "//chrome/browser/crash_upload_list/*", + "//chrome/browser/custom_handlers/*", + "//chrome/browser/data_saver/*", + "//chrome/browser/data_use_measurement/*", + "//chrome/browser/dbus/*", + #"//chrome/browser/devtools/*", # 93 errors + "//chrome/browser/diagnostics/*", + "//chrome/browser/domain_reliability/*", + "//chrome/browser/dom_distiller/*", + "//chrome/browser/downgrade/*", + "//chrome/browser/download/*", + "//chrome/browser/drive/*", + "//chrome/browser/engagement/*", "//chrome/browser/extensions/*", + "//chrome/browser/external_protocol/*", + "//chrome/browser/favicon/*", + "//chrome/browser/feature_engagement/*", + "//chrome/browser/feedback/*", + "//chrome/browser/first_run/*", + "//chrome/browser/gcm/*", + "//chrome/browser/generic_sensor/*", + "//chrome/browser/geolocation/*", + "//chrome/browser/google/*", + "//chrome/browser/gpu/*", + "//chrome/browser/guest_view/*", + "//chrome/browser/hang_monitor/*", + "//chrome/browser/history/*", + "//chrome/browser/importer/*", + "//chrome/browser/infobars/*", + "//chrome/browser/installable/*", + "//chrome/browser/install_verification/*", + "//chrome/browser/internal/*", + "//chrome/browser/interstitials/*", + "//chrome/browser/invalidation/*", + "//chrome/browser/language/*", + "//chrome/browser/lifetime/*", + #"//chrome/browser/loader/*", # 2 errors + "//chrome/browser/local_discovery/*", + "//chrome/browser/mac/*", + #"//chrome/browser/media/*", # 74 errors + "//chrome/browser/media_galleries/*", + "//chrome/browser/memory/*", + "//chrome/browser/metrics/*", + "//chrome/browser/nacl_host/*", + "//chrome/browser/navigation_predictor/*", + "//chrome/browser/net/*", + "//chrome/browser/notifications/*", + "//chrome/browser/ntp_snippets/*", + "//chrome/browser/ntp_tiles/*", + "//chrome/browser/obsolete_system/*", + "//chrome/browser/offline_items_collection/*", + "//chrome/browser/offline_pages/*", + "//chrome/browser/page_load_metrics/*", + "//chrome/browser/password_manager/*", + "//chrome/browser/payments/*", + "//chrome/browser/pdf/*", + "//chrome/browser/performance_monitor/*", + "//chrome/browser/permissions/*", + "//chrome/browser/picture_in_picture/*", + "//chrome/browser/plugins/*", + # "//chrome/browser/policy/*", # 1 error on Windows + "//chrome/browser/predictors/*", + "//chrome/browser/prefetch/*", + "//chrome/browser/prefs/*", + "//chrome/browser/prerender/*", + "//chrome/browser/previews/*", + "//chrome/browser/printing/*", + "//chrome/browser/profile_resetter/*", + "//chrome/browser/profiles/*", + #"//chrome/browser/profiling_host/*", # 16 errors + "//chrome/browser/push_messaging/*", + "//chrome/browser/recovery/*", + "//chrome/browser/renderer_context_menu/*", + "//chrome/browser/renderer_host/*", "//chrome/browser/resource_coordinator/*", + #"//chrome/browser/resources/*", # 18 errors on ChromeOS + "//chrome/browser/rlz/*", + #"//chrome/browser/safe_browsing/*", # 239 errors + "//chrome/browser/search/*", + "//chrome/browser/search_engines/*", + "//chrome/browser/search_provider_logos/*", + "//chrome/browser/service_process/*", + "//chrome/browser/sessions/*", + "//chrome/browser/signin/*", + "//chrome/browser/speech/*", + "//chrome/browser/spellchecker/*", + "//chrome/browser/ssl/*", + "//chrome/browser/status_icons/*", + "//chrome/browser/storage/*", + "//chrome/browser/subresource_filter/*", + "//chrome/browser/supervised_user/*", + "//chrome/browser/sync/*", + "//chrome/browser/sync_file_system/*", + "//chrome/browser/tab_contents/*", + "//chrome/browser/task_manager/*", + "//chrome/browser/themes/*", + "//chrome/browser/thumbnails/*", + "//chrome/browser/tracing/*", + "//chrome/browser/translate/*", "//chrome/browser/ui/*", + "//chrome/browser/undo/*", + "//chrome/browser/unified_consent/*", + "//chrome/browser/update_client/*", + "//chrome/browser/upgrade_detector/*", + "//chrome/browser/usb/*", + "//chrome/browser/vr/*", + #"//chrome/browser/web_applications/*", # 66 errors + "//chrome/browser/webauthn/*", + "//chrome/browser/webshare/*", + "//chrome/browser/win/*", + "//chrome/build/*", #"//chrome/child/*", # 1 error on Windows "//chrome/chrome_cleaner/*",
diff --git a/DEPS b/DEPS index 13c2fb5e..85dace1 100644 --- a/DEPS +++ b/DEPS
@@ -105,7 +105,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. - 'skia_revision': 'c97a339cd60116451f626da92c88a8c02cb48fbf', + 'skia_revision': 'b631742f0bff361efccf53687ddfad551a51e398', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. @@ -117,11 +117,11 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling ANGLE # and whatever else without interference from each other. - 'angle_revision': '21e5e85a4976de15e252167936fd3adb876bb7da', + 'angle_revision': 'c1551dc2a7dcee0fd1309996e670342472ae7c56', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling build tools # and whatever else without interference from each other. - 'buildtools_revision': '9a90d9aaadeb5e04327ed05775f45132e4b3523f', + 'buildtools_revision': '2dff9c9c74e9d732e6fe57c84ef7fd044cc45d96', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. @@ -129,7 +129,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling PDFium # and whatever else without interference from each other. - 'pdfium_revision': '55ccb526913debb3269a33792bbd61b05656ec46', + 'pdfium_revision': '48ae3075a5c80e75923a60d4d0ba0b56d9b08c2a', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling openmax_dl # and whatever else without interference from each other. @@ -161,7 +161,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling HarfBuzz # and whatever else without interference from each other. - 'harfbuzz_revision': 'b6fdcf4f8bd09e065c767939125861c9dc8ff18f', + 'harfbuzz_revision': '22defe0965adddaa09eebc13df7fa6c64e2abba3', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling catapult # and whatever else without interference from each other. @@ -552,7 +552,7 @@ # Build tools for Chrome OS. Note: This depends on third_party/pyelftools. 'src/third_party/chromite': { - 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '21a68ae8e5fa4dfd5dd2c3aeb619227e7ea3ff4e', + 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '70284b596877a3a5538bb5d8b0ac526a7f298f3a', 'condition': 'checkout_linux', }, @@ -577,7 +577,7 @@ }, 'src/third_party/depot_tools': - Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'af03ae194f784a9ba5e21e1a9524883482f819b6', + Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'ba883cb5ed14aac5d81d6105caabf505c3afe8c6', 'src/third_party/devtools-node-modules': Var('chromium_git') + '/external/github.com/ChromeDevTools/devtools-node-modules' + '@' + Var('devtools_node_modules_revision'), @@ -927,7 +927,7 @@ }, 'src/third_party/perfetto': - Var('android_git') + '/platform/external/perfetto.git' + '@' + '624fec3ddbea9b462b7d4fe95b0416673cbd193d', + Var('android_git') + '/platform/external/perfetto.git' + '@' + '2ae6f8e569a3e78076427ea81757869b4df7596c', 'src/third_party/perl': { 'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + 'ac0d98b5cee6c024b0cffeb4f8f45b6fc5ccdb78',
diff --git a/android_webview/DEPS b/android_webview/DEPS index 0b24be7..8ea0912d 100644 --- a/android_webview/DEPS +++ b/android_webview/DEPS
@@ -31,6 +31,7 @@ "+services/viz/public/interfaces", "+skia", "+third_party/skia/include", + "+third_party/boringssl/src/include", "+ui/android", "+ui/base", "+ui/gfx",
diff --git a/android_webview/browser/net/aw_url_request_context_getter.cc b/android_webview/browser/net/aw_url_request_context_getter.cc index 9d28b87..6222725 100644 --- a/android_webview/browser/net/aw_url_request_context_getter.cc +++ b/android_webview/browser/net/aw_url_request_context_getter.cc
@@ -38,6 +38,7 @@ #include "content/public/common/content_switches.h" #include "content/public/common/url_constants.h" #include "net/base/cache_type.h" +#include "net/cert/cert_verifier.h" #include "net/cookies/cookie_store.h" #include "net/dns/mapped_host_resolver.h" #include "net/extras/sqlite/sqlite_channel_id_store.h" @@ -176,31 +177,6 @@ return job_factory; } -// For Android WebView, do not enforce policies that are not consistent with -// the underlying OS validator. -// This means not enforcing the Legacy Symantec PKI policies outlined in -// https://security.googleblog.com/2017/09/chromes-plan-to-distrust-symantec.html -// or disabling SHA-1 for locally-installed trust anchors. -class AwSSLConfigService : public net::SSLConfigService { - public: - AwSSLConfigService() { - default_config_.symantec_enforcement_disabled = true; - default_config_.sha1_local_anchors_enabled = true; - } - - void GetSSLConfig(net::SSLConfig* config) override { - *config = default_config_; - } - - bool CanShareConnectionWithClientCerts( - const std::string& hostname) const override { - return false; - } - - private: - net::SSLConfig default_config_; -}; - } // namespace AwURLRequestContextGetter::AwURLRequestContextGetter( @@ -344,9 +320,18 @@ CreateAuthHandlerFactory(host_resolver.get())); builder.set_host_resolver(std::move(host_resolver)); - builder.set_ssl_config_service(std::make_unique<AwSSLConfigService>()); - url_request_context_ = builder.Build(); + + // For Android WebView, do not enforce policies that are not consistent with + // the underlying OS validator. + // This means not enforcing the Legacy Symantec PKI policies outlined in + // https://security.googleblog.com/2017/09/chromes-plan-to-distrust-symantec.html + // or disabling SHA-1 for locally-installed trust anchors. + net::CertVerifier::Config config; + config.enable_sha1_local_anchors = true; + config.disable_symantec_enforcement = true; + url_request_context_->cert_verifier()->SetConfig(config); + #if DCHECK_IS_ON() g_created_url_request_context_builder = true; #endif
diff --git a/android_webview/browser/net/aw_url_request_context_getter_unittest.cc b/android_webview/browser/net/aw_url_request_context_getter_unittest.cc index eb990c8..1812b99 100644 --- a/android_webview/browser/net/aw_url_request_context_getter_unittest.cc +++ b/android_webview/browser/net/aw_url_request_context_getter_unittest.cc
@@ -14,16 +14,22 @@ #include "content/public/common/url_constants.h" #include "content/public/test/test_browser_thread_bundle.h" #include "net/base/net_errors.h" +#include "net/base/test_completion_callback.h" +#include "net/cert/cert_verifier.h" +#include "net/cert/test_root_certs.h" #include "net/log/net_log.h" +#include "net/log/net_log_with_source.h" #include "net/proxy_resolution/proxy_config_service.h" #include "net/proxy_resolution/proxy_config_service_android.h" #include "net/proxy_resolution/proxy_resolution_service.h" -#include "net/ssl/ssl_config.h" -#include "net/ssl/ssl_config_service.h" +#include "net/test/cert_test_util.h" +#include "net/test/gtest_util.h" +#include "net/test/test_data_directory.h" #include "net/test/url_request/url_request_failed_job.h" #include "net/url_request/url_request_context.h" #include "net/url_request/url_request_job_factory.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/boringssl/src/include/openssl/pool.h" namespace android_webview { @@ -95,13 +101,33 @@ TEST_F(AwURLRequestContextGetterTest, SymantecPoliciesExempted) { net::URLRequestContext* context = getter_->GetURLRequestContext(); ASSERT_TRUE(context); - net::SSLConfigService* config_service = context->ssl_config_service(); - ASSERT_TRUE(config_service); - net::SSLConfig config; - EXPECT_FALSE(config.symantec_enforcement_disabled); - config_service->GetSSLConfig(&config); - EXPECT_TRUE(config.symantec_enforcement_disabled); + scoped_refptr<net::X509Certificate> cert = + net::CreateCertificateChainFromFile(net::GetTestCertsDirectory(), + "www.ahrn.com.pem", + net::X509Certificate::FORMAT_AUTO); + ASSERT_TRUE(cert); + ASSERT_EQ(2u, cert->intermediate_buffers().size()); + + scoped_refptr<net::X509Certificate> root = + net::X509Certificate::CreateFromBuffer( + bssl::UpRef(cert->intermediate_buffers().back()), {}); + ASSERT_TRUE(root); + net::ScopedTestRoot test_root(root.get()); + + net::CertVerifyResult result; + int flags = 0; + net::TestCompletionCallback callback; + std::unique_ptr<net::CertVerifier::Request> request; + int error = context->cert_verifier()->Verify( + net::CertVerifier::RequestParams(cert, "www.ahrn.com", flags, + std::string(), net::CertificateList()), + nullptr, &result, callback.callback(), &request, net::NetLogWithSource()); + EXPECT_THAT(error, net::test::IsError(net::ERR_IO_PENDING)); + EXPECT_TRUE(request); + + error = callback.WaitForResult(); + EXPECT_THAT(error, net::test::IsError(net::OK)); } // Tests that SHA-1 is still allowed for locally-installed trust anchors, @@ -110,13 +136,36 @@ TEST_F(AwURLRequestContextGetterTest, SHA1LocalAnchorsAllowed) { net::URLRequestContext* context = getter_->GetURLRequestContext(); ASSERT_TRUE(context); - net::SSLConfigService* config_service = context->ssl_config_service(); - ASSERT_TRUE(config_service); - net::SSLConfig config; - EXPECT_FALSE(config.sha1_local_anchors_enabled); - config_service->GetSSLConfig(&config); - EXPECT_TRUE(config.sha1_local_anchors_enabled); + net::CertificateList certs; + ASSERT_TRUE(net::LoadCertificateFiles( + {"weak_digest_sha1_ee.pem", "weak_digest_sha1_intermediate.pem", + "weak_digest_sha1_root.pem"}, + &certs)); + ASSERT_EQ(3u, certs.size()); + + std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates; + intermediates.push_back(bssl::UpRef(certs[1]->cert_buffer())); + scoped_refptr<net::X509Certificate> cert = + net::X509Certificate::CreateFromBuffer( + bssl::UpRef(certs[0]->cert_buffer()), std::move(intermediates)); + ASSERT_TRUE(cert); + + net::ScopedTestRoot test_root(certs[2].get()); + + net::CertVerifyResult result; + int flags = 0; + net::TestCompletionCallback callback; + std::unique_ptr<net::CertVerifier::Request> request; + int error = context->cert_verifier()->Verify( + net::CertVerifier::RequestParams(cert, "127.0.0.1", flags, std::string(), + net::CertificateList()), + nullptr, &result, callback.callback(), &request, net::NetLogWithSource()); + EXPECT_THAT(error, net::test::IsError(net::ERR_IO_PENDING)); + EXPECT_TRUE(request); + + error = callback.WaitForResult(); + EXPECT_THAT(error, net::test::IsError(net::OK)); } } // namespace android_webview
diff --git a/ash/accessibility/accessibility_controller.cc b/ash/accessibility/accessibility_controller.cc index e35a334..ae467fe 100644 --- a/ash/accessibility/accessibility_controller.cc +++ b/ash/accessibility/accessibility_controller.cc
@@ -16,7 +16,6 @@ #include "ash/high_contrast/high_contrast_controller.h" #include "ash/policy/policy_recommendation_restorer.h" #include "ash/public/cpp/ash_pref_names.h" -#include "ash/public/cpp/config.h" #include "ash/public/cpp/shell_window_ids.h" #include "ash/resources/vector_icons/vector_icons.h" #include "ash/session/session_controller.h" @@ -36,8 +35,6 @@ #include "components/prefs/pref_service.h" #include "mash/public/mojom/launchable.mojom.h" #include "services/service_manager/public/cpp/connector.h" -#include "services/ui/public/interfaces/accessibility_manager.mojom.h" -#include "services/ui/public/interfaces/constants.mojom.h" #include "ui/aura/window.h" #include "ui/base/cursor/cursor_type.h" #include "ui/base/l10n/l10n_util.h" @@ -851,7 +848,7 @@ NotifyAccessibilityStatusChanged(); - if (Shell::GetAshConfig() == Config::MASH_DEPRECATED) { + if (!features::IsAshInBrowserProcess()) { if (!connector_) // Null in tests. return; mash::mojom::LaunchablePtr launchable; @@ -872,7 +869,7 @@ return; autoclick_delay_ = autoclick_delay; - if (Shell::GetAshConfig() == Config::MASH_DEPRECATED) { + if (!features::IsAshInBrowserProcess()) { if (!connector_) // Null in tests. return; autoclick::mojom::AutoclickControllerPtr autoclick_controller; @@ -956,17 +953,6 @@ NotifyAccessibilityStatusChanged(); - // Under mash the UI service (window server) handles high contrast mode. - if (Shell::GetAshConfig() == Config::MASH_DEPRECATED) { - if (!connector_) // Null in tests. - return; - ui::mojom::AccessibilityManagerPtr accessibility_ptr; - connector_->BindInterface(ui::mojom::kServiceName, &accessibility_ptr); - accessibility_ptr->SetHighContrastMode(enabled); - return; - } - - // Under classic ash high contrast mode is handled internally. Shell::Get()->high_contrast_controller()->SetEnabled(enabled); Shell::Get()->UpdateCursorCompositingEnabled(); }
diff --git a/ash/app_list/views/apps_grid_view.cc b/ash/app_list/views/apps_grid_view.cc index 651b3ec..877ca008 100644 --- a/ash/app_list/views/apps_grid_view.cc +++ b/ash/app_list/views/apps_grid_view.cc
@@ -222,6 +222,35 @@ DISALLOW_COPY_AND_ASSIGN(ItemMoveAnimationDelegate); }; +// This class observes the end of folder dropping animation. +class FolderDroppingAnimationObserver : public TopIconAnimationObserver { + public: + FolderDroppingAnimationObserver(AppListModel* model, + const std::string& folder_item_id) + : model_(model), folder_item_id_(folder_item_id) {} + + // TopIconAnimationObserver: + void OnTopIconAnimationsComplete(TopIconAnimationView* view) override { + AppListFolderItem* item = + static_cast<AppListFolderItem*>(model_->FindItem(folder_item_id_)); + + // The folder item may be deleted during the animation. + if (!item) + return; + + // Update the folder icon. + item->NotifyOfDraggedItem(nullptr); + + base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, this); + } + + private: + AppListModel* model_; // Not owned. + const std::string folder_item_id_; + + DISALLOW_COPY_AND_ASSIGN(FolderDroppingAnimationObserver); +}; + // Returns true if the |item| is a folder item. bool IsFolderItem(AppListItem* item) { return (item->GetItemType() == AppListFolderItem::kItemType); @@ -605,6 +634,13 @@ // Coming here a drag and drop was in progress. bool landed_in_drag_and_drop_host = forward_events_to_drag_and_drop_host_; + + // This is the folder view to drop an item into. Cache the |drag_view_|'s item + // and its bounds for later use in folder dropping animation. + AppListItemView* folder_item_view = nullptr; + AppListItem* drag_item = drag_view_->item(); + const gfx::Rect drag_source_bounds(drag_view_->bounds()); + if (forward_events_to_drag_and_drop_host_) { DCHECK(!IsDraggingForReparentInRootLevelGridView()); forward_events_to_drag_and_drop_host_ = false; @@ -638,6 +674,8 @@ if (EnableFolderDragDropUI() && drop_attempt_ == DROP_FOR_FOLDER && IsValidIndex(folder_drop_target_)) { MoveItemToFolder(drag_view_, folder_drop_target_); + folder_item_view = + GetViewDisplayedAtSlotOnCurrentPage(folder_drop_target_.slot); } else if (IsValidReorderTargetIndex(reorder_drop_target_)) { MoveItemInModel(drag_view_, reorder_drop_target_); } @@ -670,6 +708,12 @@ if (!cancel && IsAppsGridGapEnabled()) view_structure_.SaveToMetadata(); + if (folder_item_view) { + // Run an animation to move dragged item to the folder. + StartFolderDroppingAnimation(folder_item_view, drag_item, + drag_source_bounds); + } + StopPageFlipTimer(); } @@ -1491,7 +1535,7 @@ } gfx::Rect AppsGridView::GetTargetIconRectInFolder( - AppListItemView* drag_item_view, + AppListItem* drag_item, AppListItemView* folder_item_view) { const gfx::Rect view_ideal_bounds = view_model_.ideal_bounds(view_model_.GetIndexOfView(folder_item_view)); @@ -1500,7 +1544,7 @@ view_ideal_bounds, folder_item_view->GetIconImage().size()); AppListFolderItem* folder_item = static_cast<AppListFolderItem*>(folder_item_view->item()); - return folder_item->GetTargetIconRectInFolderForItem(drag_item_view->item(), + return folder_item->GetTargetIconRectInFolderForItem(drag_item, icon_ideal_bounds); } @@ -1695,6 +1739,13 @@ DCHECK(IsDraggingForReparentInRootLevelGridView()); bool cancel_reparent = cancel_drag || drop_attempt_ == DROP_FOR_NONE; + + // This is the folder view to drop an item into. Cache the |drag_view_|'s item + // and its bounds for later use in folder dropping animation. + AppListItemView* folder_item_view = nullptr; + AppListItem* drag_item = drag_view_->item(); + const gfx::Rect drag_source_bounds(drag_view_->bounds()); + if (!events_forwarded_to_drag_drop_host && !cancel_reparent) { CalculateDropTarget(); if (drop_attempt_ == DROP_FOR_REORDER && @@ -1704,6 +1755,10 @@ IsValidIndex(folder_drop_target_)) { cancel_reparent = !ReparentItemToAnotherFolder(drag_view_, folder_drop_target_); + if (!cancel_reparent) { + folder_item_view = + GetViewDisplayedAtSlotOnCurrentPage(folder_drop_target_.slot); + } } else { NOTREACHED(); } @@ -1711,9 +1766,7 @@ } SetAsFolderDroppingTarget(folder_drop_target_, false); - if (cancel_reparent) { - CancelFolderItemReparent(drag_view_); - } else { + if (!cancel_reparent) { // By setting |drag_view_| to NULL here, we prevent ClearDragState() from // cleaning up the newly created AppListItemView, effectively claiming // ownership of the newly created drag view. @@ -1725,6 +1778,16 @@ if (IsAppsGridGapEnabled()) view_structure_.SaveToMetadata(); + if (cancel_reparent) { + // Run an animation to move dragged item back to its original folder. + StartFolderDroppingAnimation(activated_folder_item_view_, drag_item, + drag_source_bounds); + } else if (folder_item_view) { + // Run an animation to move dragged item to the new folder. + StartFolderDroppingAnimation(folder_item_view, drag_item, + drag_source_bounds); + } + StopPageFlipTimer(); } @@ -2306,24 +2369,6 @@ GetAppListItemViewIndexOffset() + target_model_index); } -void AppsGridView::CancelFolderItemReparent(AppListItemView* drag_item_view) { - // The icon of the dragged item must target to its final ideal bounds after - // the animation completes. - CalculateIdealBounds(); - - gfx::Rect target_icon_rect = - GetTargetIconRectInFolder(drag_item_view, activated_folder_item_view_); - - gfx::Rect drag_view_rect = drag_item_view->bounds(); - TopIconAnimationView* icon_view = new TopIconAnimationView( - drag_item_view->item()->icon(), - base::UTF8ToUTF16(drag_item_view->item()->GetDisplayName()), - target_icon_rect, false, true); /* animate like closing folder */ - AddChildView(icon_view); - icon_view->SetBoundsRect(drag_view_rect); - icon_view->TransformView(); -} - void AppsGridView::CancelContextMenusOnCurrentPage() { GridIndex start_index(pagination_model_.selected_page(), 0); int start = GetModelIndexFromIndex(start_index); @@ -2867,4 +2912,28 @@ (pagination_model_.total_pages() - 1) * TilesPerPage(0); } +void AppsGridView::StartFolderDroppingAnimation( + AppListItemView* folder_item_view, + AppListItem* drag_item, + const gfx::Rect& source_bounds) { + // Calculate target bounds of dragged item. + gfx::Rect target_bounds = + GetTargetIconRectInFolder(drag_item, folder_item_view); + + // Update folder icon. + AppListFolderItem* folder_item = + static_cast<AppListFolderItem*>(folder_item_view->item()); + folder_item->NotifyOfDraggedItem(drag_item); + + // Start animation. + TopIconAnimationView* animation_view = new TopIconAnimationView( + drag_item->icon(), base::UTF8ToUTF16(drag_item->GetDisplayName()), + target_bounds, false, true); + AddChildView(animation_view); + animation_view->SetBoundsRect(source_bounds); + animation_view->AddObserver( + new FolderDroppingAnimationObserver(model_, folder_item->id())); + animation_view->TransformView(); +} + } // namespace app_list
diff --git a/ash/app_list/views/apps_grid_view.h b/ash/app_list/views/apps_grid_view.h index 6ad44c49..9704e7b7 100644 --- a/ash/app_list/views/apps_grid_view.h +++ b/ash/app_list/views/apps_grid_view.h
@@ -47,11 +47,11 @@ class AppListItemView; class AppsGridViewFolderDelegate; class ContentsView; +class ExpandArrowView; class IndicatorChipView; class SuggestionsContainerView; class PaginationController; class PulsingBlockView; -class ExpandArrowView; // Represents the index to an item view in the grid. struct GridIndex { @@ -409,11 +409,6 @@ void RemoveLastItemFromReparentItemFolderIfNecessary( const std::string& source_folder_id); - // If user does not drop the re-parenting folder item to any valid target, - // cancel the re-parenting action, let the item go back to its original - // parent folder with UI animation. - void CancelFolderItemReparent(AppListItemView* drag_item_view); - // Cancels any context menus showing for app items on the current page. void CancelContextMenusOnCurrentPage(); @@ -517,9 +512,9 @@ // folder during reparenting a folder item. bool IsDraggingForReparentInHiddenGridView() const; - // Returns the target icon bounds for |drag_item_view| to fly back - // to its parent |folder_item_view| in animation. - gfx::Rect GetTargetIconRectInFolder(AppListItemView* drag_item_view, + // Returns the target icon bounds for |drag_item| to fly back to its parent + // |folder_item_view| in animation. + gfx::Rect GetTargetIconRectInFolder(AppListItem* drag_item, AppListItemView* folder_item_view); // Returns true if the grid view is under an OEM folder. @@ -608,6 +603,13 @@ // is out of range. int GetItemsNumOfPage(int page) const; + // Starts the animation to transition the |drag_item| from |source_bounds| to + // the target bounds in the |folder_item_view|. Note that this animation + // should run only after |drag_item| is added to the folder. + void StartFolderDroppingAnimation(AppListItemView* folder_item_view, + AppListItem* drag_item, + const gfx::Rect& source_bounds); + AppListModel* model_ = nullptr; // Owned by AppListView. AppListItemList* item_list_ = nullptr; // Not owned.
diff --git a/ash/assistant/assistant_controller.cc b/ash/assistant/assistant_controller.cc index 162fd1d9..871f3439 100644 --- a/ash/assistant/assistant_controller.cc +++ b/ash/assistant/assistant_controller.cc
@@ -239,6 +239,11 @@ NotifyUrlOpened(url); } +void AssistantController::ShutDown() { + // Controllers can be added to handle this event as needed. + assistant_ui_controller_->ShutDown(); +} + void AssistantController::NotifyConstructed() { for (AssistantControllerObserver& observer : observers_) observer.OnAssistantControllerConstructed();
diff --git a/ash/assistant/assistant_controller.h b/ash/assistant/assistant_controller.h index 7ed56b5..0698c2c 100644 --- a/ash/assistant/assistant_controller.h +++ b/ash/assistant/assistant_controller.h
@@ -122,6 +122,9 @@ // TODO(dmblack): Support opening specific URLs in the Assistant container. void OpenUrl(const GURL& url); + // Called before dtor to deregister services and avoid life cycle issues. + void ShutDown(); + AssistantInteractionController* interaction_controller() { DCHECK(assistant_interaction_controller_); return assistant_interaction_controller_.get();
diff --git a/ash/assistant/assistant_ui_controller.cc b/ash/assistant/assistant_ui_controller.cc index ddfa45f59..f73de30 100644 --- a/ash/assistant/assistant_ui_controller.cc +++ b/ash/assistant/assistant_ui_controller.cc
@@ -14,6 +14,7 @@ #include "ash/system/toast/toast_data.h" #include "ash/system/toast/toast_manager.h" #include "ash/voice_interaction/voice_interaction_controller.h" +#include "ash/wm/tablet_mode/tablet_mode_controller.h" #include "base/optional.h" #include "chromeos/services/assistant/public/mojom/assistant.mojom.h" #include "ui/base/l10n/l10n_util.h" @@ -44,6 +45,7 @@ AddModelObserver(this); assistant_controller_->AddObserver(this); Shell::Get()->highlighter_controller()->AddObserver(this); + Shell::Get()->tablet_mode_controller()->AddObserver(this); } AssistantUiController::~AssistantUiController() { @@ -263,6 +265,20 @@ ShowUi(source); } +void AssistantUiController::OnTabletModeStarted() { + if (container_view_) + container_view_->OnTabletModeChanged(); +} + +void AssistantUiController::OnTabletModeEnded() { + if (container_view_) + container_view_->OnTabletModeChanged(); +} + +void AssistantUiController::ShutDown() { + Shell::Get()->tablet_mode_controller()->RemoveObserver(this); +} + void AssistantUiController::UpdateUiMode( base::Optional<AssistantUiMode> ui_mode) { // If a UI mode is provided, we will use it in lieu of updating UI mode on the
diff --git a/ash/assistant/assistant_ui_controller.h b/ash/assistant/assistant_ui_controller.h index 521261d7..2661a556 100644 --- a/ash/assistant/assistant_ui_controller.h +++ b/ash/assistant/assistant_ui_controller.h
@@ -15,6 +15,7 @@ #include "ash/assistant/ui/caption_bar.h" #include "ash/assistant/ui/dialog_plate/dialog_plate.h" #include "ash/highlighter/highlighter_controller.h" +#include "ash/wm/tablet_mode/tablet_mode_observer.h" #include "base/macros.h" #include "ui/views/widget/widget_observer.h" @@ -44,7 +45,8 @@ public AssistantMiniViewDelegate, public CaptionBarDelegate, public DialogPlateObserver, - public HighlighterController::Observer { + public HighlighterController::Observer, + public TabletModeObserver { public: explicit AssistantUiController(AssistantController* assistant_controller); ~AssistantUiController() override; @@ -100,6 +102,13 @@ void HideUi(AssistantSource source); void ToggleUi(AssistantSource source); + // TabletModeObserver: + void OnTabletModeStarted() override; + void OnTabletModeEnded() override; + + // Called before dtor to clean up service dependencies. + void ShutDown(); + AssistantContainerView* GetViewForTest(); private:
diff --git a/ash/assistant/ui/assistant_container_view.cc b/ash/assistant/ui/assistant_container_view.cc index d8748fc8d..e49d589 100644 --- a/ash/assistant/ui/assistant_container_view.cc +++ b/ash/assistant/ui/assistant_container_view.cc
@@ -4,6 +4,7 @@ #include "ash/assistant/ui/assistant_container_view.h" +#include <iostream> #include <memory> #include "ash/assistant/assistant_controller.h" @@ -14,6 +15,7 @@ #include "ash/assistant/ui/assistant_ui_constants.h" #include "ash/assistant/ui/assistant_web_view.h" #include "ash/shell.h" +#include "ash/wm/tablet_mode/tablet_mode_controller.h" #include "base/strings/utf_string_conversions.h" #include "ui/display/display.h" #include "ui/display/screen.h" @@ -28,10 +30,12 @@ namespace { +constexpr int kClamshellMarginBottomDip = 8; // Margin in clamshell mode. +constexpr int kTabletMarginTopDip = 24; // Margin in tablet mode. + // Appearance. constexpr SkColor kBackgroundColor = SK_ColorWHITE; constexpr int kCornerRadiusDip = 20; -constexpr int kMarginDip = 8; // Animation. constexpr int kResizeAnimationDurationMs = 250; @@ -245,13 +249,21 @@ display::Display display = display::Screen::GetScreen()->GetDisplayMatching( root_window->GetBoundsInScreen()); + bool tablet_mode = Shell::Get() + ->tablet_mode_controller() + ->IsTabletModeWindowManagerEnabled(); + // Anchor to the bottom center of the work area. gfx::Rect work_area = display.work_area(); - gfx::Rect anchor = gfx::Rect(work_area.x(), work_area.bottom() - kMarginDip, - work_area.width(), 0); + gfx::Rect anchor = + gfx::Rect(work_area.x(), + tablet_mode ? kTabletMarginTopDip + : work_area.bottom() - kClamshellMarginBottomDip, + work_area.width(), 0); SetAnchorRect(anchor); - set_arrow(views::BubbleBorder::Arrow::BOTTOM_CENTER); + set_arrow(tablet_mode ? views::BubbleBorder::Arrow::TOP_CENTER + : views::BubbleBorder::Arrow::BOTTOM_CENTER); } void AssistantContainerView::OnUiModeChanged(AssistantUiMode ui_mode) { @@ -297,13 +309,24 @@ // Use our interpolated size. bounds.set_size(gfx::Size(size.width(), size.height())); - // Maintain our original |bottom| and |center_x| positions. + if (!Shell::Get() + ->tablet_mode_controller() + ->IsTabletModeWindowManagerEnabled()) { + // Maintain our original |bottom| positions in clamshell mode. In tablet + // mode, they should grow downwards, which is the default behavior. + bounds.set_y(bottom - bounds.height()); + } + // Maintain |center_x| position. bounds.set_x(center_x - (bounds.width() / 2)); - bounds.set_y(bottom - bounds.height()); GetWidget()->SetBounds(bounds); } +void AssistantContainerView::OnTabletModeChanged() { + DCHECK(GetWidget()); + SetAnchor(GetWidget()->GetNativeWindow()->GetRootWindow()); +} + void AssistantContainerView::OnDisplayMetricsChanged( const display::Display& display, uint32_t changed_metrics) {
diff --git a/ash/assistant/ui/assistant_container_view.h b/ash/assistant/ui/assistant_container_view.h index b5d1b80..4b372da 100644 --- a/ash/assistant/ui/assistant_container_view.h +++ b/ash/assistant/ui/assistant_container_view.h
@@ -58,6 +58,8 @@ void OnDisplayMetricsChanged(const display::Display& display, uint32_t changed_metrics) override; + void OnTabletModeChanged(); + private: // Sets anchor rect to |root_window|. If it's null, // result of GetRootWindowForNewWindows() will be used.
diff --git a/ash/assistant/ui/assistant_container_view_unittest.cc b/ash/assistant/ui/assistant_container_view_unittest.cc index 5d120bb..57e39da 100644 --- a/ash/assistant/ui/assistant_container_view_unittest.cc +++ b/ash/assistant/ui/assistant_container_view_unittest.cc
@@ -9,6 +9,7 @@ #include "ash/shell.h" #include "ash/test/ash_test_base.h" #include "ash/voice_interaction/voice_interaction_controller.h" +#include "ash/wm/tablet_mode/tablet_mode_controller.h" #include "base/macros.h" #include "base/test/scoped_feature_list.h" #include "chromeos/chromeos_switches.h" @@ -19,6 +20,9 @@ namespace { +constexpr int kClamshellMarginBottomDip = 8; // Margin in clamshell mode. +constexpr int kTabletMarginTopDip = 24; // Margin in tablet mode. + class AssistantContainerViewTest : public AshTestBase { public: AssistantContainerViewTest() = default; @@ -103,16 +107,41 @@ Shell::Get()->GetRootWindowForNewWindows()->GetBoundsInScreen()) .work_area(); - // We expect a bottom margin. - constexpr int bottom_margin = 8; - // We expect the view to be horizontally centered and bottom aligned. gfx::Rect expected_bounds = gfx::Rect(expected_work_area); expected_bounds.ClampToCenteredSize(view->size()); expected_bounds.set_y(expected_work_area.bottom() - view->height() - - bottom_margin); + kClamshellMarginBottomDip); ASSERT_EQ(expected_bounds, view->GetBoundsInScreen()); } +TEST_F(AssistantContainerViewTest, TabletModeAnchoring) { + // Guarantee short but non-zero duration for animations. + ui::ScopedAnimationDurationScaleMode scoped_animation_duration( + ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION); + + gfx::Rect expected_work_area = + display::Screen::GetScreen() + ->GetDisplayMatching( + Shell::Get()->GetRootWindowForNewWindows()->GetBoundsInScreen()) + .work_area(); + + int clamshell_y = expected_work_area.bottom() - kClamshellMarginBottomDip; + + ui_controller()->ShowUi(AssistantSource::kUnspecified); + AssistantContainerView* view = ui_controller()->GetViewForTest(); + + gfx::Rect bounds = view->GetBoundsInScreen(); + ASSERT_EQ(bounds.bottom(), clamshell_y); + + Shell::Get()->tablet_mode_controller()->EnableTabletModeWindowManager(true); + bounds = view->GetBoundsInScreen(); + ASSERT_EQ(bounds.y(), kTabletMarginTopDip); + + Shell::Get()->tablet_mode_controller()->EnableTabletModeWindowManager(false); + bounds = view->GetBoundsInScreen(); + ASSERT_EQ(bounds.bottom(), clamshell_y); +} + } // namespace ash
diff --git a/ash/assistant/ui/dialog_plate/dialog_plate.cc b/ash/assistant/ui/dialog_plate/dialog_plate.cc index b8454fc..790e273 100644 --- a/ash/assistant/ui/dialog_plate/dialog_plate.cc +++ b/ash/assistant/ui/dialog_plate/dialog_plate.cc
@@ -11,7 +11,9 @@ #include "ash/assistant/util/animation_util.h" #include "ash/public/cpp/vector_icons/vector_icons.h" #include "ash/resources/vector_icons/vector_icons.h" +#include "ash/shell.h" #include "ash/strings/grit/ash_strings.h" +#include "ash/wm/tablet_mode/tablet_mode_controller.h" #include "base/bind.h" #include "base/strings/utf_string_conversions.h" #include "ui/base/l10n/l10n_util.h" @@ -23,6 +25,7 @@ #include "ui/views/border.h" #include "ui/views/controls/button/image_button.h" #include "ui/views/controls/textfield/textfield.h" +#include "ui/views/focus/focus_manager.h" #include "ui/views/layout/box_layout.h" #include "ui/views/layout/fill_layout.h" @@ -47,6 +50,12 @@ base::TimeDelta::FromMilliseconds(333); constexpr int kAnimationTranslationDip = 30; +bool IsTabletMode() { + return Shell::Get() + ->tablet_mode_controller() + ->IsTabletModeWindowManagerEnabled(); +} + } // namespace // DialogPlate ----------------------------------------------------------------- @@ -365,6 +374,11 @@ if (key_event.type() != ui::EventType::ET_KEY_PRESSED) return false; + // In tablet mode the virtual keyboard should not be sticky, so we hide it + // when committing a query. + if (IsTabletMode()) + textfield_->GetFocusManager()->ClearFocus(); + const base::StringPiece16& trimmed_text = base::TrimWhitespace(textfield_->text(), base::TrimPositions::TRIM_ALL);
diff --git a/ash/login/ui/lock_contents_view.cc b/ash/login/ui/lock_contents_view.cc index 09e4151..1a19f07 100644 --- a/ash/login/ui/lock_contents_view.cc +++ b/ash/login/ui/lock_contents_view.cc
@@ -1581,7 +1581,7 @@ opt_to_hide->CaptureStateForAnimationPreLayout(); } - // Update auth methods for |opt_to_update|. Disable auth on |opt_to_hide|. + // Update auth methods for |opt_to_update|. if (opt_to_update) { UserState* state = FindStateForUser( opt_to_update->current_user()->basic_user_info->account_id); @@ -1606,10 +1606,14 @@ to_update_auth |= LoginAuthUserView::AUTH_FINGERPRINT; } } - opt_to_update->SetAuthMethods(to_update_auth); + opt_to_update->SetAuthMethods(to_update_auth, state->show_pin); } - if (opt_to_hide) - opt_to_hide->SetAuthMethods(LoginAuthUserView::AUTH_NONE); + + // Disable auth on |opt_to_hide|. + if (opt_to_hide) { + opt_to_hide->SetAuthMethods(LoginAuthUserView::AUTH_NONE, + false /*can_use_pin*/); + } Layout();
diff --git a/ash/login/ui/lock_contents_view_unittest.cc b/ash/login/ui/lock_contents_view_unittest.cc index ed7d6fb..72e5f9c 100644 --- a/ash/login/ui/lock_contents_view_unittest.cc +++ b/ash/login/ui/lock_contents_view_unittest.cc
@@ -1138,7 +1138,7 @@ LockScreen::TestApi(LockScreen::Get()).contents_view(); ASSERT_NE(nullptr, contents); - // Add user with enabled pin method of authentication. + // Add user who can use pin authentication. const std::string email = "user@domain.com"; LoadUser(email); contents->OnPinEnabledForUserChanged(AccountId::FromUserEmail(email), true); @@ -1207,6 +1207,44 @@ ->HasFocus()); } +TEST_F(LockContentsViewKeyboardUnitTest, PinSubmitWithVirtualKeyboardShown) { + ASSERT_NO_FATAL_FAILURE(ShowLockScreen()); + LockContentsView* contents = + LockScreen::TestApi(LockScreen::Get()).contents_view(); + + // Add user who can use pin authentication. + const std::string email = "user@domain.com"; + LoadUser(email); + contents->OnPinEnabledForUserChanged(AccountId::FromUserEmail(email), true); + LoginBigUserView* big_view = + LockContentsView::TestApi(contents).primary_big_view(); + + // Require that AuthenticateUser is called with authenticated_by_pin set to + // true. + auto client = BindMockLoginScreenClient(); + EXPECT_CALL(*client, + AuthenticateUser_(_, "1111", true /*authenticated_by_pin*/, _)); + + // Hide the PIN keyboard. + LoginPinView* pin_view = + LoginAuthUserView::TestApi(big_view->auth_user()).pin_view(); + EXPECT_TRUE(pin_view->visible()); + ASSERT_NO_FATAL_FAILURE(ShowKeyboard()); + EXPECT_FALSE(pin_view->visible()); + + // Submit a password. + LoginAuthUserView::TestApi(big_view->auth_user()) + .password_view() + ->RequestFocus(); + ui::test::EventGenerator* generator = GetEventGenerator(); + generator->PressKey(ui::KeyboardCode::VKEY_1, 0); + generator->PressKey(ui::KeyboardCode::VKEY_1, 0); + generator->PressKey(ui::KeyboardCode::VKEY_1, 0); + generator->PressKey(ui::KeyboardCode::VKEY_1, 0); + generator->PressKey(ui::KeyboardCode::VKEY_RETURN, 0); + base::RunLoop().RunUntilIdle(); +} + // Verify that swapping works in two user layout between one regular auth user // and one public account user. TEST_F(LockContentsViewUnitTest, SwapAuthAndPublicAccountUserInTwoUserLayout) {
diff --git a/ash/login/ui/login_auth_user_view.cc b/ash/login/ui/login_auth_user_view.cc index eddaa46f..555efc94 100644 --- a/ash/login/ui/login_auth_user_view.cc +++ b/ash/login/ui/login_auth_user_view.cc
@@ -469,7 +469,7 @@ add_padding(kDistanceFromPinKeyboardToBigUserViewBottomDp); // Update authentication UI. - SetAuthMethods(auth_methods_); + SetAuthMethods(auth_methods_, false /*can_use_pin*/); user_view_->UpdateForUser(user, false /*animate*/); observer_.Add(Shell::Get()->wallpaper_controller()); @@ -479,7 +479,9 @@ LoginAuthUserView::~LoginAuthUserView() = default; -void LoginAuthUserView::SetAuthMethods(uint32_t auth_methods) { +void LoginAuthUserView::SetAuthMethods(uint32_t auth_methods, + bool can_use_pin) { + can_use_pin_ = can_use_pin; bool had_password = HasAuthMethod(AUTH_PASSWORD); auth_methods_ = static_cast<AuthMethods>(auth_methods); @@ -491,6 +493,11 @@ bool auth_disabled = HasAuthMethod(AUTH_DISABLED); bool hide_auth = auth_disabled || force_online_sign_in; + // implication: if |has_pin| is true, then |can_use_pin| must also be true + DCHECK(!has_pin || can_use_pin); + // implication: if |can_use_pin| is false, then |has_pin| must also be false + DCHECK(can_use_pin || !has_pin); + online_sign_in_message_->SetVisible(force_online_sign_in); disabled_auth_message_->SetVisible(auth_disabled); @@ -720,8 +727,6 @@ } void LoginAuthUserView::OnAuthSubmit(const base::string16& password) { - bool authenticated_by_pin = (auth_methods_ & AUTH_PIN) != 0; - // Pressing enter when the password field is empty and tap-to-unlock is // enabled should attempt unlock. if (HasAuthMethod(AUTH_TAP) && password.empty()) { @@ -732,7 +737,7 @@ password_view_->SetReadOnly(true); Shell::Get()->login_screen_controller()->AuthenticateUser( current_user()->basic_user_info->account_id, base::UTF16ToUTF8(password), - authenticated_by_pin, + can_use_pin_, base::BindOnce(&LoginAuthUserView::OnAuthComplete, weak_factory_.GetWeakPtr())); }
diff --git a/ash/login/ui/login_auth_user_view.h b/ash/login/ui/login_auth_user_view.h index f950eaf4..c81ff7d 100644 --- a/ash/login/ui/login_auth_user_view.h +++ b/ash/login/ui/login_auth_user_view.h
@@ -97,8 +97,9 @@ ~LoginAuthUserView() override; // Set the displayed set of auth methods. |auth_methods| contains or-ed - // together AuthMethod values. - void SetAuthMethods(uint32_t auth_methods); + // together AuthMethod values. |can_use_pin| should be true if the user can + // authenticate using PIN, even if the PIN keyboard is not displayed. + void SetAuthMethods(uint32_t auth_methods, bool can_use_pin); AuthMethods auth_methods() const { return auth_methods_; } // Add an easy unlock icon. @@ -166,6 +167,10 @@ void DecorateOnlineSignInMessage(); AuthMethods auth_methods_ = AUTH_NONE; + // True if the user's password might be a PIN. PIN is hashed differently from + // password. The PIN keyboard may not always be visible even when the user + // wants to submit a PIN, eg. the virtual keyboard hides the PIN keyboard. + bool can_use_pin_ = false; LoginUserView* user_view_ = nullptr; LoginPasswordView* password_view_ = nullptr; LoginPinView* pin_view_ = nullptr;
diff --git a/ash/login/ui/login_auth_user_view_unittest.cc b/ash/login/ui/login_auth_user_view_unittest.cc index bfeff4c..4101287 100644 --- a/ash/login/ui/login_auth_user_view_unittest.cc +++ b/ash/login/ui/login_auth_user_view_unittest.cc
@@ -53,6 +53,11 @@ SetWidget(CreateWidgetWithContent(container_)); } + void SetAuthMethods(uint32_t auth_methods) { + bool can_use_pin = (auth_methods & LoginAuthUserView::AUTH_PIN) != 0; + view_->SetAuthMethods(auth_methods, can_use_pin); + } + mojom::LoginUserInfoPtr user_; views::View* container_ = nullptr; // Owned by test widget view hierarchy. LoginAuthUserView* view_ = nullptr; // Owned by test widget view hierarchy. @@ -66,7 +71,7 @@ // Verifies showing the PIN keyboard makes the user view grow. TEST_F(LoginAuthUserViewUnittest, ShowingPinExpandsView) { gfx::Size start_size = view_->size(); - view_->SetAuthMethods(LoginAuthUserView::AUTH_PIN); + SetAuthMethods(LoginAuthUserView::AUTH_PIN); container_->Layout(); gfx::Size expanded_size = view_->size(); EXPECT_GT(expanded_size.height(), start_size.height()); @@ -86,11 +91,11 @@ EXPECT_FALSE(auth_test.user_view()->HasFocus()); // If the user view is showing a password it must be opaque. - view_->SetAuthMethods(LoginAuthUserView::AUTH_PASSWORD); + SetAuthMethods(LoginAuthUserView::AUTH_PASSWORD); EXPECT_TRUE(user_test.is_opaque()); - view_->SetAuthMethods(LoginAuthUserView::AUTH_NONE); + SetAuthMethods(LoginAuthUserView::AUTH_NONE); EXPECT_FALSE(user_test.is_opaque()); - view_->SetAuthMethods(LoginAuthUserView::AUTH_PASSWORD); + SetAuthMethods(LoginAuthUserView::AUTH_PASSWORD); EXPECT_TRUE(user_test.is_opaque()); } @@ -111,8 +116,8 @@ EXPECT_CALL( *client, AttemptUnlock(user_view->current_user()->basic_user_info->account_id)); - view_->SetAuthMethods(LoginAuthUserView::AUTH_PASSWORD | - LoginAuthUserView::AUTH_TAP); + SetAuthMethods(LoginAuthUserView::AUTH_PASSWORD | + LoginAuthUserView::AUTH_TAP); password_view->Clear(); generator->PressKey(ui::KeyboardCode::VKEY_RETURN, 0); @@ -137,7 +142,7 @@ // When auth method is |AUTH_ONLINE_SIGN_IN|, the online sign-in message is // visible. The password field and PIN keyboard are invisible. - view_->SetAuthMethods(LoginAuthUserView::AUTH_ONLINE_SIGN_IN); + SetAuthMethods(LoginAuthUserView::AUTH_ONLINE_SIGN_IN); EXPECT_TRUE(online_sign_in_message->visible()); EXPECT_FALSE(password_view->visible()); EXPECT_FALSE(pin_view->visible()); @@ -154,13 +159,13 @@ base::RunLoop().RunUntilIdle(); // The online sign-in message is invisible for all other auth methods. - view_->SetAuthMethods(LoginAuthUserView::AUTH_NONE); + SetAuthMethods(LoginAuthUserView::AUTH_NONE); EXPECT_FALSE(online_sign_in_message->visible()); - view_->SetAuthMethods(LoginAuthUserView::AUTH_PASSWORD); + SetAuthMethods(LoginAuthUserView::AUTH_PASSWORD); EXPECT_FALSE(online_sign_in_message->visible()); - view_->SetAuthMethods(LoginAuthUserView::AUTH_PIN); + SetAuthMethods(LoginAuthUserView::AUTH_PIN); EXPECT_FALSE(online_sign_in_message->visible()); - view_->SetAuthMethods(LoginAuthUserView::AUTH_TAP); + SetAuthMethods(LoginAuthUserView::AUTH_TAP); EXPECT_FALSE(online_sign_in_message->visible()); } @@ -173,20 +178,20 @@ }; // Set a password. - view_->SetAuthMethods(LoginAuthUserView::AUTH_PASSWORD); + SetAuthMethods(LoginAuthUserView::AUTH_PASSWORD); password_test.textfield()->SetText(base::ASCIIToUTF16("Hello")); // Enable some other auth method (PIN), password is not cleared. view_->CaptureStateForAnimationPreLayout(); - view_->SetAuthMethods(LoginAuthUserView::AUTH_PASSWORD | - LoginAuthUserView::AUTH_PIN); + SetAuthMethods(LoginAuthUserView::AUTH_PASSWORD | + LoginAuthUserView::AUTH_PIN); EXPECT_TRUE(has_password()); view_->ApplyAnimationPostLayout(); EXPECT_TRUE(has_password()); // Disable password, password is cleared. view_->CaptureStateForAnimationPreLayout(); - view_->SetAuthMethods(LoginAuthUserView::AUTH_NONE); + SetAuthMethods(LoginAuthUserView::AUTH_NONE); EXPECT_TRUE(has_password()); view_->ApplyAnimationPostLayout(); EXPECT_FALSE(has_password());
diff --git a/ash/public/cpp/app_list/app_list_features.cc b/ash/public/cpp/app_list/app_list_features.cc index ffaf114..718605b 100644 --- a/ash/public/cpp/app_list/app_list_features.cc +++ b/ash/public/cpp/app_list/app_list_features.cc
@@ -17,14 +17,14 @@ base::FEATURE_DISABLED_BY_DEFAULT}; const base::Feature kEnableBackgroundBlur{"EnableBackgroundBlur", base::FEATURE_DISABLED_BY_DEFAULT}; -const base::Feature kEnablePlayStoreAppSearch{"EnablePlayStoreAppSearch", - base::FEATURE_ENABLED_BY_DEFAULT}; +const base::Feature kEnablePlayStoreAppSearch{ + "EnablePlayStoreAppSearch", base::FEATURE_DISABLED_BY_DEFAULT}; const base::Feature kEnableHomeLauncher{"EnableHomeLauncher", base::FEATURE_ENABLED_BY_DEFAULT}; const base::Feature kEnableSettingsShortcutSearch{ "EnableSettingsShortcutSearch", base::FEATURE_DISABLED_BY_DEFAULT}; -const base::Feature kEnableAppsGridGapFeature{"EnableAppsGridGapFeature", - base::FEATURE_ENABLED_BY_DEFAULT}; +const base::Feature kEnableAppsGridGapFeature{ + "EnableAppsGridGapFeature", base::FEATURE_DISABLED_BY_DEFAULT}; const base::Feature kEnableNewStyleLauncher{"EnableNewStyleLauncher", base::FEATURE_ENABLED_BY_DEFAULT}; const base::Feature kEnableContinueReading{"EnableContinueReading",
diff --git a/ash/public/cpp/ash_features.cc b/ash/public/cpp/ash_features.cc index 0dcd9eb..857fb03 100644 --- a/ash/public/cpp/ash_features.cc +++ b/ash/public/cpp/ash_features.cc
@@ -14,7 +14,7 @@ base::FEATURE_ENABLED_BY_DEFAULT}; const base::Feature kDragAppsInTabletMode{"DragAppsInTabletMode", - base::FEATURE_DISABLED_BY_DEFAULT}; + base::FEATURE_ENABLED_BY_DEFAULT}; const base::Feature kDragTabsInTabletMode{"DragTabsInTabletMode", base::FEATURE_ENABLED_BY_DEFAULT};
diff --git a/ash/public/cpp/immersive/immersive_fullscreen_controller_test_api.cc b/ash/public/cpp/immersive/immersive_fullscreen_controller_test_api.cc index 9f1d2081a..cbcebc5 100644 --- a/ash/public/cpp/immersive/immersive_fullscreen_controller_test_api.cc +++ b/ash/public/cpp/immersive/immersive_fullscreen_controller_test_api.cc
@@ -7,7 +7,9 @@ #include "ash/public/cpp/immersive/immersive_fullscreen_controller.h" #include "ash/public/cpp/immersive/immersive_fullscreen_controller_delegate.h" #include "ui/aura/env.h" +#include "ui/aura/window.h" #include "ui/gfx/geometry/rect.h" +#include "ui/views/widget/widget.h" namespace ash { @@ -32,7 +34,10 @@ bottommost_in_screen = bounds_in_screen[i].bottom(); } gfx::Point cursor_pos(0, bottommost_in_screen + 10); - aura::Env::GetInstance()->SetLastMouseLocation(cursor_pos); + immersive_fullscreen_controller_->widget() + ->GetNativeView() + ->env() + ->SetLastMouseLocation(cursor_pos); immersive_fullscreen_controller_->UpdateLocatedEventRevealedLock(); }
diff --git a/ash/shelf/shelf_application_menu_model_unittest.cc b/ash/shelf/shelf_application_menu_model_unittest.cc index 27e3245b..0ea0e54 100644 --- a/ash/shelf/shelf_application_menu_model_unittest.cc +++ b/ash/shelf/shelf_application_menu_model_unittest.cc
@@ -50,13 +50,11 @@ base::string16 title = base::ASCIIToUTF16("title"); ShelfApplicationMenuModel menu(title, std::vector<mojom::MenuItemPtr>(), nullptr); - // Expect the title with separators. - ASSERT_EQ(static_cast<int>(3), menu.GetItemCount()); - EXPECT_EQ(ui::MenuModel::TYPE_SEPARATOR, menu.GetTypeAt(0)); - EXPECT_EQ(ui::MenuModel::TYPE_COMMAND, menu.GetTypeAt(1)); - EXPECT_EQ(title, menu.GetLabelAt(1)); - EXPECT_FALSE(menu.IsEnabledAt(1)); - EXPECT_EQ(ui::MenuModel::TYPE_SEPARATOR, menu.GetTypeAt(2)); + // Expect the title. + ASSERT_EQ(static_cast<int>(1), menu.GetItemCount()); + EXPECT_EQ(ui::MenuModel::TYPE_COMMAND, menu.GetTypeAt(0)); + EXPECT_EQ(title, menu.GetLabelAt(0)); + EXPECT_FALSE(menu.IsEnabledAt(0)); } // Verifies the menu contents given a non-empty item list. @@ -76,23 +74,23 @@ ShelfApplicationMenuModel menu(title, std::move(items), nullptr); ShelfApplicationMenuModelTestAPI menu_test_api(&menu); - // Expect the title with separators, the enabled items, and another separator. - ASSERT_EQ(static_cast<int>(7), menu.GetItemCount()); - EXPECT_EQ(ui::MenuModel::TYPE_SEPARATOR, menu.GetTypeAt(0)); + // Expect the title and the enabled items. + ASSERT_EQ(static_cast<int>(5), menu.GetItemCount()); + + // The label title should not be enabled. + EXPECT_EQ(ui::MenuModel::TYPE_COMMAND, menu.GetTypeAt(0)); + EXPECT_EQ(title, menu.GetLabelAt(0)); + EXPECT_FALSE(menu.IsEnabledAt(0)); + EXPECT_EQ(ui::MenuModel::TYPE_COMMAND, menu.GetTypeAt(1)); - EXPECT_EQ(title, menu.GetLabelAt(1)); - EXPECT_FALSE(menu.IsEnabledAt(1)); - EXPECT_EQ(ui::MenuModel::TYPE_SEPARATOR, menu.GetTypeAt(2)); + EXPECT_EQ(title1, menu.GetLabelAt(1)); + EXPECT_TRUE(menu.IsEnabledAt(1)); + EXPECT_EQ(ui::MenuModel::TYPE_COMMAND, menu.GetTypeAt(2)); + EXPECT_EQ(title2, menu.GetLabelAt(2)); + EXPECT_TRUE(menu.IsEnabledAt(2)); EXPECT_EQ(ui::MenuModel::TYPE_COMMAND, menu.GetTypeAt(3)); - EXPECT_EQ(title1, menu.GetLabelAt(3)); + EXPECT_EQ(title3, menu.GetLabelAt(3)); EXPECT_TRUE(menu.IsEnabledAt(3)); - EXPECT_EQ(ui::MenuModel::TYPE_COMMAND, menu.GetTypeAt(4)); - EXPECT_EQ(title2, menu.GetLabelAt(4)); - EXPECT_TRUE(menu.IsEnabledAt(4)); - EXPECT_EQ(ui::MenuModel::TYPE_COMMAND, menu.GetTypeAt(5)); - EXPECT_EQ(title3, menu.GetLabelAt(5)); - EXPECT_TRUE(menu.IsEnabledAt(5)); - EXPECT_EQ(ui::MenuModel::TYPE_SEPARATOR, menu.GetTypeAt(6)); } // Verifies RecordMenuItemSelectedMetrics uses the correct histogram buckets.
diff --git a/ash/shelf/shelf_context_menu_model_unittest.cc b/ash/shelf/shelf_context_menu_model_unittest.cc index 16ddc589..ee70b604 100644 --- a/ash/shelf/shelf_context_menu_model_unittest.cc +++ b/ash/shelf/shelf_context_menu_model_unittest.cc
@@ -126,33 +126,53 @@ // Check the shelf auto-hide behavior and menu interaction. ShelfContextMenuModel menu1(MenuItemList(), nullptr, primary_id); - EXPECT_FALSE(menu1.IsItemCheckedAt(0)); EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_NEVER, shelf->auto_hide_behavior()); menu1.ActivatedAt(0); EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS, shelf->auto_hide_behavior()); - // This menu shows auto-hide enabled; check alignment and menu interaction. + // Recreate the menu, auto-hide should still be enabled. ShelfContextMenuModel menu2(MenuItemList(), nullptr, primary_id); - EXPECT_TRUE(menu2.IsItemCheckedAt(0)); + EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS, shelf->auto_hide_behavior()); + + // By default the shelf should be on bottom, shelf alignment options in order: + // Left, Bottom, Right. Bottom should be checked. ui::MenuModel* submenu = menu2.GetSubmenuModelAt(1); EXPECT_TRUE(submenu->IsItemCheckedAt(1)); EXPECT_EQ(SHELF_ALIGNMENT_BOTTOM, shelf->alignment()); + + // Activate the left shelf alignment option. submenu->ActivatedAt(0); EXPECT_EQ(SHELF_ALIGNMENT_LEFT, shelf->alignment()); - // This menu shows left alignment; check wallpaper item interaction. + // Recreate the menu, it should show left alignment checked. ShelfContextMenuModel menu3(MenuItemList(), nullptr, primary_id); submenu = menu3.GetSubmenuModelAt(1); EXPECT_TRUE(submenu->IsItemCheckedAt(0)); + TestWallpaperControllerClient client; Shell::Get()->wallpaper_controller()->SetClientForTesting( client.CreateInterfacePtr()); EXPECT_EQ(0u, client.open_count()); + + // Click the third option, wallpaper picker. It should open. menu3.ActivatedAt(2); Shell::Get()->wallpaper_controller()->FlushForTesting(); EXPECT_EQ(1u, client.open_count()); } +// Tests that a desktop context menu shows the default options. +TEST_F(ShelfContextMenuModelTest, DesktopMenu) { + MenuItemList items; + // Pass a null delegate to indicate the menu is not for an application. + ShelfContextMenuModel menu(std::move(items), nullptr, + GetPrimaryDisplay().id()); + + ASSERT_EQ(3, menu.GetItemCount()); + EXPECT_EQ(CommandId::MENU_AUTO_HIDE, menu.GetCommandIdAt(0)); + EXPECT_EQ(CommandId::MENU_ALIGNMENT_MENU, menu.GetCommandIdAt(1)); + EXPECT_EQ(CommandId::MENU_CHANGE_WALLPAPER, menu.GetCommandIdAt(2)); +} + // Tests the prepending of custom items in a shelf context menu. TEST_F(ShelfContextMenuModelTest, CustomItems) { // Make a list of custom items with a variety of values. @@ -163,9 +183,7 @@ item->label = base::ASCIIToUTF16("item"); item->enabled = true; items.push_back(std::move(item)); - mojom::MenuItemPtr separator(mojom::MenuItem::New()); - separator->type = ui::MenuModel::TYPE_SEPARATOR; - items.push_back(std::move(separator)); + mojom::MenuItemPtr check(mojom::MenuItem::New()); check->type = ui::MenuModel::TYPE_CHECK; check->command_id = 999; @@ -173,6 +191,7 @@ check->enabled = true; check->checked = false; items.push_back(std::move(check)); + mojom::MenuItemPtr radio(mojom::MenuItem::New()); radio->type = ui::MenuModel::TYPE_RADIO; radio->command_id = 1337; @@ -181,38 +200,35 @@ radio->checked = true; items.push_back(std::move(radio)); - // Ensure the menu model's prepended contents match the items above. TestShelfItemDelegate delegate; ShelfContextMenuModel menu(std::move(items), &delegate, GetPrimaryDisplay().id()); - ASSERT_EQ(7, menu.GetItemCount()); + + // Ensure the menu model's prepended contents match the items above. Because + // the delegate is not null, the menu is interpreted as an application menu. + // It will not have the desktop menu options which are autohide, shelf + // position, and wallpaper picker. + ASSERT_EQ(3, menu.GetItemCount()); EXPECT_EQ(ui::MenuModel::TYPE_COMMAND, menu.GetTypeAt(0)); EXPECT_EQ(123, menu.GetCommandIdAt(0)); EXPECT_EQ(base::ASCIIToUTF16("item"), menu.GetLabelAt(0)); EXPECT_TRUE(menu.IsEnabledAt(0)); - EXPECT_EQ(ui::MenuModel::TYPE_SEPARATOR, menu.GetTypeAt(1)); + EXPECT_EQ(ui::MenuModel::TYPE_CHECK, menu.GetTypeAt(1)); + EXPECT_EQ(999, menu.GetCommandIdAt(1)); + EXPECT_EQ(base::ASCIIToUTF16("check"), menu.GetLabelAt(1)); + EXPECT_TRUE(menu.IsEnabledAt(1)); + EXPECT_FALSE(menu.IsItemCheckedAt(1)); - EXPECT_EQ(ui::MenuModel::TYPE_CHECK, menu.GetTypeAt(2)); - EXPECT_EQ(999, menu.GetCommandIdAt(2)); - EXPECT_EQ(base::ASCIIToUTF16("check"), menu.GetLabelAt(2)); - EXPECT_TRUE(menu.IsEnabledAt(2)); - EXPECT_FALSE(menu.IsItemCheckedAt(2)); - - EXPECT_EQ(ui::MenuModel::TYPE_RADIO, menu.GetTypeAt(3)); - EXPECT_EQ(1337, menu.GetCommandIdAt(3)); - EXPECT_EQ(base::ASCIIToUTF16("radio"), menu.GetLabelAt(3)); - EXPECT_FALSE(menu.IsEnabledAt(3)); - EXPECT_TRUE(menu.IsItemCheckedAt(3)); - - // The default contents should appear at the bottom. - EXPECT_EQ(CommandId::MENU_AUTO_HIDE, menu.GetCommandIdAt(4)); - EXPECT_EQ(CommandId::MENU_ALIGNMENT_MENU, menu.GetCommandIdAt(5)); - EXPECT_EQ(CommandId::MENU_CHANGE_WALLPAPER, menu.GetCommandIdAt(6)); + EXPECT_EQ(ui::MenuModel::TYPE_RADIO, menu.GetTypeAt(2)); + EXPECT_EQ(1337, menu.GetCommandIdAt(2)); + EXPECT_EQ(base::ASCIIToUTF16("radio"), menu.GetLabelAt(2)); + EXPECT_FALSE(menu.IsEnabledAt(2)); + EXPECT_TRUE(menu.IsItemCheckedAt(2)); // Invoking a custom item should execute the command id on the delegate. - menu.ActivatedAt(2); + menu.ActivatedAt(1); EXPECT_EQ(999, delegate.last_executed_command()); } @@ -259,44 +275,54 @@ EXPECT_NE(-1, secondary_menu.GetIndexOfCommandId(CommandId::MENU_AUTO_HIDE)); } -TEST_F(ShelfContextMenuModelTest, DisableAutoHideOptionOnTabletMode) { +// Tests that the autohide and alignment menu options are not included in tablet +// mode. +TEST_F(ShelfContextMenuModelTest, ExcludeClamshellOptionsOnTabletMode) { TabletModeController* tablet_mode_controller = Shell::Get()->tablet_mode_controller(); int64_t primary_id = GetPrimaryDisplay().id(); - // Tests that in tablet mode, shelf auto-hide option is disabled. + // In tablet mode, the wallpaper picker should be the only option because the + // other options are disabled. tablet_mode_controller->EnableTabletModeWindowManager(true); ShelfContextMenuModel menu1(MenuItemList(), nullptr, primary_id); - ASSERT_EQ(CommandId::MENU_AUTO_HIDE, menu1.GetCommandIdAt(0)); - EXPECT_FALSE(menu1.IsEnabledAt(0)); - EXPECT_TRUE(menu1.IsVisibleAt(0)); + EXPECT_EQ(1, menu1.GetItemCount()); + EXPECT_EQ(ShelfContextMenuModel::MENU_CHANGE_WALLPAPER, + menu1.GetCommandIdAt(0)); - // Tests that exiting tablet mode reenables the auto-hide context menu item. + // Test that a menu shown out of tablet mode includes all three options: + // MENU_AUTO_HIDE, MENU_ALIGNMENT_MENU, and MENU_CHANGE_WALLPAPER. tablet_mode_controller->EnableTabletModeWindowManager(false); ShelfContextMenuModel menu2(MenuItemList(), nullptr, primary_id); - ASSERT_EQ(CommandId::MENU_AUTO_HIDE, menu2.GetCommandIdAt(0)); + EXPECT_EQ(3, menu2.GetItemCount()); + + // Test the auto hide option. + EXPECT_EQ(ShelfContextMenuModel::MENU_AUTO_HIDE, menu2.GetCommandIdAt(0)); EXPECT_TRUE(menu2.IsEnabledAt(0)); - EXPECT_TRUE(menu2.IsVisibleAt(0)); -} -TEST_F(ShelfContextMenuModelTest, DisableAlignmentMenuOnTabletMode) { - TabletModeController* tablet_mode_controller = - Shell::Get()->tablet_mode_controller(); - int64_t primary_id = GetPrimaryDisplay().id(); - - // Tests that in tablet mode, shelf alignment menu is disabled. - tablet_mode_controller->EnableTabletModeWindowManager(true); - ShelfContextMenuModel menu1(MenuItemList(), nullptr, primary_id); - ASSERT_EQ(CommandId::MENU_ALIGNMENT_MENU, menu1.GetCommandIdAt(1)); - EXPECT_FALSE(menu1.IsEnabledAt(1)); - EXPECT_TRUE(menu1.IsVisibleAt(1)); - - // Tests that exiting tablet mode reenables the shelf alignment menu. - tablet_mode_controller->EnableTabletModeWindowManager(false); - ShelfContextMenuModel menu2(MenuItemList(), nullptr, primary_id); - ASSERT_EQ(CommandId::MENU_ALIGNMENT_MENU, menu2.GetCommandIdAt(1)); + // Test the shelf alignment menu option. + EXPECT_EQ(ShelfContextMenuModel::MENU_ALIGNMENT_MENU, + menu2.GetCommandIdAt(1)); EXPECT_TRUE(menu2.IsEnabledAt(1)); - EXPECT_TRUE(menu2.IsVisibleAt(1)); + + // Test the shelf alignment submenu. + ui::MenuModel* submenu = menu2.GetSubmenuModelAt(1); + EXPECT_EQ(ShelfContextMenuModel::MENU_ALIGNMENT_LEFT, + submenu->GetCommandIdAt(0)); + EXPECT_TRUE(submenu->IsEnabledAt(0)); + + EXPECT_EQ(ShelfContextMenuModel::MENU_ALIGNMENT_BOTTOM, + submenu->GetCommandIdAt(1)); + EXPECT_TRUE(submenu->IsEnabledAt(1)); + + EXPECT_EQ(ShelfContextMenuModel::MENU_ALIGNMENT_RIGHT, + submenu->GetCommandIdAt(2)); + EXPECT_TRUE(submenu->IsEnabledAt(2)); + + // Test the wallpaper picker option. + EXPECT_EQ(ShelfContextMenuModel::MENU_CHANGE_WALLPAPER, + menu2.GetCommandIdAt(2)); + EXPECT_TRUE(menu2.IsEnabledAt(2)); } TEST_F(ShelfContextMenuModelTest, CommandIdsMatchEnumsForHistograms) {
diff --git a/ash/shelf/shelf_view_unittest.cc b/ash/shelf/shelf_view_unittest.cc index c3728af7..e5410bb 100644 --- a/ash/shelf/shelf_view_unittest.cc +++ b/ash/shelf/shelf_view_unittest.cc
@@ -1993,33 +1993,6 @@ EXPECT_FALSE(test_api_->CloseMenu()); } -// Tests that the app list button shows a context menu on right click when -// touchable app context menus are not enabled. -TEST_F(ShelfViewTest, AppListButtonShowsContextMenu) { - ui::test::EventGenerator* generator = GetEventGenerator(); - AppListButton* app_list_button = shelf_view_->GetAppListButton(); - generator->MoveMouseTo(app_list_button->GetBoundsInScreen().CenterPoint()); - generator->PressRightButton(); - EXPECT_TRUE(test_api_->CloseMenu()); -} - -// Tests that a ShelfButton ink drop highlight is set to ACTIVATED when a menu -// is shown by mouse. -TEST_F(ShelfViewTest, ShelfButtonShowsInkDropHighlightOnMenuShow) { - const ShelfID id_0 = AddApp(); - ShelfButton* button_0 = GetButtonByID(id_0); - ui::test::EventGenerator* generator = GetEventGenerator(); - generator->MoveMouseTo(button_0->GetBoundsInScreen().CenterPoint()); - generator->PressRightButton(); - EXPECT_EQ(views::InkDropState::ACTIVATED, - button_0->GetInkDropForTesting()->GetTargetInkDropState()); - - // Close the menu, the InkDropState should transition to HIDDEN. - EXPECT_TRUE(test_api_->CloseMenu()); - EXPECT_EQ(views::InkDropState::HIDDEN, - button_0->GetInkDropForTesting()->GetTargetInkDropState()); -} - // Tests that ShelfWindowWatcher buttons show a context menu on right click. TEST_F(ShelfViewTest, ShelfWindowWatcherButtonShowsContextMenu) { ui::test::EventGenerator* generator = GetEventGenerator(); @@ -2767,7 +2740,10 @@ mouse_location, ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON, 0); button->OnMouseReleased(release_event); - test_api_->CloseMenu(); + EXPECT_EQ(views::InkDropState::ACTIVATED, + browser_button_ink_drop_->GetTargetInkDropState()); + EXPECT_TRUE(test_api_->CloseMenu()); + EXPECT_EQ(views::InkDropState::HIDDEN, browser_button_ink_drop_->GetTargetInkDropState()); EXPECT_THAT(browser_button_ink_drop_->GetAndResetRequestedStates(),
diff --git a/ash/shell.cc b/ash/shell.cc index e7e2e91..86c192e 100644 --- a/ash/shell.cc +++ b/ash/shell.cc
@@ -790,6 +790,11 @@ // the former may use the latter before destruction. app_list_controller_.reset(); + // Shutdown |assistant_controller_| to properly remove observer on + // |tablet_mode_controller_|. + if (chromeos::switches::IsAssistantEnabled()) + assistant_controller_->ShutDown(); + // Destroy tablet mode controller early on since it has some observers which // need to be removed. tablet_mode_controller_.reset();
diff --git a/ash/system/power/power_event_observer.cc b/ash/system/power/power_event_observer.cc index af67a117..ec9369e 100644 --- a/ash/system/power/power_event_observer.cc +++ b/ash/system/power/power_event_observer.cc
@@ -7,7 +7,6 @@ #include <map> #include <utility> -#include "ash/public/cpp/config.h" #include "ash/root_window_controller.h" #include "ash/session/session_controller.h" #include "ash/shell.h" @@ -283,10 +282,7 @@ void PowerEventObserver::SuspendDone(const base::TimeDelta& sleep_duration) { suspend_in_progress_ = false; - // TODO(derat): After mus exposes a method for resuming displays, call it - // here: http://crbug.com/692193 - if (Shell::GetAshConfig() != Config::MASH_DEPRECATED) - Shell::Get()->display_configurator()->ResumeDisplays(); + Shell::Get()->display_configurator()->ResumeDisplays(); Shell::Get()->system_tray_model()->clock()->NotifyRefreshClock(); // If the suspend request was being blocked while waiting for the lock @@ -348,15 +344,9 @@ ui::UserActivityDetector::Get()->OnDisplayPowerChanging(); - // TODO(derat): After mus exposes a method for suspending displays, call it - // here: http://crbug.com/692193 - if (Shell::GetAshConfig() != Config::MASH_DEPRECATED) { - Shell::Get()->display_configurator()->SuspendDisplays( - base::Bind(&OnSuspendDisplaysCompleted, - base::Passed(&displays_suspended_callback_))); - } else { - std::move(displays_suspended_callback_).Run(); - } + Shell::Get()->display_configurator()->SuspendDisplays( + base::Bind(&OnSuspendDisplaysCompleted, + base::Passed(&displays_suspended_callback_))); } void PowerEventObserver::EndPendingWallpaperAnimations() {
diff --git a/ash/wm/splitview/split_view_controller.cc b/ash/wm/splitview/split_view_controller.cc index 4624a93..755b0ecb 100644 --- a/ash/wm/splitview/split_view_controller.cc +++ b/ash/wm/splitview/split_view_controller.cc
@@ -82,11 +82,6 @@ bounds_in_screen.y())); } -// Transpose the given |rect|. -void TransposeRect(gfx::Rect* rect) { - rect->SetRect(rect->y(), rect->x(), rect->height(), rect->width()); -} - mojom::SplitViewState ToMojomSplitViewState(SplitViewController::State state) { switch (state) { case SplitViewController::NO_SNAP:
diff --git a/ash/wm/splitview/split_view_controller_unittest.cc b/ash/wm/splitview/split_view_controller_unittest.cc index 543ab095..9ad77458 100644 --- a/ash/wm/splitview/split_view_controller_unittest.cc +++ b/ash/wm/splitview/split_view_controller_unittest.cc
@@ -2299,6 +2299,49 @@ EXPECT_FALSE(overview_observer->overview_animate_when_exiting()); } +// Tests that there is no top drag indicator if drag a window in portrait screen +// orientation. +TEST_F(SplitViewTabDraggingTest, DragIndicatorsInPortraitOrientationTest) { + UpdateDisplay("800x600"); + int64_t display_id = display::Screen::GetScreen()->GetPrimaryDisplay().id(); + display::DisplayManager* display_manager = Shell::Get()->display_manager(); + display::test::ScopedSetInternalDisplayId set_internal(display_manager, + display_id); + ScreenOrientationControllerTestApi test_api( + Shell::Get()->screen_orientation_controller()); + ASSERT_EQ(test_api.GetCurrentOrientation(), + OrientationLockType::kLandscapePrimary); + + const gfx::Rect bounds(0, 0, 400, 400); + std::unique_ptr<aura::Window> window(CreateWindow(bounds)); + wm::GetWindowState(window.get())->Maximize(); + EXPECT_TRUE(wm::GetWindowState(window.get())->IsMaximized()); + std::unique_ptr<WindowResizer> resizer = + StartDrag(window.get(), window.get()); + ASSERT_TRUE(resizer.get()); + EXPECT_TRUE(Shell::Get()->window_selector_controller()->IsSelecting()); + // Drag the window past the indicators threshold to show the indicators. + DragWindowTo(resizer.get(), + gfx::Point(200, GetIndicatorsThreshold(window.get()))); + EXPECT_EQ(GetIndicatorState(resizer.get()), IndicatorState::kDragArea); + CompleteDrag(std::move(resizer)); + EXPECT_TRUE(wm::GetWindowState(window.get())->IsMaximized()); + + // Rotate the screen by 270 degree to portrait primary orientation. + test_api.SetDisplayRotation(display::Display::ROTATE_270, + display::Display::RotationSource::ACTIVE); + EXPECT_EQ(test_api.GetCurrentOrientation(), + OrientationLockType::kPortraitPrimary); + resizer = StartDrag(window.get(), window.get()); + ASSERT_TRUE(resizer.get()); + // Drag the window past the indicators threshold to show the indicators. + DragWindowTo(resizer.get(), + gfx::Point(200, GetIndicatorsThreshold(window.get()))); + EXPECT_EQ(GetIndicatorState(resizer.get()), IndicatorState::kDragAreaRight); + CompleteDrag(std::move(resizer)); + EXPECT_TRUE(wm::GetWindowState(window.get())->IsMaximized()); +} + class TestWindowDelegateWithWidget : public views::WidgetDelegate { public: TestWindowDelegateWithWidget(bool can_activate)
diff --git a/ash/wm/splitview/split_view_drag_indicators.cc b/ash/wm/splitview/split_view_drag_indicators.cc index 46ac019..a4d5309 100644 --- a/ash/wm/splitview/split_view_drag_indicators.cc +++ b/ash/wm/splitview/split_view_drag_indicators.cc
@@ -67,36 +67,16 @@ return transform; } -bool IsPreviewAreaState(IndicatorState indicator_state) { - return indicator_state == IndicatorState::kPreviewAreaLeft || - indicator_state == IndicatorState::kPreviewAreaRight; -} - -// Calculate whether the preview area should physically be on the left or top -// of the screen. kPreviewAreaLeft and kPreviewAreaRight correspond with -// LEFT_SNAPPED and RIGHT_SNAPPED which do not always correspond to the physical -// left and right of the screen. See split_view_controller.h for more details. -bool IsPreviewAreaOnLeftTopOfScreen(IndicatorState indicator_state) { - SplitViewController* split_view_controller = - Shell::Get()->split_view_controller(); - return (indicator_state == IndicatorState::kPreviewAreaLeft && - split_view_controller->IsCurrentScreenOrientationPrimary()) || - (indicator_state == IndicatorState::kPreviewAreaRight && - !split_view_controller->IsCurrentScreenOrientationPrimary()); -} - // Helper function to compute the transform for the indicator labels when the // view changes states. |main_transform| determines what ratio of the highlight // we want to shift to. |non_transformed_bounds| represents the bounds of the // label before its transform is applied; the centerpoint is used to calculate -// the amount of shift. One of |highlight_width| or |highlight_height| will be -// used to calculate the amount of shift as well, depending on |landscape|. If -// the label is not |left_or_top| (right or bottom) we will translate in the -// other direction. +// the amount of shift. |highlight_length| will be used to calculate the amount +// of shift as well. If the label is not |left_or_top| (right or bottom) we +// will translate in the other direction. gfx::Transform ComputeLabelTransform(bool main_transform, const gfx::Rect& non_transformed_bounds, - int highlight_width, - int highlight_height, + int highlight_length, bool landscape, bool left_or_top) { // Compute the distance of the translation. @@ -106,7 +86,6 @@ const gfx::Point center_point = non_transformed_bounds.CenterPoint(); const int primary_axis_center = landscape ? center_point.x() : center_point.y(); - const int highlight_length = landscape ? highlight_width : highlight_height; const float translate = std::fabs(ratio * highlight_length - primary_axis_center); @@ -123,11 +102,55 @@ } // namespace +// static +bool SplitViewDragIndicators::IsPreviewAreaState( + IndicatorState indicator_state) { + return indicator_state == IndicatorState::kPreviewAreaLeft || + indicator_state == IndicatorState::kPreviewAreaRight; +} + +// static +bool SplitViewDragIndicators::IsLeftIndicatorState( + IndicatorState indicator_state) { + return indicator_state == IndicatorState::kDragAreaLeft || + indicator_state == IndicatorState::kCannotSnapLeft; +} + +// static +bool SplitViewDragIndicators::IsRightIndicatorState( + IndicatorState indicator_state) { + return indicator_state == IndicatorState::kDragAreaRight || + indicator_state == IndicatorState::kCannotSnapRight; +} + +// static +bool SplitViewDragIndicators::IsCannotSnapState( + IndicatorState indicator_state) { + return indicator_state == IndicatorState::kCannotSnap || + indicator_state == IndicatorState::kCannotSnapLeft || + indicator_state == IndicatorState::kCannotSnapRight; +} + +// static +bool SplitViewDragIndicators::IsPreviewAreaOnLeftTopOfScreen( + IndicatorState indicator_state) { + SplitViewController* split_view_controller = + Shell::Get()->split_view_controller(); + // kPreviewAreaLeft and kPreviewAreaRight correspond with LEFT_SNAPPED and + // RIGHT_SNAPPED which do not always correspond to the physical left and right + // of the screen. See split_view_controller.h for more details. + return (indicator_state == IndicatorState::kPreviewAreaLeft && + split_view_controller->IsCurrentScreenOrientationPrimary()) || + (indicator_state == IndicatorState::kPreviewAreaRight && + !split_view_controller->IsCurrentScreenOrientationPrimary()); +} + // View which contains a label and can be rotated. Used by and rotated by // SplitViewDragIndicatorsView. class SplitViewDragIndicators::RotatedImageLabelView : public views::View { public: - RotatedImageLabelView() { + explicit RotatedImageLabelView(bool is_right_or_bottom) + : is_right_or_bottom_(is_right_or_bottom) { label_ = new views::Label(base::string16(), views::style::CONTEXT_LABEL); label_->SetPaintToLayer(); label_->layer()->SetFillsBoundsOpaquely(false); @@ -165,12 +188,47 @@ ComputeRotateAroundCenterTransform(bounds, angle)); } + // Called to update the opacity of the labels view on |indicator_state|. + void OnIndicatorTypeChanged(IndicatorState indicator_state, + IndicatorState previous_indicator_state) { + if (indicator_state == IndicatorState::kNone || + IsPreviewAreaState(indicator_state)) { + DoSplitviewOpacityAnimation(layer(), SPLITVIEW_ANIMATION_TEXT_FADE_OUT); + return; + } + + // No need to update left/top label view for right indicator state and also + // no need to update right/bottom label view for left indicator state. + if ((!is_right_or_bottom_ && IsRightIndicatorState(indicator_state)) || + (is_right_or_bottom_ && IsLeftIndicatorState(indicator_state))) { + return; + } + + SetLabelText(l10n_util::GetStringUTF16(IsCannotSnapState(indicator_state) + ? IDS_ASH_SPLIT_VIEW_CANNOT_SNAP + : IDS_ASH_SPLIT_VIEW_GUIDANCE)); + SplitviewAnimationType animation_type; + if (Shell::Get()->split_view_controller()->state() == + SplitViewController::NO_SNAP) { + animation_type = IsPreviewAreaState(previous_indicator_state) + ? SPLITVIEW_ANIMATION_TEXT_FADE_IN_WITH_HIGHLIGHT + : SPLITVIEW_ANIMATION_TEXT_FADE_IN; + } else { + animation_type = SPLITVIEW_ANIMATION_TEXT_FADE_OUT_WITH_HIGHLIGHT; + } + DoSplitviewOpacityAnimation(layer(), animation_type); + } + protected: gfx::Size CalculatePreferredSize() const override { return label_parent_->GetPreferredSize(); } private: + // True if the label view is the right/bottom side one, false if it is the + // left/top one. + const bool is_right_or_bottom_; + RoundedRectView* label_parent_ = nullptr; views::Label* label_ = nullptr; @@ -201,8 +259,10 @@ AddChildView(left_highlight_view_); AddChildView(right_highlight_view_); - left_rotated_view_ = new RotatedImageLabelView(); - right_rotated_view_ = new RotatedImageLabelView(); + left_rotated_view_ = + new RotatedImageLabelView(/*is_right_or_bottom=*/false); + right_rotated_view_ = + new RotatedImageLabelView(/*is_right_or_bottom=*/true); AddChildView(left_rotated_view_); AddChildView(right_rotated_view_); @@ -224,77 +284,15 @@ previous_indicator_state_ = indicator_state_; indicator_state_ = indicator_state; - switch (indicator_state) { - case IndicatorState::kNone: - DoSplitviewOpacityAnimation(left_highlight_view_->layer(), - SPLITVIEW_ANIMATION_HIGHLIGHT_FADE_OUT); - DoSplitviewOpacityAnimation(right_highlight_view_->layer(), - SPLITVIEW_ANIMATION_HIGHLIGHT_FADE_OUT); - DoSplitviewOpacityAnimation(left_rotated_view_->layer(), - SPLITVIEW_ANIMATION_TEXT_FADE_OUT); - DoSplitviewOpacityAnimation(right_rotated_view_->layer(), - SPLITVIEW_ANIMATION_TEXT_FADE_OUT); - return; - case IndicatorState::kDragArea: - case IndicatorState::kCannotSnap: { - const bool show = Shell::Get()->split_view_controller()->state() == - SplitViewController::NO_SNAP; + left_rotated_view_->OnIndicatorTypeChanged(indicator_state, + previous_indicator_state_); + right_rotated_view_->OnIndicatorTypeChanged(indicator_state, + previous_indicator_state_); + left_highlight_view_->OnIndicatorTypeChanged(indicator_state); + right_highlight_view_->OnIndicatorTypeChanged(indicator_state); - for (RotatedImageLabelView* view : GetTextViews()) { - view->SetLabelText(l10n_util::GetStringUTF16( - indicator_state == IndicatorState::kCannotSnap - ? IDS_ASH_SPLIT_VIEW_CANNOT_SNAP - : IDS_ASH_SPLIT_VIEW_GUIDANCE)); - SplitviewAnimationType animation_type; - if (!show) { - animation_type = SPLITVIEW_ANIMATION_TEXT_FADE_OUT_WITH_HIGHLIGHT; - } else { - animation_type = - IsPreviewAreaState(previous_indicator_state_) - ? SPLITVIEW_ANIMATION_TEXT_FADE_IN_WITH_HIGHLIGHT - : SPLITVIEW_ANIMATION_TEXT_FADE_IN; - } - DoSplitviewOpacityAnimation(view->layer(), animation_type); - } - - for (SplitViewHighlightView* view : GetHighlightViews()) { - view->SetColor(indicator_state == IndicatorState::kCannotSnap - ? SK_ColorBLACK - : SK_ColorWHITE); - DoSplitviewOpacityAnimation( - view->layer(), show ? SPLITVIEW_ANIMATION_HIGHLIGHT_FADE_IN - : SPLITVIEW_ANIMATION_HIGHLIGHT_FADE_OUT); - } - - Layout(previous_indicator_state_ != IndicatorState::kNone); - return; - } - case IndicatorState::kPreviewAreaLeft: - case IndicatorState::kPreviewAreaRight: { - for (RotatedImageLabelView* view : GetTextViews()) { - DoSplitviewOpacityAnimation(view->layer(), - SPLITVIEW_ANIMATION_TEXT_FADE_OUT); - } - - if (IsPreviewAreaOnLeftTopOfScreen(indicator_state_)) { - DoSplitviewOpacityAnimation(left_highlight_view_->layer(), - SPLITVIEW_ANIMATION_PREVIEW_AREA_FADE_IN); - DoSplitviewOpacityAnimation( - right_highlight_view_->layer(), - SPLITVIEW_ANIMATION_OTHER_HIGHLIGHT_FADE_OUT); - } else { - DoSplitviewOpacityAnimation( - left_highlight_view_->layer(), - SPLITVIEW_ANIMATION_OTHER_HIGHLIGHT_FADE_OUT); - DoSplitviewOpacityAnimation(right_highlight_view_->layer(), - SPLITVIEW_ANIMATION_PREVIEW_AREA_FADE_IN); - } - Layout(/*animate=*/true); - return; - } - } - - NOTREACHED(); + if (indicator_state != IndicatorState::kNone) + Layout(previous_indicator_state_ != IndicatorState::kNone); } views::View* GetViewForIndicatorType(IndicatorType type) { @@ -325,31 +323,30 @@ ->split_view_controller() ->IsCurrentScreenOrientationLandscape(); + const int display_width = landscape ? width() : height(); + const int display_height = landscape ? height() : width(); + // Calculate the bounds of the two highlight regions. const int highlight_width = - landscape ? width() * kHighlightScreenPrimaryAxisRatio - : width() - 2 * kHighlightScreenEdgePaddingDp; + display_width * kHighlightScreenPrimaryAxisRatio; const int highlight_height = - landscape ? height() - 2 * kHighlightScreenEdgePaddingDp - : height() * kHighlightScreenPrimaryAxisRatio; + display_height - 2 * kHighlightScreenEdgePaddingDp; + gfx::Size highlight_size(highlight_width, highlight_height); // The origin of the right highlight view in landscape, or the bottom // highlight view in portrait. - const gfx::Point right_bottom_origin( - landscape ? width() - highlight_width - kHighlightScreenEdgePaddingDp - : kHighlightScreenEdgePaddingDp, - landscape - ? kHighlightScreenEdgePaddingDp - : height() - highlight_height - kHighlightScreenEdgePaddingDp); + gfx::Point right_bottom_origin( + display_width - highlight_width - kHighlightScreenEdgePaddingDp, + kHighlightScreenEdgePaddingDp); - gfx::Rect left_highlight_bounds, right_highlight_bounds; - left_highlight_bounds = - gfx::Rect(kHighlightScreenEdgePaddingDp, kHighlightScreenEdgePaddingDp, - highlight_width, highlight_height); - right_highlight_bounds = - gfx::Rect(right_bottom_origin.x(), right_bottom_origin.y(), - highlight_width, highlight_height); - + const gfx::Point hightlight_padding_point(kHighlightScreenEdgePaddingDp, + kHighlightScreenEdgePaddingDp); + gfx::Rect left_highlight_bounds(hightlight_padding_point, highlight_size); + gfx::Rect right_highlight_bounds(right_bottom_origin, highlight_size); + if (!landscape) { + TransposeRect(&left_highlight_bounds); + TransposeRect(&right_highlight_bounds); + } const bool preview_left = (indicator_state_ == IndicatorState::kPreviewAreaLeft); if (IsPreviewAreaState(indicator_state_)) { @@ -365,29 +362,19 @@ // Calculate the bounds of the other highlight, which is the one that // shrinks and fades away, while the other one, the preview area, expands // and takes up half the screen. - gfx::Rect other_bounds; - if (landscape) { - other_bounds.set_size( - gfx::Size(kOtherHighlightLengthDp, - height() - 2 * kHighlightScreenEdgePaddingDp)); - other_bounds.set_origin(gfx::Point( - width() - kOtherHighlightLengthDp - kHighlightScreenEdgePaddingDp, - kHighlightScreenEdgePaddingDp)); - } else { - other_bounds.set_size( - gfx::Size(width() - 2 * kHighlightScreenEdgePaddingDp, - kOtherHighlightLengthDp)); - other_bounds.set_origin(gfx::Point(kHighlightScreenEdgePaddingDp, - height() - kOtherHighlightLengthDp - - kHighlightScreenEdgePaddingDp)); - } + gfx::Rect other_bounds( + display_width - kOtherHighlightLengthDp - + kHighlightScreenEdgePaddingDp, + kHighlightScreenEdgePaddingDp, kOtherHighlightLengthDp, + display_height - 2 * kHighlightScreenEdgePaddingDp); + if (!landscape) + TransposeRect(&other_bounds); if (IsPreviewAreaOnLeftTopOfScreen(indicator_state_)) { left_highlight_bounds = preview_area_bounds; right_highlight_bounds = other_bounds; } else { - other_bounds.set_origin(gfx::Point(kHighlightScreenEdgePaddingDp, - kHighlightScreenEdgePaddingDp)); + other_bounds.set_origin(hightlight_padding_point); left_highlight_bounds = other_bounds; right_highlight_bounds = preview_area_bounds; } @@ -400,14 +387,24 @@ // Calculate the bounds of the views which contain the guidance text and // icon. Rotate the two views in landscape mode. - const gfx::Size size(left_rotated_view_->GetPreferredSize().width(), - kSplitviewLabelPreferredHeightDp); - gfx::Rect left_rotated_bounds(highlight_width / 2 - size.width() / 2, - highlight_height / 2 - size.height() / 2, - size.width(), size.height()); + const int size_width = + indicator_state_ == IndicatorState::kDragAreaLeft + ? left_rotated_view_->GetPreferredSize().width() + : right_rotated_view_->GetPreferredSize().width(); + gfx::Size size(size_width, kSplitviewLabelPreferredHeightDp); + if (!landscape) + highlight_size.SetSize(highlight_size.height(), highlight_size.width()); + gfx::Rect left_rotated_bounds( + highlight_size.width() / 2 - size.width() / 2, + highlight_size.height() / 2 - size.height() / 2, size.width(), + size.height()); gfx::Rect right_rotated_bounds = left_rotated_bounds; - left_rotated_bounds.Offset(kHighlightScreenEdgePaddingDp, - kHighlightScreenEdgePaddingDp); + left_rotated_bounds.Offset(hightlight_padding_point.x(), + hightlight_padding_point.y()); + if (!landscape) { + right_bottom_origin.SetPoint(right_bottom_origin.y(), + right_bottom_origin.x()); + } right_rotated_bounds.Offset(right_bottom_origin.x(), right_bottom_origin.y()); @@ -430,12 +427,12 @@ SplitviewAnimationType animation = SPLITVIEW_ANIMATION_TEXT_SLIDE_IN; if (IsPreviewAreaState(indicator_state_)) { animation = SPLITVIEW_ANIMATION_TEXT_SLIDE_OUT; - main_rotated_transform = ComputeLabelTransform( - preview_left, left_rotated_bounds, highlight_width, highlight_height, - landscape, preview_left); - other_rotated_transform = ComputeLabelTransform( - !preview_left, left_rotated_bounds, highlight_width, highlight_height, - landscape, preview_left); + main_rotated_transform = + ComputeLabelTransform(preview_left, left_rotated_bounds, + highlight_width, landscape, preview_left); + other_rotated_transform = + ComputeLabelTransform(!preview_left, left_rotated_bounds, + highlight_width, landscape, preview_left); } DoSplitviewTransformAnimation( @@ -446,13 +443,6 @@ preview_left ? other_rotated_transform : main_rotated_transform); } - std::vector<SplitViewHighlightView*> GetHighlightViews() { - return {left_highlight_view_, right_highlight_view_}; - } - std::vector<RotatedImageLabelView*> GetTextViews() { - return {left_rotated_view_, right_rotated_view_}; - } - SplitViewHighlightView* left_highlight_view_ = nullptr; SplitViewHighlightView* right_highlight_view_ = nullptr; RotatedImageLabelView* left_rotated_view_ = nullptr;
diff --git a/ash/wm/splitview/split_view_drag_indicators.h b/ash/wm/splitview/split_view_drag_indicators.h index ee35f4b..f99b881 100644 --- a/ash/wm/splitview/split_view_drag_indicators.h +++ b/ash/wm/splitview/split_view_drag_indicators.h
@@ -22,9 +22,30 @@ // Enum which contains the possible states SplitViewDragIndicators can be in. enum class IndicatorState { kNone, + // Showing both left/top and right/bottom drag guidances. kDragArea, + + // Showing only left/top drag guidance. + kDragAreaLeft, + + // Showing only right/bottom drag guidance. + kDragAreaRight, + + // Showing both left/top and right/bottom cannot drag indicators. kCannotSnap, + + // Showing only left/top cannot drag indicator. + kCannotSnapLeft, + + // Showing only right/bottom cannot drag indicator. + kCannotSnapRight, + + // Showing a left/top preview area with the same bounds as left/top snapped + // window. kPreviewAreaLeft, + + // Showing a right/bottom preview area with the same bounds as right/bottom + // snapped window. kPreviewAreaRight }; @@ -43,6 +64,15 @@ // window has entered a snap region. class ASH_EXPORT SplitViewDragIndicators { public: + static bool IsPreviewAreaState(IndicatorState indicator_state); + static bool IsLeftIndicatorState(IndicatorState indicator_state); + static bool IsRightIndicatorState(IndicatorState indicator_state); + static bool IsCannotSnapState(IndicatorState indicator_state); + + // Calculates whether the preview area should physically be on the left or + // top of the screen. + static bool IsPreviewAreaOnLeftTopOfScreen(IndicatorState indicator_state); + SplitViewDragIndicators(); ~SplitViewDragIndicators();
diff --git a/ash/wm/splitview/split_view_highlight_view.cc b/ash/wm/splitview/split_view_highlight_view.cc index f0d8d09..60cf561 100644 --- a/ash/wm/splitview/split_view_highlight_view.cc +++ b/ash/wm/splitview/split_view_highlight_view.cc
@@ -4,7 +4,9 @@ #include "ash/wm/splitview/split_view_highlight_view.h" +#include "ash/shell.h" #include "ash/wm/overview/rounded_rect_view.h" +#include "ash/wm/splitview/split_view_controller.h" #include "ash/wm/splitview/split_view_utils.h" #include "ui/gfx/canvas.h" #include "ui/views/view.h" @@ -168,4 +170,43 @@ middle_->layer()->SetColor(color); } +void SplitViewHighlightView::OnIndicatorTypeChanged( + IndicatorState indicator_state) { + if (indicator_state == IndicatorState::kNone) { + DoSplitviewOpacityAnimation(layer(), + SPLITVIEW_ANIMATION_HIGHLIGHT_FADE_OUT); + return; + } + + if (SplitViewDragIndicators::IsPreviewAreaState(indicator_state)) { + const bool is_preview_on_left_or_top = + SplitViewDragIndicators::IsPreviewAreaOnLeftTopOfScreen( + indicator_state); + const bool should_fade_in = is_right_or_bottom_ ? !is_preview_on_left_or_top + : is_preview_on_left_or_top; + DoSplitviewOpacityAnimation( + layer(), should_fade_in ? SPLITVIEW_ANIMATION_PREVIEW_AREA_FADE_IN + : SPLITVIEW_ANIMATION_OTHER_HIGHLIGHT_FADE_OUT); + return; + } + + // No need to update left/top highlight view for right indicator state and + // also no need to update right/bottom highlight view for left indicator + // state. + if ((!is_right_or_bottom_ && + SplitViewDragIndicators::IsRightIndicatorState(indicator_state)) || + (is_right_or_bottom_ && + SplitViewDragIndicators::IsLeftIndicatorState(indicator_state))) { + return; + } + SetColor(SplitViewDragIndicators::IsCannotSnapState(indicator_state) + ? SK_ColorBLACK + : SK_ColorWHITE); + DoSplitviewOpacityAnimation(layer(), + Shell::Get()->split_view_controller()->state() == + SplitViewController::NO_SNAP + ? SPLITVIEW_ANIMATION_HIGHLIGHT_FADE_IN + : SPLITVIEW_ANIMATION_HIGHLIGHT_FADE_OUT); +} + } // namespace ash
diff --git a/ash/wm/splitview/split_view_highlight_view.h b/ash/wm/splitview/split_view_highlight_view.h index ea2dd55..08cdfc6 100644 --- a/ash/wm/splitview/split_view_highlight_view.h +++ b/ash/wm/splitview/split_view_highlight_view.h
@@ -6,6 +6,7 @@ #define ASH_WM_SPLITVIEW_SPLIT_VIEW_HIGHLIGHT_VIEW_H_ #include "ash/ash_export.h" +#include "ash/wm/splitview/split_view_drag_indicators.h" #include "ui/views/view.h" namespace ash { @@ -30,6 +31,9 @@ void SetColor(SkColor color); + // Called to update the opacity of the highlights view on |indicator_state|. + void OnIndicatorTypeChanged(IndicatorState indicator_state); + private: friend class SplitViewHighlightViewTestApi; @@ -50,4 +54,4 @@ } // namespace ash -#endif // ASH_WM_SPLITVIEW_SPLIT_VIEW_HIGHLIGHT_VIEW_H_ \ No newline at end of file +#endif // ASH_WM_SPLITVIEW_SPLIT_VIEW_HIGHLIGHT_VIEW_H_
diff --git a/ash/wm/splitview/split_view_utils.cc b/ash/wm/splitview/split_view_utils.cc index 2cef3c9..20c3053 100644 --- a/ash/wm/splitview/split_view_utils.cc +++ b/ash/wm/splitview/split_view_utils.cc
@@ -9,6 +9,7 @@ #include "ui/compositor/layer_animation_observer.h" #include "ui/compositor/layer_animator.h" #include "ui/compositor/scoped_layer_animation_settings.h" +#include "ui/gfx/geometry/rect.h" namespace ash { @@ -190,4 +191,8 @@ layer->SetTransform(target_transform); } +void TransposeRect(gfx::Rect* rect) { + rect->SetRect(rect->y(), rect->x(), rect->height(), rect->width()); +} + } // namespace ash
diff --git a/ash/wm/splitview/split_view_utils.h b/ash/wm/splitview/split_view_utils.h index 534f17d..91d3f2f 100644 --- a/ash/wm/splitview/split_view_utils.h +++ b/ash/wm/splitview/split_view_utils.h
@@ -7,6 +7,10 @@ #include "ui/gfx/transform.h" +namespace gfx { +class Rect; +} // namespace gfx + namespace ui { class Layer; } // namespace ui @@ -66,6 +70,9 @@ SplitviewAnimationType type, const gfx::Transform& target_transform); +// Transposes the given |rect|. +void TransposeRect(gfx::Rect* rect); + } // namespace ash #endif // ASH_WM_SPLITVIEW_SPLIT_VIEW_UTILS_H_
diff --git a/ash/wm/tablet_mode/tablet_mode_window_drag_delegate.cc b/ash/wm/tablet_mode/tablet_mode_window_drag_delegate.cc index 183dad8c..ee4a3d8 100644 --- a/ash/wm/tablet_mode/tablet_mode_window_drag_delegate.cc +++ b/ash/wm/tablet_mode/tablet_mode_window_drag_delegate.cc
@@ -320,7 +320,12 @@ return IndicatorState::kNone; } - return can_snap ? IndicatorState::kDragArea : IndicatorState::kCannotSnap; + // No top drag indicator if in portrait screen orientation. + if (split_view_controller_->IsCurrentScreenOrientationLandscape()) + return can_snap ? IndicatorState::kDragArea : IndicatorState::kCannotSnap; + + return can_snap ? IndicatorState::kDragAreaRight + : IndicatorState::kCannotSnapRight; } void TabletModeWindowDragDelegate::UpdateDraggedWindowTransform(
diff --git a/base/android/java/src/org/chromium/base/ContentUriUtils.java b/base/android/java/src/org/chromium/base/ContentUriUtils.java index add7e8c..e8548ef 100644 --- a/base/android/java/src/org/chromium/base/ContentUriUtils.java +++ b/base/android/java/src/org/chromium/base/ContentUriUtils.java
@@ -221,10 +221,17 @@ @CalledByNative public static String maybeGetDisplayName(String uriString) { Uri uri = Uri.parse(uriString); - String displayName = getDisplayName( - uri, ContextUtils.getApplicationContext(), MediaStore.MediaColumns.DISPLAY_NAME); - return TextUtils.isEmpty(displayName) ? null : displayName; + try { + String displayName = getDisplayName(uri, ContextUtils.getApplicationContext(), + MediaStore.MediaColumns.DISPLAY_NAME); + return TextUtils.isEmpty(displayName) ? null : displayName; + } catch (SecurityException e) { + Log.w(TAG, "Cannot open content uri: " + uriString, e); + } + + // If we are unable to query the content URI, just return null. + return null; } /**
diff --git a/base/message_loop/message_pump_mac.h b/base/message_loop/message_pump_mac.h index fa88c3a..61079cd 100644 --- a/base/message_loop/message_pump_mac.h +++ b/base/message_loop/message_pump_mac.h
@@ -80,6 +80,15 @@ class BASE_EXPORT MessagePumpCFRunLoopBase : public MessagePump { public: + // Mask that determines which modes to use. Exposed for tests. + enum { kCommonModeMask = 0x1, kAllModesMask = 0x1f }; + + // Modes to use for MessagePumpNSApplication that are considered "safe". + // Currently just common and exclusive modes. Ideally, messages would be + // pumped in all modes, but that interacts badly with app modal dialogs (e.g. + // NSAlert). Exposed for tests. + enum { kNSApplicationModalSafeModeMask = 0x13 }; + // MessagePump: void Run(Delegate* delegate) override; void ScheduleWork() override; @@ -128,7 +137,7 @@ class ScopedModeEnabler; // The maximum number of run loop modes that can be monitored. - static constexpr int kNumModes = 4; + static constexpr int kNumModes = 5; // Marking timers as invalid at the right time helps significantly reduce // power use (see the comment in RunDelayedWorkTimer()), however there is no
diff --git a/base/message_loop/message_pump_mac.mm b/base/message_loop/message_pump_mac.mm index fb25201..3ef79d6 100644 --- a/base/message_loop/message_pump_mac.mm +++ b/base/message_loop/message_pump_mac.mm
@@ -30,14 +30,6 @@ namespace { -// Mask that determines which modes to use. -enum { kCommonModeMask = 0x1, kAllModesMask = 0xf }; - -// Modes to use for MessagePumpNSApplication that are considered "safe". -// Currently just common and exclusive modes. Ideally, messages would be pumped -// in all modes, but that interacts badly with app modal dialogs (e.g. NSAlert). -enum { kNSApplicationModalSafeModeMask = 0x3 }; - void NoOp(void* info) { } @@ -156,6 +148,9 @@ // Process work when AppKit is highlighting an item on the main menubar. CFSTR("NSUnhighlightMenuRunLoopMode"), + + // Process work when AppKit is animating the menu bar. + CFSTR("NSAnimationRunLoopMode"), }; static_assert(arraysize(modes) == kNumModes, "mode size mismatch"); static_assert((1 << kNumModes) - 1 == kAllModesMask, @@ -762,16 +757,18 @@ ScopedPumpMessagesInPrivateModes::ScopedPumpMessagesInPrivateModes() { DCHECK(g_app_pump); - DCHECK_EQ(kNSApplicationModalSafeModeMask, g_app_pump->GetModeMask()); + DCHECK_EQ(MessagePumpCFRunLoopBase::kNSApplicationModalSafeModeMask, + g_app_pump->GetModeMask()); // Pumping events in private runloop modes is known to interact badly with // app modal windows like NSAlert. if (![NSApp modalWindow]) - g_app_pump->SetModeMask(kAllModesMask); + g_app_pump->SetModeMask(MessagePumpCFRunLoopBase::kAllModesMask); } ScopedPumpMessagesInPrivateModes::~ScopedPumpMessagesInPrivateModes() { DCHECK(g_app_pump); - g_app_pump->SetModeMask(kNSApplicationModalSafeModeMask); + g_app_pump->SetModeMask( + MessagePumpCFRunLoopBase::kNSApplicationModalSafeModeMask); } int ScopedPumpMessagesInPrivateModes::GetModeMaskForTest() {
diff --git a/base/message_loop/message_pump_mac_unittest.mm b/base/message_loop/message_pump_mac_unittest.mm index 6b63aa1..c30b2d4 100644 --- a/base/message_loop/message_pump_mac_unittest.mm +++ b/base/message_loop/message_pump_mac_unittest.mm
@@ -16,14 +16,6 @@ - (void)runTestThenCloseAlert:(NSAlert*)alert; @end -namespace { - -// Internal constants from message_pump_mac.mm. -constexpr int kAllModesMask = 0xf; -constexpr int kNSApplicationModalSafeModeMask = 0x3; - -} // namespace - namespace base { class TestMessagePumpCFRunLoopBase { @@ -192,7 +184,8 @@ { base::ScopedPumpMessagesInPrivateModes allow_private; // No modal window, so all modes should be pumped. - EXPECT_EQ(kAllModesMask, allow_private.GetModeMaskForTest()); + EXPECT_EQ(MessagePumpCFRunLoopBase::kAllModesMask, + allow_private.GetModeMaskForTest()); } base::scoped_nsobject<NSAlert> alert([[NSAlert alloc] init]); @@ -216,7 +209,7 @@ { base::ScopedPumpMessagesInPrivateModes allow_private; // With a modal window, only safe modes should be pumped. - EXPECT_EQ(kNSApplicationModalSafeModeMask, + EXPECT_EQ(base::MessagePumpCFRunLoopBase::kNSApplicationModalSafeModeMask, allow_private.GetModeMaskForTest()); } [[alert buttons][0] performClick:nil];
diff --git a/base/process/process_metrics.cc b/base/process/process_metrics.cc index c3a70633..63c86d93 100644 --- a/base/process/process_metrics.cc +++ b/base/process/process_metrics.cc
@@ -67,7 +67,9 @@ #if defined(OS_CHROMEOS) GetSwapInfo(&system_metrics.swap_info_); #endif - +#if defined(OS_WIN) + GetSystemPerformanceInfo(&system_metrics.performance_); +#endif return system_metrics; } @@ -85,6 +87,9 @@ #if defined(OS_CHROMEOS) res->Set("swapinfo", swap_info_.ToValue()); #endif +#if defined(OS_WIN) + res->Set("perfinfo", performance_.ToValue()); +#endif return std::move(res); }
diff --git a/base/process/process_metrics.h b/base/process/process_metrics.h index 6bfd93e..79dd76a 100644 --- a/base/process/process_metrics.h +++ b/base/process/process_metrics.h
@@ -475,6 +475,37 @@ BASE_EXPORT bool GetSwapInfo(SwapInfo* swap_info); #endif // defined(OS_CHROMEOS) +struct BASE_EXPORT SystemPerformanceInfo { + SystemPerformanceInfo(); + SystemPerformanceInfo(const SystemPerformanceInfo& other); + + // Serializes the platform specific fields to value. + std::unique_ptr<Value> ToValue() const; + + // Total idle time of all processes in the system (units of 100 ns). + uint64_t idle_time = 0; + // Number of bytes read. + uint64_t read_transfer_count = 0; + // Number of bytes written. + uint64_t write_transfer_count = 0; + // Number of bytes transferred (e.g. DeviceIoControlFile) + uint64_t other_transfer_count = 0; + // The amount of read operations. + uint64_t read_operation_count = 0; + // The amount of write operations. + uint64_t write_operation_count = 0; + // The amount of other operations. + uint64_t other_operation_count = 0; + // The number of pages written to the system's pagefiles. + uint64_t pagefile_pages_written = 0; + // The number of write operations performed on the system's pagefiles. + uint64_t pagefile_pages_write_ios = 0; +}; + +// Retrieves performance counters from the operating system. +// Fills in the provided |info| structure. Returns true on success. +BASE_EXPORT bool GetSystemPerformanceInfo(SystemPerformanceInfo* info); + // Collects and holds performance metrics for system memory and disk. // Provides functionality to retrieve the data on various platforms and // to serialize the stored data. @@ -499,6 +530,9 @@ #if defined(OS_CHROMEOS) SwapInfo swap_info_; #endif +#if defined(OS_WIN) + SystemPerformanceInfo performance_; +#endif }; #if defined(OS_MACOSX) && !defined(OS_IOS)
diff --git a/base/process/process_metrics_win.cc b/base/process/process_metrics_win.cc index 18ef58a..807ae96 100644 --- a/base/process/process_metrics_win.cc +++ b/base/process/process_metrics_win.cc
@@ -25,11 +25,96 @@ // System pagesize. This value remains constant on x86/64 architectures. const int PAGESIZE_KB = 4; -typedef NTSTATUS(WINAPI* NTQUERYSYSTEMINFORMATION)( - SYSTEM_INFORMATION_CLASS SystemInformationClass, - PVOID SystemInformation, - ULONG SystemInformationLength, - PULONG ReturnLength); +// ntstatus.h conflicts with windows.h so define this locally. +#define STATUS_SUCCESS ((NTSTATUS)0x00000000L) + +// Definition of this struct is taken from the book: +// Windows NT/200, Native API reference, Gary Nebbett +struct SYSTEM_PERFORMANCE_INFORMATION { + // Total idle time of all processes in the system (units of 100 ns). + LARGE_INTEGER IdleTime; + // Number of bytes read (by all call to ZwReadFile). + LARGE_INTEGER ReadTransferCount; + // Number of bytes written (by all call to ZwWriteFile). + LARGE_INTEGER WriteTransferCount; + // Number of bytes transferred (e.g. DeviceIoControlFile) + LARGE_INTEGER OtherTransferCount; + // The amount of read operations. + ULONG ReadOperationCount; + // The amount of write operations. + ULONG WriteOperationCount; + // The amount of other operations. + ULONG OtherOperationCount; + ULONG AvailablePages; + ULONG TotalCommittedPages; + ULONG TotalCommitLimit; + ULONG PeakCommitment; + ULONG PageFaults; + ULONG WriteCopyFaults; + ULONG TransitionFaults; + ULONG CacheTransitionFaults; + ULONG DemandZeroFaults; + ULONG PagesRead; + ULONG PageReadIos; + ULONG CacheReads; + ULONG CacheIos; + // The number of pages written to the system's pagefiles. + ULONG PagefilePagesWritten; + // The number of write operations performed on the system's pagefiles. + ULONG PagefilePageWriteIos; + ULONG MappedFilePagesWritten; + ULONG MappedFilePageWriteIos; + ULONG PagedPoolUsage; + ULONG NonPagedPoolUsage; + ULONG PagedPoolAllocs; + ULONG PagedPoolFrees; + ULONG NonPagedPoolAllocs; + ULONG NonPagedPoolFrees; + ULONG TotalFreeSystemPtes; + ULONG SystemCodePage; + ULONG TotalSystemDriverPages; + ULONG TotalSystemCodePages; + ULONG SmallNonPagedLookasideListAllocateHits; + ULONG SmallPagedLookasideListAllocateHits; + ULONG Reserved3; + ULONG MmSystemCachePage; + ULONG PagedPoolPage; + ULONG SystemDriverPage; + ULONG FastReadNoWait; + ULONG FastReadWait; + ULONG FastReadResourceMiss; + ULONG FastReadNotPossible; + ULONG FastMdlReadNoWait; + ULONG FastMdlReadWait; + ULONG FastMdlReadResourceMiss; + ULONG FastMdlReadNotPossible; + ULONG MapDataNoWait; + ULONG MapDataWait; + ULONG MapDataNoWaitMiss; + ULONG MapDataWaitMiss; + ULONG PinMappedDataCount; + ULONG PinReadNoWait; + ULONG PinReadWait; + ULONG PinReadNoWaitMiss; + ULONG PinReadWaitMiss; + ULONG CopyReadNoWait; + ULONG CopyReadWait; + ULONG CopyReadNoWaitMiss; + ULONG CopyReadWaitMiss; + ULONG MdlReadNoWait; + ULONG MdlReadWait; + ULONG MdlReadNoWaitMiss; + ULONG MdlReadWaitMiss; + ULONG ReadAheadIos; + ULONG LazyWriteIos; + ULONG LazyWritePages; + ULONG DataFlushes; + ULONG DataPages; + ULONG ContextSwitches; + ULONG FirstLevelTbFills; + ULONG SecondLevelTbFills; + ULONG SystemCalls; +}; } // namespace @@ -204,4 +289,64 @@ return 0; } +SystemPerformanceInfo::SystemPerformanceInfo() = default; +SystemPerformanceInfo::SystemPerformanceInfo( + const SystemPerformanceInfo& other) = default; + +std::unique_ptr<Value> SystemPerformanceInfo::ToValue() const { + std::unique_ptr<DictionaryValue> result(new DictionaryValue()); + + // Write out uint64_t variables as doubles. + // Note: this may discard some precision, but for JS there's no other option. + result->SetDouble("idle_time", static_cast<double>(idle_time)); + result->SetDouble("read_transfer_count", + static_cast<double>(read_transfer_count)); + result->SetDouble("write_transfer_count", + static_cast<double>(write_transfer_count)); + result->SetDouble("other_transfer_count", + static_cast<double>(other_transfer_count)); + result->SetDouble("read_operation_count", + static_cast<double>(read_operation_count)); + result->SetDouble("write_operation_count", + static_cast<double>(write_operation_count)); + result->SetDouble("other_operation_count", + static_cast<double>(other_operation_count)); + result->SetDouble("pagefile_pages_written", + static_cast<double>(pagefile_pages_written)); + result->SetDouble("pagefile_pages_write_ios", + static_cast<double>(pagefile_pages_write_ios)); + + return result; +} + +// Retrieves performance counters from the operating system. +// Fills in the provided |info| structure. Returns true on success. +BASE_EXPORT bool GetSystemPerformanceInfo(SystemPerformanceInfo* info) { + static const auto query_system_information_ptr = + reinterpret_cast<decltype(&::NtQuerySystemInformation)>(GetProcAddress( + GetModuleHandle(L"ntdll.dll"), "NtQuerySystemInformation")); + if (!query_system_information_ptr) + return false; + + SYSTEM_PERFORMANCE_INFORMATION counters = {}; + const NTSTATUS status = query_system_information_ptr( + ::SystemPerformanceInformation, &counters, + sizeof(SYSTEM_PERFORMANCE_INFORMATION), nullptr); + + if (status != STATUS_SUCCESS) + return false; + + info->idle_time = counters.IdleTime.QuadPart; + info->read_transfer_count = counters.ReadTransferCount.QuadPart; + info->write_transfer_count = counters.WriteTransferCount.QuadPart; + info->other_transfer_count = counters.OtherTransferCount.QuadPart; + info->read_operation_count = counters.ReadOperationCount; + info->write_operation_count = counters.WriteOperationCount; + info->other_operation_count = counters.OtherOperationCount; + info->pagefile_pages_written = counters.PagefilePagesWritten; + info->pagefile_pages_write_ios = counters.PagefilePageWriteIos; + + return true; +} + } // namespace base
diff --git a/build/android/pylib/gtest/gtest_test_instance.py b/build/android/pylib/gtest/gtest_test_instance.py index 7e0923a..cd8ddbc 100644 --- a/build/android/pylib/gtest/gtest_test_instance.py +++ b/build/android/pylib/gtest/gtest_test_instance.py
@@ -533,7 +533,9 @@ disabled_filter_items = [] if disabled_prefixes is None: - disabled_prefixes = ['FAILS_', 'PRE_', 'MANUAL_'] + disabled_prefixes = ['FAILS_', 'PRE_'] + if '--run-manual' not in self._flags: + disabled_prefixes += ['MANUAL_'] if not self._run_disabled: disabled_prefixes += ['DISABLED_', 'FLAKY_']
diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn index c23d332b..d2ee5883 100644 --- a/build/config/compiler/BUILD.gn +++ b/build/config/compiler/BUILD.gn
@@ -381,7 +381,10 @@ "-Wl,-z,now", "-Wl,-z,relro", ] - if (!using_sanitizer) { + + # Compiler instrumentation can introduce dependencies in DSOs to symbols in + # the executable they are loaded into, so they are unresolved at link-time. + if (!using_sanitizer && !is_safestack) { ldflags += [ "-Wl,-z,defs", "-Wl,--as-needed",
diff --git a/build/config/fuchsia/BUILD.gn b/build/config/fuchsia/BUILD.gn index ab88b6ea..b9e1a351 100644 --- a/build/config/fuchsia/BUILD.gn +++ b/build/config/fuchsia/BUILD.gn
@@ -34,11 +34,11 @@ # patches, we might want to make tools/clang/scripts/update.py build it # and bundle it with the clang package instead of using the library from # the SDK, https://crbug.com/724204 - # Note: Intentionally 7.0.0 instead of $clang_version because the clang + # Note: Intentionally 8.0.0 instead of $clang_version because the clang # version of the toolchain_libs directory in the Fuchsia SDK can be # different from the version of Chromium's clang. "-resource-dir", - rebase_path(fuchsia_sdk, root_build_dir) + "/toolchain_libs/clang/7.0.0", + rebase_path(fuchsia_sdk, root_build_dir) + "/toolchain_libs/clang/8.0.0", # The stack defaults to 256k on Fuchsia (see # https://fuchsia.googlesource.com/zircon/+/master/system/private/zircon/stack.h#9),
diff --git a/build/config/sanitizers/BUILD.gn b/build/config/sanitizers/BUILD.gn index dae0d85..2ad0304 100644 --- a/build/config/sanitizers/BUILD.gn +++ b/build/config/sanitizers/BUILD.gn
@@ -197,6 +197,9 @@ if (is_ubsan_vptr) { ldflags += [ "-fsanitize=vptr" ] } + if (is_safestack) { + ldflags += [ "-fsanitize=safe-stack" ] + } if (use_sanitizer_coverage) { if (use_libfuzzer) { @@ -421,6 +424,12 @@ } } +config("safestack_flags") { + if (is_safestack) { + cflags = [ "-fsanitize=safe-stack" ] + } +} + config("tsan_flags") { if (is_tsan) { assert(is_linux, "tsan only supported on linux x86_64") @@ -536,6 +545,7 @@ ":cfi_flags", ":lsan_flags", ":msan_flags", + ":safestack_flags", ":tsan_flags", ":ubsan_flags", ":ubsan_no_recover",
diff --git a/build/config/sanitizers/sanitizers.gni b/build/config/sanitizers/sanitizers.gni index edb0a37..84ce878 100644 --- a/build/config/sanitizers/sanitizers.gni +++ b/build/config/sanitizers/sanitizers.gni
@@ -33,6 +33,9 @@ # Compile for Undefined Behaviour Sanitizer's vptr checks. is_ubsan_vptr = false + # Compile with SafeStack shadow stack support. + is_safestack = false + # Track where uninitialized memory originates from. From fastest to slowest: # 0 - no tracking, 1 - track only the initial allocation site, 2 - track the # chain of stores leading from allocation site to use site. @@ -155,9 +158,9 @@ sanitizer_coverage_flags = "trace-pc-guard,indirect-calls" } -# Whether we are linking against a sanitizer runtime library. Among other -# things, this changes the default symbol level and other settings in order to -# prepare to create stack traces "live" using the sanitizer runtime. +# Whether we are linking against a debugging sanitizer runtime library. Among +# other things, this changes the default symbol level and other settings in +# order to prepare to create stack traces "live" using the sanitizer runtime. using_sanitizer = is_asan || is_lsan || is_tsan || is_msan || is_ubsan || is_ubsan_null || is_ubsan_vptr || is_ubsan_security || use_sanitizer_coverage || use_cfi_diag @@ -168,6 +171,9 @@ assert(!is_cfi || is_clang, "is_cfi requires setting is_clang = true in 'gn args'") +assert(!is_safestack || is_clang, + "is_safestack requires setting is_clang = true in 'gn args'") + prebuilt_instrumented_libraries_available = is_msan && (msan_track_origins == 0 || msan_track_origins == 2)
diff --git a/build/fuchsia/sdk.sha1 b/build/fuchsia/sdk.sha1 index 7c0879fc..413cca9 100644 --- a/build/fuchsia/sdk.sha1 +++ b/build/fuchsia/sdk.sha1
@@ -1 +1 @@ -fcba89bea65da4805154879bf1a01e02e89d1f5f \ No newline at end of file +1aedaa9ac17c5429b5cab2dde8407299ead0ac0d \ No newline at end of file
diff --git a/build/linux/chrome.safestack.map b/build/linux/chrome.safestack.map new file mode 100644 index 0000000..76b9f5b --- /dev/null +++ b/build/linux/chrome.safestack.map
@@ -0,0 +1,93 @@ +# This is a separate SafeStack version script to avoid accidentally exporting +# a pthread_create symbol in the default build +{ +global: + __bss_start; + __data_start; + data_start; + _edata; + _end; + _IO_stdin_used; + + # Initialization and finalization functions for static global + # variables. + _fini; + _init; + __libc_csu_fini; + __libc_csu_init; + + # Chrome's main function. Exported for historical purposes. + ChromeMain; + + # Program entry point. + _start; + + # Memory allocation symbols. We want chrome and any libraries to + # share the same heap, so it is correct to export these symbols. + calloc; + cfree; + free; + __free_hook; + __libc_calloc; + __libc_cfree; + __libc_free; + __libc_malloc; + __libc_memalign; + __libc_pvalloc; + __libc_realloc; + __libc_valloc; + mallinfo; + malloc; + __malloc_hook; + malloc_size; + malloc_stats; + malloc_usable_size; + mallopt; + memalign; + __memalign_hook; + __posix_memalign; + posix_memalign; + pvalloc; + realloc; + __realloc_hook; + valloc; + + # Various flavors of operator new and operator delete. + _ZdaPv; + _ZdaPvm; + _ZdaPvmSt11align_val_t; + _ZdaPvRKSt9nothrow_t; + _ZdaPvSt11align_val_t; + _ZdaPvSt11align_val_tRKSt9nothrow_t; + _ZdlPv; + _ZdlPvm; + _ZdlPvmSt11align_val_t; + _ZdlPvRKSt9nothrow_t; + _ZdlPvSt11align_val_t; + _ZdlPvSt11align_val_tRKSt9nothrow_t; + _Znam; + _ZnamRKSt9nothrow_t; + _ZnamSt11align_val_t; + _ZnamSt11align_val_tRKSt9nothrow_t; + _Znwm; + _ZnwmRKSt9nothrow_t; + _ZnwmSt11align_val_t; + _ZnwmSt11align_val_tRKSt9nothrow_t; + + # Various flavors of localtime(). These are exported by the chrome + # sandbox to intercept calls to localtime(), which would otherwise + # fail in untrusted processes that don't have permission to read + # /etc/localtime. These overrides forward the request to the browser + # process, which uses dlsym(localtime) to make the real calls. + localtime; + localtime64; + localtime64_r; + localtime_r; + + # The SafeStack runtime overrides thread creation routines to allocate shadow + # stacks on thread creation. + pthread_create; + +local: + *; +};
diff --git a/build/linux/unbundle/README b/build/linux/unbundle/README index 6e4f0a95..b6b6321 100644 --- a/build/linux/unbundle/README +++ b/build/linux/unbundle/README
@@ -32,7 +32,7 @@ 1. remove_bundled_libraries.py <preserved-directories> - For example: remove_bundled_libraries.py third_party/mesa + For example: remove_bundled_libraries.py third_party/zlib The script scans sources looking for third_party directories. Everything that is not explicitly preserved is removed (except for
diff --git a/build/util/lastchange.py b/build/util/lastchange.py index 19e3237..18521bc2 100755 --- a/build/util/lastchange.py +++ b/build/util/lastchange.py
@@ -15,9 +15,10 @@ import sys class VersionInfo(object): - def __init__(self, revision_id, full_revision_string): + def __init__(self, revision_id, full_revision_string, timestamp): self.revision_id = revision_id self.revision = full_revision_string + self.timestamp = timestamp def RunGitCommand(directory, command): @@ -58,14 +59,14 @@ A VersionInfo object or None on error. """ hsh = '' - git_args = ['log', '-1', '--format=%H'] + git_args = ['log', '-1', '--format=%H %ct'] if filter is not None: git_args.append('--grep=' + filter) proc = RunGitCommand(directory, git_args) if proc: output = proc.communicate()[0].strip() if proc.returncode == 0 and output: - hsh = output + hsh, ct = output.split() else: logging.error('Git error: rc=%d, output=%r' % (proc.returncode, output)) @@ -80,7 +81,7 @@ if line.startswith('Cr-Commit-Position:'): pos = line.rsplit()[-1].strip() break - return VersionInfo(hsh, '%s-%s' % (hsh, pos)) + return VersionInfo(hsh, '%s-%s' % (hsh, pos), int(ct)) def FetchVersionInfo(directory=None, filter=None): @@ -90,7 +91,7 @@ """ version_info = FetchGitRevision(directory, filter) if not version_info: - version_info = VersionInfo('0', '0') + version_info = VersionInfo('0', '0', 0) return version_info @@ -136,6 +137,7 @@ """ Writes the specified contents to the specified file_name iff the contents are different than the current contents. + Returns if new data was written. """ try: old_contents = open(file_name, 'r').read() @@ -143,9 +145,10 @@ pass else: if contents == old_contents: - return + return False os.unlink(file_name) open(file_name, 'w').write(contents) + return True def main(argv=None): @@ -211,7 +214,9 @@ sys.stdout.write(contents) else: if out_file: - WriteIfChanged(out_file, contents) + if WriteIfChanged(out_file, contents): + with open(out_file + '.committime', 'w') as timefile: + timefile.write(str(version_info.timestamp)) if header: WriteIfChanged(header, GetHeaderContents(header, opts.version_macro,
diff --git a/build/write_build_date_header.py b/build/write_build_date_header.py index 01c9e276..6628d663 100755 --- a/build/write_build_date_header.py +++ b/build/write_build_date_header.py
@@ -7,7 +7,7 @@ build_type impacts the timestamp generated: - default: the build date is set to the most recent first Sunday of a month at 5:00am. The reason is that it is a time where invalidating the build cache - shouldn't have major reprecussions (due to lower load). + shouldn't have major repercussions (due to lower load). - official: the build date is set to the current date at 5:00am, or the day before if the current time is before 5:00am. Either way, it is guaranteed to be in the past and always in UTC. @@ -23,6 +23,9 @@ import sys +THIS_DIR = os.path.abspath(os.path.dirname(__file__)) + + def GetFirstSundayOfMonth(year, month): """Returns the first sunday of the given month of the given year. @@ -80,7 +83,16 @@ 'build_type', help='The type of build', choices=('official', 'default')) args = argument_parser.parse_args() - now = datetime.datetime.utcnow() + # The mtime of the revision in build/util/LASTCHANGE is stored in a file + # next to it. Read it, to get a deterministic time close to "now". + # That date is then modified as described at the top of the file so that + # it changes less frequently than with every commit. + # This intentionally always uses build/util/LASTCHANGE's commit time even if + # use_dummy_lastchange is set. + lastchange_file = os.path.join(THIS_DIR, 'util', 'LASTCHANGE.committime') + last_commit_timestamp = int(open(lastchange_file).read()) + now = datetime.datetime.utcfromtimestamp(last_commit_timestamp) + if now.hour < 5: # The time is locked at 5:00 am in UTC to cause the build cache # invalidation to not happen exactly at midnight. Use the same calculation
diff --git a/cc/layers/layer_impl.h b/cc/layers/layer_impl.h index 8a2f9a6..98a0aa1 100644 --- a/cc/layers/layer_impl.h +++ b/cc/layers/layer_impl.h
@@ -273,6 +273,8 @@ // Viewport bounds delta are only used for viewport layers and account for // changes in the viewport layers from browser controls and page scale // factors. These deltas are only set on the active tree. + // TODO(bokan): These methods should be unneeded now that LTHI sets these + // directly on the property trees. void SetViewportBoundsDelta(const gfx::Vector2dF& bounds_delta); gfx::Vector2dF ViewportBoundsDelta() const; @@ -530,6 +532,8 @@ bool hit_testable_without_draws_content_ : 1; bool is_resized_by_browser_controls_ : 1; + // TODO(bokan): This can likely be removed after blink-gen-property-trees + // is shipped. https://crbug.com/836884. static_assert(LAST_VIEWPORT_LAYER_TYPE < (1u << 3), "enough bits for ViewportLayerType (viewport_layer_type_)"); uint8_t viewport_layer_type_ : 3; // ViewportLayerType
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc index 365c67a..74e3caa 100644 --- a/cc/trees/layer_tree_host_impl.cc +++ b/cc/trees/layer_tree_host_impl.cc
@@ -65,6 +65,7 @@ #include "cc/tiles/picture_layer_tiling.h" #include "cc/tiles/raster_tile_priority_queue.h" #include "cc/tiles/software_image_decode_cache.h" +#include "cc/trees/clip_node.h" #include "cc/trees/damage_tracker.h" #include "cc/trees/debug_rect_history.h" #include "cc/trees/draw_property_utils.h" @@ -2449,17 +2450,9 @@ } void LayerTreeHostImpl::UpdateViewportContainerSizes() { - // TODO(bokan): Make URL-bar bounds deltas work with Blink-generated property - // trees. https://crbug.com/850135. if (!InnerViewportScrollNode()) return; - LayerImpl* inner_container = active_tree_->InnerViewportContainerLayer(); - LayerImpl* outer_container = active_tree_->OuterViewportContainerLayer(); - - if (!inner_container) - return; - ViewportAnchor anchor(InnerViewportScrollNode(), OuterViewportScrollLayer(), active_tree_.get()); @@ -2481,20 +2474,57 @@ // Adjust the viewport layers by shrinking/expanding the container to account // for changes in the size (e.g. browser controls) since the last resize from // Blink. - gfx::Vector2dF amount_to_expand(0.f, delta_from_top_controls); - inner_container->SetViewportBoundsDelta(amount_to_expand); + auto* property_trees = active_tree_->property_trees(); + gfx::Vector2dF inner_bounds_delta(0.f, delta_from_top_controls); + if (property_trees->inner_viewport_container_bounds_delta() == + inner_bounds_delta) + return; - if (outer_container && !outer_container->BoundsForScrolling().IsEmpty()) { - // Adjust the outer viewport container as well, since adjusting only the - // inner may cause its bounds to exceed those of the outer, causing scroll - // clamping. - gfx::Vector2dF amount_to_expand_scaled = gfx::ScaleVector2d( - amount_to_expand, 1.f / active_tree_->min_page_scale_factor()); - outer_container->SetViewportBoundsDelta(amount_to_expand_scaled); - InnerViewportScrollLayer()->SetViewportBoundsDelta(amount_to_expand_scaled); + property_trees->SetInnerViewportContainerBoundsDelta(inner_bounds_delta); + ClipNode* inner_clip_node = property_trees->clip_tree.Node( + InnerViewportScrollLayer()->clip_tree_index()); + inner_clip_node->clip.set_height( + InnerViewportScrollNode()->container_bounds.height() + + inner_bounds_delta.y()); + + // Adjust the outer viewport container as well, since adjusting only the + // inner may cause its bounds to exceed those of the outer, causing scroll + // clamping. + if (OuterViewportScrollNode()) { + gfx::Vector2dF outer_bounds_delta = gfx::ScaleVector2d( + inner_bounds_delta, 1.f / active_tree_->min_page_scale_factor()); + + property_trees->SetOuterViewportContainerBoundsDelta(outer_bounds_delta); + property_trees->SetInnerViewportScrollBoundsDelta(outer_bounds_delta); + + ClipNode* outer_clip_node = property_trees->clip_tree.Node( + OuterViewportScrollLayer()->clip_tree_index()); + outer_clip_node->clip.set_height( + OuterViewportScrollNode()->container_bounds.height() + + outer_bounds_delta.y()); anchor.ResetViewportToAnchoredPosition(); } + + property_trees->clip_tree.set_needs_update(true); + property_trees->full_tree_damaged = true; + active_tree_->set_needs_update_draw_properties(); + + // Viewport scrollbar positions are determined using the viewport bounds + // delta. + active_tree_->SetScrollbarGeometriesNeedUpdate(); + active_tree_->set_needs_update_draw_properties(); + + // For pre-BlinkGenPropertyTrees mode, we need to ensure the layers are + // appropriately updated. + if (!settings().use_layer_lists) { + if (OuterViewportContainerLayer()) + OuterViewportContainerLayer()->NoteLayerPropertyChanged(); + if (InnerViewportScrollLayer()) + InnerViewportScrollLayer()->NoteLayerPropertyChanged(); + if (OuterViewportScrollLayer()) + OuterViewportScrollLayer()->NoteLayerPropertyChanged(); + } } void LayerTreeHostImpl::SynchronouslyInitializeAllTiles() { @@ -2778,6 +2808,16 @@ } UpdateViewportContainerSizes(); + + if (InnerViewportScrollNode()) { + active_tree_->property_trees()->scroll_tree.ClampScrollToMaxScrollOffset( + InnerViewportScrollNode(), active_tree_.get()); + } + if (OuterViewportScrollNode()) { + active_tree_->property_trees()->scroll_tree.ClampScrollToMaxScrollOffset( + OuterViewportScrollNode(), active_tree_.get()); + } + active_tree_->DidBecomeActive(); client_->RenewTreePriority();
diff --git a/chrome/BUILD.gn b/chrome/BUILD.gn index 7f95c59f..358538d8 100644 --- a/chrome/BUILD.gn +++ b/chrome/BUILD.gn
@@ -279,7 +279,11 @@ } if (is_desktop_linux && !is_component_build && !using_sanitizer) { - version_script = "//build/linux/chrome.map" + if (is_safestack) { + version_script = "//build/linux/chrome.safestack.map" + } else { + version_script = "//build/linux/chrome.map" + } inputs = [ version_script, ]
diff --git a/chrome/android/java/res/layout/modal_dialog_view.xml b/chrome/android/java/res/layout/modal_dialog_view.xml index 00d6382b..cf2ccbde 100644 --- a/chrome/android/java/res/layout/modal_dialog_view.xml +++ b/chrome/android/java/res/layout/modal_dialog_view.xml
@@ -58,13 +58,13 @@ android:layout_height="wrap_content" style="?attr/buttonBarStyle"> - <Button + <android.support.v7.widget.AppCompatButton android:id="@+id/negative_button" android:layout_width="wrap_content" android:layout_height="wrap_content" style="?attr/buttonBarNegativeButtonStyle" /> - <Button + <android.support.v7.widget.AppCompatButton android:id="@+id/positive_button" android:layout_width="wrap_content" android:layout_height="wrap_content"
diff --git a/chrome/android/java/res/values-v17/styles.xml b/chrome/android/java/res/values-v17/styles.xml index ac929a2..9dd564f 100644 --- a/chrome/android/java/res/values-v17/styles.xml +++ b/chrome/android/java/res/values-v17/styles.xml
@@ -138,13 +138,8 @@ <item name="android:paddingBottom">@dimen/modal_dialog_control_padding_vertical</item> </style> - <!-- TODO(huayinz): Move this to pre-defined style once we have the disabled state defined --> - <style name="TextAppearance.ModalDialogButton" parent="BlueButtonText2"> - <item name="android:textColor">@color/blue_when_enabled</item> - </style> - <style name="ModalDialogButtonStyle" parent="Widget.AppCompat.Button.ButtonBar.AlertDialog"> - <item name="android:textAppearance">@style/TextAppearance.ModalDialogButton</item> + <item name="android:textAppearance">@style/BlueButtonText2</item> </style> <style name="SimpleDialog" parent="AlertDialogTheme">
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/FetchHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/FetchHelper.java index 7231d74c..6bb83c1 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/FetchHelper.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/FetchHelper.java
@@ -296,46 +296,11 @@ private void maybeStartFetch(final Tab tab) { if (tab == null || tab != mCurrentTab) return; + assert !tab.isIncognito(); + // Skip additional requests for current tab, until clearState is called. if (mFetchRequestedForCurrentTab) return; - if (shouldFetchCanonicalUrl(tab)) { - mFetchRequestedForCurrentTab = true; - String url = tab.getUrl(); - tab.getWebContents().getMainFrame().getCanonicalUrlForSharing(new Callback<String>() { - @Override - public void onResult(String result) { - if (tab != mCurrentTab) { - return; - } - - // Reset mFetchRequestedForCurrentTab so that it remains false if - // maybeStartFetchWithCanonicalURLResolved doesn't end up requesting - // suggestions. If it does end up requesting suggestions, - // mFetchRequestedForCurrentTab will be set back to true in the same - // synchronous flow of execution, so there shouldn't be a race condition. - mFetchRequestedForCurrentTab = false; - - TabFetchReadinessState tabFetchReadinessState = getTabFetchReadinessState(tab); - if (tabFetchReadinessState != null && tabFetchReadinessState.isTrackingPage() - && tabFetchReadinessState.isContextTheSame(url)) { - tabFetchReadinessState.setCanonicalUrl(result); - maybeStartFetchWithCanonicalURLResolved( - tab, getUrlToFetchFor(tab.getUrl(), result)); - } - } - }); - return; - } else { - maybeStartFetchWithCanonicalURLResolved(tab, tab.getUrl()); - } - } - - private void maybeStartFetchWithCanonicalURLResolved(Tab tab, String resolvedUrl) { - if (tab == null || tab != mCurrentTab) return; - - assert !tab.isIncognito(); - TabFetchReadinessState tabFetchReadinessState = getTabFetchReadinessState(mCurrentTab); // If we are not tracking a valid page, we can bail. @@ -354,43 +319,54 @@ return; } - long remainingFetchDelayMillis = + long currentDelayMillis = SystemClock.uptimeMillis() - tabFetchReadinessState.getFetchTimeBaselineMillis(); - long minimumFetchDelayMillis = getMinimumFetchDelayMillis(); - if (!sDisableDelayForTesting && remainingFetchDelayMillis < minimumFetchDelayMillis) { - postDelayedFetch( - resolvedUrl, mCurrentTab, minimumFetchDelayMillis - remainingFetchDelayMillis); - return; - } + long delayMillis = Math.max(0, getMinimumFetchDelayMillis() - currentDelayMillis); + final String url = tabFetchReadinessState.getUrl(); - mFetchRequestedForCurrentTab = true; - mDelegate.requestSuggestions(resolvedUrl); - } - - private void postDelayedFetch(final String url, final Tab tab, long delayMillis) { - if (tab == null) { - assert false; + if (sDisableDelayForTesting || delayMillis == 0) { + getCanonicalUrlThenFetch(tab, url); return; } mDelegate.reportFetchDelayed(tab.getWebContents()); - ThreadUtils.postOnUiThreadDelayed(new Runnable() { + ThreadUtils.postOnUiThreadDelayed(() -> getCanonicalUrlThenFetch(tab, url), delayMillis); + } + + private void getCanonicalUrlThenFetch(final Tab tab, final String url) { + if (!shouldFetchCanonicalUrl(tab)) { + fetchSuggestions(tab, url); + return; + } + + tab.getWebContents().getMainFrame().getCanonicalUrlForSharing(new Callback<String>() { @Override - public void run() { - // Make sure that the tab is currently selected. + public void onResult(String result) { if (tab != mCurrentTab) return; - if (mFetchRequestedForCurrentTab) return; - - if (!isObservingTab(tab)) return; - - // URL in tab changed since the task was originally posted. - if (!getTabFetchReadinessState(tab).isContextTheSame(url)) return; - - mFetchRequestedForCurrentTab = true; - mDelegate.requestSuggestions(url); + TabFetchReadinessState tabFetchReadinessState = getTabFetchReadinessState(tab); + if (tabFetchReadinessState != null && tabFetchReadinessState.isTrackingPage() + && tabFetchReadinessState.isContextTheSame(url)) { + tabFetchReadinessState.setCanonicalUrl(result); + fetchSuggestions(tab, getUrlToFetchFor(tab.getUrl(), result)); + } } - }, delayMillis); + }); + } + + private void fetchSuggestions(final Tab tab, final String url) { + // Make sure that the tab is currently selected. + if (tab != mCurrentTab) return; + + if (mFetchRequestedForCurrentTab) return; + + if (!isObservingTab(tab)) return; + + // URL in tab changed since the task was originally posted. + if (!getTabFetchReadinessState(tab).isContextTheSame(url)) return; + + mFetchRequestedForCurrentTab = true; + mDelegate.requestSuggestions(url); } private void clearState() {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/ToolbarProgressBar.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/ToolbarProgressBar.java index 7d727ef..9b4ba308 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/widget/ToolbarProgressBar.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/ToolbarProgressBar.java
@@ -262,6 +262,13 @@ public void onDetachedFromWindow() { super.onDetachedFromWindow(); mIsAttachedToWindow = false; + + if (mProgressThrottle != null) { + mProgressThrottle.setTimeListener(null); + mProgressThrottle.cancel(); + } + mSmoothProgressAnimator.setTimeListener(null); + mSmoothProgressAnimator.cancel(); } /**
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/vr/VrBrowserNativeUiTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/vr/VrBrowserNativeUiTest.java index 1f7ea95..551410cb 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/vr/VrBrowserNativeUiTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/vr/VrBrowserNativeUiTest.java
@@ -9,6 +9,8 @@ import static org.chromium.chrome.browser.vr.XrTestFramework.POLL_TIMEOUT_LONG_MS; import static org.chromium.chrome.test.util.ChromeRestriction.RESTRICTION_TYPE_VIEWER_DAYDREAM; +import android.os.SystemClock; +import android.support.test.InstrumentationRegistry; import android.support.test.filters.MediumTest; import org.junit.Assert; @@ -20,11 +22,16 @@ import org.chromium.base.test.util.CommandLineFlags; import org.chromium.base.test.util.Restriction; import org.chromium.chrome.browser.ChromeSwitches; +import org.chromium.chrome.browser.payments.ui.PaymentRequestUI; +import org.chromium.chrome.browser.payments.ui.PaymentRequestUI.PaymentRequestObserverForTest; import org.chromium.chrome.browser.vr.rules.ChromeTabbedActivityVrTestRule; import org.chromium.chrome.browser.vr.util.VrBrowserTransitionUtils; +import org.chromium.chrome.browser.vr.util.VrShellDelegateUtils; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; +import org.chromium.net.test.EmbeddedTestServer; import java.util.concurrent.TimeoutException; +import java.util.concurrent.atomic.AtomicBoolean; /** * End-to-end tests for native UI presentation in VR Browser mode. @@ -38,11 +45,14 @@ @Rule public ChromeTabbedActivityVrTestRule mVrTestRule = new ChromeTabbedActivityVrTestRule(); + private VrBrowserTestFramework mVrBrowserTestFramework; + private static final String TEST_PAGE_2D_URL = VrBrowserTestFramework.getFileUrlForHtmlTestFile("test_navigation_2d_page"); @Before public void setUp() throws Exception { + mVrBrowserTestFramework = new VrBrowserTestFramework(mVrTestRule); VrBrowserTransitionUtils.forceEnterVrBrowserOrFail(POLL_TIMEOUT_LONG_MS); } @@ -71,4 +81,46 @@ Assert.assertTrue("URL is not being show for non-native page", TestVrShellDelegate.isDisplayingUrlForTesting()); } + + /** + * Tests that the Payment Request API is supressed in the VR Browser and its native UI does not + * show. Automation of a manual test from https://crbug.com/862162. + */ + @Test + @MediumTest + public void testPaymentRequest() throws InterruptedException { + // We can't request payment on file:// URLs, so use a local server. + EmbeddedTestServer server = + EmbeddedTestServer.createAndStartServer(InstrumentationRegistry.getContext()); + mVrBrowserTestFramework.loadUrlAndAwaitInitialization( + server.getURL(VrBrowserTestFramework.getEmbeddedServerPathForHtmlTestFile( + "test_payment_request")), + PAGE_LOAD_TIMEOUT_S); + // Set up an observer so we'll know if the payment request is shown. + AtomicBoolean requestShown = new AtomicBoolean(false); + PaymentRequestObserverForTest observer = new PaymentRequestObserverForTest() { + @Override + public void onPaymentRequestReadyForInput(PaymentRequestUI ui) { + requestShown.set(true); + } + @Override + public void onPaymentRequestReadyToPay(PaymentRequestUI ui) {} + @Override + public void onPaymentRequestSelectionChecked(PaymentRequestUI ui) {} + @Override + public void onPaymentRequestResultReady(PaymentRequestUI ui) {} + }; + PaymentRequestUI.setPaymentRequestObserverForTest(observer); + // Request payment and wait for the promise to auto-reject. + mVrBrowserTestFramework.executeStepAndWait("stepRequestPayment()"); + // Ensure that the native UI wasn't shown even though the request was rejected. + // Need to sleep for a bit in order to allow the UI to show if it's going to. + SystemClock.sleep(1000); + Assert.assertFalse("Native Payment Request UI was shown", requestShown.get()); + // Ensure we weren't somehow kicked out of VR from this. + Assert.assertTrue("Payment request caused VR exit", + VrShellDelegateUtils.getDelegateInstance().isVrEntryComplete()); + mVrBrowserTestFramework.endTest(); + server.stopAndDestroyServer(); + } }
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/contextual_suggestions/FetchHelperTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/contextual_suggestions/FetchHelperTest.java index 542e4ff..87e7bc29 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/contextual_suggestions/FetchHelperTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/contextual_suggestions/FetchHelperTest.java
@@ -426,7 +426,9 @@ FetchHelper helper = createFetchHelper(); getTabObserver().onPageLoadFinished(mTab); + verify(mFrameHost, times(0)).getCanonicalUrlForSharing(any()); runUntilFetchPossible(); + verify(mFrameHost, times(1)).getCanonicalUrlForSharing(any()); verify(mDelegate, times(1)).requestSuggestions(DIFFERENT_URL); }
diff --git a/chrome/android/profiles/newest.txt b/chrome/android/profiles/newest.txt index c689c953..add49b1 100644 --- a/chrome/android/profiles/newest.txt +++ b/chrome/android/profiles/newest.txt
@@ -1 +1 @@ -chromeos-chrome-amd64-70.0.3522.0_rc-r1.afdo.bz2 \ No newline at end of file +chromeos-chrome-amd64-70.0.3523.0_rc-r1.afdo.bz2 \ No newline at end of file
diff --git a/chrome/app/chromeos_strings.grdp b/chrome/app/chromeos_strings.grdp index 3535685..60c7e3c 100644 --- a/chrome/app/chromeos_strings.grdp +++ b/chrome/app/chromeos_strings.grdp
@@ -3766,6 +3766,14 @@ Don't remind me again </message> + <!-- TPM Firmware Update Notification Strings --> + <message name="IDS_TPM_FIRMWARE_UPDATE_NOTIFICATION_TITLE" desc="Notification title shown to inform the user that there is a pending TPM firmware update for the device."> + Security upgrade available + </message> + <message name="IDS_TPM_FIRMWARE_UPDATE_NOTIFICATION_MESSAGE" desc="Notification shown to inform the user that there is a pending TPM firmware update for the device."> + Reset your <ph name="DEVICE_TYPE">$1<ex>Chromebook</ex></ph> to upgrade your security. + </message> + <!-- Obsolete versions Notification strings--> <message name="IDS_UPDATE_REQUIRED_LOGIN_SCREEN_MESSAGE" desc="The message on login screen to inform the user that policy prevents user sign in before OS version is is updated."> Your device is no longer compliant with the minimum client version specified by your admin. Please update to login.
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index 99f35ba..3c2358ce 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -758,6 +758,8 @@ "metrics/oom/out_of_memory_reporter.h", "metrics/perf/perf_provider_chromeos.cc", "metrics/perf/perf_provider_chromeos.h", + "metrics/power_metrics_provider_mac.h", + "metrics/power_metrics_provider_mac.mm", "metrics/process_memory_metrics_emitter.cc", "metrics/process_memory_metrics_emitter.h", "metrics/renderer_uptime_tracker.cc", @@ -1195,8 +1197,6 @@ "prerender/prerender_util.h", "previews/previews_infobar_delegate.cc", "previews/previews_infobar_delegate.h", - "previews/previews_infobar_tab_helper.cc", - "previews/previews_infobar_tab_helper.h", "previews/previews_lite_page_decider.cc", "previews/previews_lite_page_decider.h", "previews/previews_lite_page_navigation_throttle.cc", @@ -1206,6 +1206,8 @@ "previews/previews_service.h", "previews/previews_service_factory.cc", "previews/previews_service_factory.h", + "previews/previews_ui_tab_helper.cc", + "previews/previews_ui_tab_helper.h", "previews/resource_loading_hints/resource_loading_hints_web_contents_observer.cc", "previews/resource_loading_hints/resource_loading_hints_web_contents_observer.h", "process_resource_usage.cc",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index 9fbfd1f9..75d6bb7 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -3877,6 +3877,13 @@ FEATURE_VALUE_TYPE(ash::features::kNewWallpaperPicker)}, #endif // OS_CHROMEOS +#if defined(OS_CHROMEOS) + {"enable-oobe-recommend-apps-screen", + flag_descriptions::kEnableOobeRecommendAppsScreenName, + flag_descriptions::kEnableOobeRecommendAppsScreenDescription, kOsCrOS, + FEATURE_VALUE_TYPE(features::kOobeRecommendAppsScreen)}, +#endif // OS_CHROMEOS + #if defined(OS_ANDROID) {"enable-query-in-omnibox", flag_descriptions::kQueryInOmniboxName, flag_descriptions::kQueryInOmniboxDescription, kOsAndroid, @@ -4016,6 +4023,10 @@ flag_descriptions::kAutofillCacheQueryResponsesName, flag_descriptions::kAutofillCacheQueryResponsesDescription, kOsAll, FEATURE_VALUE_TYPE(autofill::features::kAutofillCacheQueryResponses)}, + {"autofill-enable-company-name", + flag_descriptions::kAutofillEnableCompanyNameName, + flag_descriptions::kAutofillEnableCompanyNameDescription, kOsAll, + FEATURE_VALUE_TYPE(autofill::features::kAutofillEnableCompanyName)}, {"autofill-enforce-min-required-fields-for-heuristics", flag_descriptions::kAutofillEnforceMinRequiredFieldsForHeuristicsName, flag_descriptions::
diff --git a/chrome/browser/android/vr/arcore_device/arcore_device.cc b/chrome/browser/android/vr/arcore_device/arcore_device.cc index 46e5139..5314478 100644 --- a/chrome/browser/android/vr/arcore_device/arcore_device.cc +++ b/chrome/browser/android/vr/arcore_device/arcore_device.cc
@@ -441,8 +441,6 @@ &ARCoreGl::Resume, arcore_gl_thread_->GetARCoreGl()->GetWeakPtr())); } - auto session = mojom::XRSession::New(); - mojom::XRFrameDataProviderPtr data_provider; mojom::XREnviromentIntegrationProviderPtr enviroment_provider; mojom::XRSessionControllerPtr controller; @@ -450,8 +448,10 @@ this, mojo::MakeRequest(&data_provider), mojo::MakeRequest(&enviroment_provider), mojo::MakeRequest(&controller))); + auto session = mojom::XRSession::New(); session->data_provider = data_provider.PassInterface(); session->enviroment_provider = enviroment_provider.PassInterface(); + session->display_info = display_info_.Clone(); std::move(callback).Run(std::move(session), std::move(controller)); }
diff --git a/chrome/browser/android/vr/vr_gl_thread.cc b/chrome/browser/android/vr/vr_gl_thread.cc index 83e45081..84c252b 100644 --- a/chrome/browser/android/vr/vr_gl_thread.cc +++ b/chrome/browser/android/vr/vr_gl_thread.cc
@@ -88,10 +88,9 @@ weak_browser_ui_ = vr_shell_gl_->GetBrowserUiWeakPtr(); task_runner()->PostTask( - FROM_HERE, - base::BindOnce(&VrShellGl::Initialize, vr_shell_gl_->GetWeakPtr(), - base::Unretained(gl_surface_created_event_), - base::Passed(std::move(surface_callback_)))); + FROM_HERE, base::BindOnce(&VrShellGl::Init, vr_shell_gl_->GetWeakPtr(), + base::Unretained(gl_surface_created_event_), + base::Passed(std::move(surface_callback_)))); } void VrGLThread::CleanUp() {
diff --git a/chrome/browser/android/vr/vr_shell_gl.cc b/chrome/browser/android/vr/vr_shell_gl.cc index a567065..43de3cd 100644 --- a/chrome/browser/android/vr/vr_shell_gl.cc +++ b/chrome/browser/android/vr/vr_shell_gl.cc
@@ -30,7 +30,6 @@ #include "chrome/browser/android/vr/vr_shell.h" #include "chrome/browser/vr/assets_loader.h" #include "chrome/browser/vr/gl_texture_location.h" -#include "chrome/browser/vr/graphics_delegate.h" #include "chrome/browser/vr/metrics/session_metrics_helper.h" #include "chrome/browser/vr/model/assets.h" #include "chrome/browser/vr/model/camera_model.h" @@ -193,7 +192,7 @@ bool start_in_web_vr_mode, bool pause_content, bool low_density) - : RenderLoop(std::move(ui), browser, kWebVRSlidingAverageSize), + : RenderLoop(std::move(ui), browser, this, kWebVRSlidingAverageSize), webvr_vsync_align_( base::FeatureList::IsEnabled(features::kWebVrVsyncAlign)), low_density_(low_density), @@ -223,9 +222,8 @@ webxr_.EndPresentation(); } -void VrShellGl::Initialize( - base::WaitableEvent* gl_surface_created_event, - base::OnceCallback<gfx::AcceleratedWidget()> callback) { +void VrShellGl::Init(base::WaitableEvent* gl_surface_created_event, + base::OnceCallback<gfx::AcceleratedWidget()> callback) { if (surfaceless_rendering_) { InitializeGl(nullptr); } else { @@ -254,9 +252,7 @@ return; } - graphics_delegate_ = std::make_unique<GraphicsDelegate>(surface_); - - if (!graphics_delegate_->Initialize()) { + if (!BaseCompositorDelegate::Initialize(surface_)) { ForceExitVr(); return; } @@ -479,7 +475,7 @@ bool VrShellGl::IsSubmitFrameExpected(int16_t frame_index) { // submit_client_ could be null when we exit presentation, if there were - // pending SubmitFrame messages queued. VRDisplayClient::OnExitPresent + // pending SubmitFrame messages queued. XRSessionClient::OnExitPresent // will clean up state in blink, so it doesn't wait for // OnSubmitFrameTransferred or OnSubmitFrameRendered. Similarly, // the animating frame state is cleared when exiting presentation, @@ -684,6 +680,7 @@ auto session = device::mojom::XRSession::New(); session->data_provider = frame_data_provider.PassInterface(); session->submit_frame_sink = std::move(submit_frame_sink); + session->display_info = std::move(display_info); browser_->SendRequestPresentReply(std::move(session)); } @@ -1228,7 +1225,6 @@ void VrShellGl::DrawIntoAcquiredFrame(int16_t frame_index, base::TimeTicks current_time) { TRACE_EVENT1("gpu", "VrShellGl::DrawIntoAcquiredFrame", "frame", frame_index); - last_used_head_pose_ = render_info_.head_pose; bool is_webxr_frame = frame_index >= 0; DCHECK(!is_webxr_frame || webxr_.HaveProcessingFrame());
diff --git a/chrome/browser/android/vr/vr_shell_gl.h b/chrome/browser/android/vr/vr_shell_gl.h index 8dedd921..2637a228 100644 --- a/chrome/browser/android/vr/vr_shell_gl.h +++ b/chrome/browser/android/vr/vr_shell_gl.h
@@ -17,8 +17,8 @@ #include "base/memory/weak_ptr.h" #include "base/single_thread_task_runner.h" #include "chrome/browser/android/vr/android_vsync_helper.h" -#include "chrome/browser/android/vr/vr_controller.h" #include "chrome/browser/android/vr/web_xr_presentation_state.h" +#include "chrome/browser/vr/base_compositor_delegate.h" #include "chrome/browser/vr/fps_meter.h" #include "chrome/browser/vr/model/controller_model.h" #include "chrome/browser/vr/render_info.h" @@ -97,6 +97,7 @@ // This class manages all GLThread owned objects and GL rendering for VrShell. // It is not threadsafe and must only be used on the GL thread. class VrShellGl : public RenderLoop, + public BaseCompositorDelegate, public device::mojom::XRPresentationProvider, public device::mojom::XRFrameDataProvider { public: @@ -110,8 +111,8 @@ bool low_density); ~VrShellGl() override; - void Initialize(base::WaitableEvent* gl_surface_created_event, - base::OnceCallback<gfx::AcceleratedWidget()> callback); + void Init(base::WaitableEvent* gl_surface_created_event, + base::OnceCallback<gfx::AcceleratedWidget()> callback); void OnTriggerEvent(bool pressed); void OnExitPresent(); @@ -400,8 +401,6 @@ std::vector<gvr::BufferSpec> specs_; - gfx::Transform last_used_head_pose_; - ControllerModel controller_model_; std::unique_ptr<PlatformUiInputDelegate> vr_dialog_input_delegate_;
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn index a147b32..3d75b7d 100644 --- a/chrome/browser/chromeos/BUILD.gn +++ b/chrome/browser/chromeos/BUILD.gn
@@ -1745,6 +1745,8 @@ "tether/tether_service_factory.h", "tpm_firmware_update.cc", "tpm_firmware_update.h", + "tpm_firmware_update_notification.cc", + "tpm_firmware_update_notification.h", "ui/echo_dialog_listener.h", "ui/echo_dialog_view.cc", "ui/echo_dialog_view.h",
diff --git a/chrome/browser/chromeos/DEPS b/chrome/browser/chromeos/DEPS index 3375767b44..8641d15 100644 --- a/chrome/browser/chromeos/DEPS +++ b/chrome/browser/chromeos/DEPS
@@ -2,7 +2,7 @@ # TODO(ananta): Remove this when we move files which display UI in # chrome/browser/chromeos to chrome/browser/ui/views/chromeos # crbug.com/728877 - "+chrome/browser/ui/views/harmony/chrome_layout_provider.h", + "+chrome/browser/ui/views/chrome_layout_provider.h", "+components/constrained_window", "+components/drive/drive_pref_names.h",
diff --git a/chrome/browser/chromeos/app_mode/arc/arc_kiosk_app_manager.cc b/chrome/browser/chromeos/app_mode/arc/arc_kiosk_app_manager.cc index 6d5c9d2c..4670cbcd 100644 --- a/chrome/browser/chromeos/app_mode/arc/arc_kiosk_app_manager.cc +++ b/chrome/browser/chromeos/app_mode/arc/arc_kiosk_app_manager.cc
@@ -18,6 +18,8 @@ #include "chrome/browser/ui/app_list/arc/arc_app_list_prefs.h" #include "chromeos/cryptohome/async_method_caller.h" #include "chromeos/cryptohome/cryptohome_parameters.h" +#include "chromeos/cryptohome/cryptohome_util.h" +#include "chromeos/dbus/cryptohome/rpc.pb.h" #include "chromeos/dbus/cryptohome_client.h" #include "chromeos/dbus/dbus_thread_manager.h" #include "chromeos/settings/cros_settings_names.h" @@ -27,6 +29,7 @@ #include "components/prefs/scoped_user_pref_update.h" #include "components/user_manager/user.h" #include "components/user_manager/user_manager.h" +#include "third_party/cros_system_api/dbus/cryptohome/dbus-constants.h" #include "third_party/cros_system_api/dbus/service_constants.h" namespace chromeos { @@ -52,19 +55,19 @@ local_state->CommitPendingWrite(); } -void OnRemoveAppCryptohomeComplete(const cryptohome::Identification& id, - const base::Closure& callback, - bool success, - cryptohome::MountError return_code) { - if (success) { +void OnRemoveAppCryptohomeComplete( + const cryptohome::Identification& id, + base::OnceClosure callback, + base::Optional<cryptohome::BaseReply> reply) { + cryptohome::MountError error = BaseReplyToMountError(reply); + if (error == cryptohome::MOUNT_ERROR_NONE) { CancelDelayedCryptohomeRemoval(id); } else { ScheduleDelayedCryptohomeRemoval(id); - LOG(ERROR) << "Remove one of the cryptohomes failed, return code: " - << return_code; + LOG(ERROR) << "Remove app cryptohome failed, error: " << error; } if (!callback.is_null()) - callback.Run(); + std::move(callback).Run(); } void PerformDelayedCryptohomeRemovals(bool service_is_available) { @@ -85,9 +88,13 @@ } const cryptohome::Identification cryptohome_id( cryptohome::Identification::FromString(entry)); - cryptohome::AsyncMethodCaller::GetInstance()->AsyncRemove( - cryptohome_id, base::Bind(&OnRemoveAppCryptohomeComplete, cryptohome_id, - base::Closure())); + + cryptohome::AccountIdentifier account_id_proto; + account_id_proto.set_account_id(cryptohome_id.id()); + + DBusThreadManager::Get()->GetCryptohomeClient()->RemoveEx( + account_id_proto, base::BindOnce(&OnRemoveAppCryptohomeComplete, + cryptohome_id, base::OnceClosure())); } } @@ -292,9 +299,12 @@ // Schedule cryptohome removal after active user logout. ScheduleDelayedCryptohomeRemoval(cryptohome_id); } else { - cryptohome::AsyncMethodCaller::GetInstance()->AsyncRemove( - cryptohome_id, base::Bind(&OnRemoveAppCryptohomeComplete, - cryptohome_id, base::Closure())); + cryptohome::AccountIdentifier account_id_proto; + account_id_proto.set_account_id(cryptohome_id.id()); + + DBusThreadManager::Get()->GetCryptohomeClient()->RemoveEx( + account_id_proto, base::BindOnce(&OnRemoveAppCryptohomeComplete, + cryptohome_id, base::OnceClosure())); } }
diff --git a/chrome/browser/chromeos/app_mode/kiosk_app_manager.cc b/chrome/browser/chromeos/app_mode/kiosk_app_manager.cc index 78f4eb8..b0faf95 100644 --- a/chrome/browser/chromeos/app_mode/kiosk_app_manager.cc +++ b/chrome/browser/chromeos/app_mode/kiosk_app_manager.cc
@@ -43,6 +43,8 @@ #include "chromeos/chromeos_switches.h" #include "chromeos/cryptohome/async_method_caller.h" #include "chromeos/cryptohome/cryptohome_parameters.h" +#include "chromeos/cryptohome/cryptohome_util.h" +#include "chromeos/dbus/cryptohome/rpc.pb.h" #include "chromeos/dbus/dbus_thread_manager.h" #include "chromeos/settings/cros_settings_names.h" #include "components/account_id/account_id.h" @@ -100,20 +102,21 @@ local_state->CommitPendingWrite(); } -void OnRemoveAppCryptohomeComplete(const cryptohome::Identification& id, - const std::string& app, - const base::Closure& callback, - bool success, - cryptohome::MountError return_code) { - if (success) { +void OnRemoveAppCryptohomeComplete( + const cryptohome::Identification& id, + const std::string& app, + base::OnceClosure callback, + base::Optional<cryptohome::BaseReply> reply) { + cryptohome::MountError error = BaseReplyToMountError(reply); + if (error == cryptohome::MOUNT_ERROR_NONE) { CancelDelayedCryptohomeRemoval(id); } else { ScheduleDelayedCryptohomeRemoval(id, app); - LOG(ERROR) << "Remove cryptohome for " << app - << " failed, return code: " << return_code; + LOG(ERROR) << "Remove cryptohome for " << app << " failed, return code: " + << cryptohome::BaseReplyToMountError(reply.value()); } - if (!callback.is_null()) - callback.Run(); + if (callback) + std::move(callback).Run(); } void PerformDelayedCryptohomeRemovals(bool service_is_available) { @@ -131,9 +134,14 @@ std::string app_id; it.value().GetAsString(&app_id); VLOG(1) << "Removing obsolete crypthome for " << app_id; - cryptohome::AsyncMethodCaller::GetInstance()->AsyncRemove( - cryptohome_id, base::Bind(&OnRemoveAppCryptohomeComplete, cryptohome_id, - app_id, base::Closure())); + + cryptohome::AccountIdentifier account_id_proto; + account_id_proto.set_account_id(cryptohome_id.id()); + + DBusThreadManager::Get()->GetCryptohomeClient()->RemoveEx( + account_id_proto, + base::BindOnce(&OnRemoveAppCryptohomeComplete, cryptohome_id, app_id, + base::OnceClosure())); } } @@ -915,9 +923,14 @@ for (auto& entry : old_apps) { entry.second->ClearCache(); const cryptohome::Identification cryptohome_id(entry.second->account_id()); - cryptohome::AsyncMethodCaller::GetInstance()->AsyncRemove( - cryptohome_id, base::Bind(&OnRemoveAppCryptohomeComplete, cryptohome_id, - entry.first, cryptohomes_barrier_closure)); + cryptohome::AccountIdentifier account_id_proto; + account_id_proto.set_account_id(cryptohome_id.id()); + + DBusThreadManager::Get()->GetCryptohomeClient()->RemoveEx( + account_id_proto, + base::BindOnce(&OnRemoveAppCryptohomeComplete, cryptohome_id, + entry.first, cryptohomes_barrier_closure)); + apps_to_remove.push_back(entry.second->app_id()); } external_cache_->RemoveExtensions(apps_to_remove);
diff --git a/chrome/browser/chromeos/attestation/platform_verification_dialog.cc b/chrome/browser/chromeos/attestation/platform_verification_dialog.cc index 17e8d76..f9edc2f0 100644 --- a/chrome/browser/chromeos/attestation/platform_verification_dialog.cc +++ b/chrome/browser/chromeos/attestation/platform_verification_dialog.cc
@@ -13,7 +13,7 @@ #include "chrome/browser/ui/browser_navigator.h" #include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/singleton_tabs.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" #include "chrome/common/url_constants.h" #include "chrome/grit/generated_resources.h" #include "components/constrained_window/constrained_window_views.h"
diff --git a/chrome/browser/chromeos/file_manager/open_with_browser.cc b/chrome/browser/chromeos/file_manager/open_with_browser.cc index 9154c64..fdb3f438 100644 --- a/chrome/browser/chromeos/file_manager/open_with_browser.cc +++ b/chrome/browser/chromeos/file_manager/open_with_browser.cc
@@ -84,8 +84,7 @@ bool IsPdfPluginEnabled(Profile* profile) { DCHECK(profile); - base::FilePath plugin_path = base::FilePath::FromUTF8Unsafe( - ChromeContentClient::kPDFPluginPath); + static const base::FilePath plugin_path(ChromeContentClient::kPDFPluginPath); return IsPepperPluginEnabled(profile, plugin_path); }
diff --git a/chrome/browser/chromeos/login/auth/cryptohome_authenticator_unittest.cc b/chrome/browser/chromeos/login/auth/cryptohome_authenticator_unittest.cc index af0732b..bfa5eea 100644 --- a/chrome/browser/chromeos/login/auth/cryptohome_authenticator_unittest.cc +++ b/chrome/browser/chromeos/login/auth/cryptohome_authenticator_unittest.cc
@@ -154,6 +154,10 @@ mount_guest_should_succeed_ = should_succeed; } + void set_remove_ex_should_succeed(bool should_succeed) { + remove_ex_should_succeed_ = should_succeed; + } + void MountEx(const cryptohome::AccountIdentifier& cryptohome_id, const cryptohome::AuthorizationRequest& auth, const cryptohome::MountRequest& request, @@ -213,12 +217,25 @@ FROM_HERE, base::BindOnce(std::move(callback), reply)); } + // Calls RemoveEx method. |callback| is called after the method call + // succeeds. + void RemoveEx(const cryptohome::AccountIdentifier& account, + DBusMethodCallback<cryptohome::BaseReply> callback) override { + cryptohome::BaseReply reply; + if (!remove_ex_should_succeed_) + reply.set_error(cryptohome::CRYPTOHOME_ERROR_REMOVE_FAILED); + + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::BindOnce(std::move(callback), reply)); + } + private: cryptohome::AccountIdentifier expected_id_; std::string expected_authorization_secret_; bool is_create_attempt_expected_ = false; bool migrate_key_should_succeed_ = false; bool mount_guest_should_succeed_ = false; + bool remove_ex_should_succeed_ = false; DISALLOW_COPY_AND_ASSIGN(TestCryptohomeClient); }; @@ -654,20 +671,13 @@ ExpectLoginSuccess(expected_user_context); FailOnLoginFailure(); - // Set up mock async method caller to respond successfully to a cryptohome - // remove attempt. - mock_caller_->SetUp(true, cryptohome::MOUNT_ERROR_NONE); - EXPECT_CALL( - *mock_caller_, - AsyncRemove(cryptohome::Identification(user_context_.GetAccountId()), _)) - .Times(1) - .RetiresOnSaturation(); - // Set up mock homedir methods to respond successfully to a cryptohome create // attempt. ExpectGetKeyDataExCall(std::unique_ptr<int64_t>(), std::unique_ptr<std::string>()); ExpectMountExCall(true /* expect_create_attempt */); + fake_cryptohome_client_->set_remove_ex_should_succeed( + true /* should_succeed */); state_->PresetOnlineLoginStatus(AuthFailure::AuthFailureNone()); SetAttemptState(auth_.get(), state_.release()); @@ -680,13 +690,8 @@ FailOnLoginSuccess(); ExpectLoginFailure(AuthFailure(AuthFailure::DATA_REMOVAL_FAILED)); - // Set up mock async method caller to fail a cryptohome remove attempt. - mock_caller_->SetUp(false, cryptohome::MOUNT_ERROR_FATAL); - EXPECT_CALL( - *mock_caller_, - AsyncRemove(cryptohome::Identification(user_context_.GetAccountId()), _)) - .Times(1) - .RetiresOnSaturation(); + fake_cryptohome_client_->set_remove_ex_should_succeed( + false /* should_succeed */); SetAttemptState(auth_.get(), state_.release());
diff --git a/chrome/browser/chromeos/login/existing_user_controller.cc b/chrome/browser/chromeos/login/existing_user_controller.cc index a341d63..9f94610 100644 --- a/chrome/browser/chromeos/login/existing_user_controller.cc +++ b/chrome/browser/chromeos/login/existing_user_controller.cc
@@ -62,6 +62,7 @@ #include "chromeos/chromeos_switches.h" #include "chromeos/cryptohome/async_method_caller.h" #include "chromeos/cryptohome/cryptohome_parameters.h" +#include "chromeos/cryptohome/cryptohome_util.h" #include "chromeos/dbus/dbus_thread_manager.h" #include "chromeos/dbus/power_manager_client.h" #include "chromeos/dbus/session_manager_client.h" @@ -1129,12 +1130,18 @@ EncryptionMigrationMode::ASK_USER)); break; - case apu::EcryptfsMigrationAction::kWipe: - cryptohome::AsyncMethodCaller::GetInstance()->AsyncRemove( - cryptohome::Identification(user_context.GetAccountId()), - base::Bind(&ExistingUserController::WipePerformed, - weak_factory_.GetWeakPtr(), user_context)); + case apu::EcryptfsMigrationAction::kWipe: { + cryptohome::AccountIdentifier account_identifier; + account_identifier.set_account_id( + cryptohome::Identification(user_context.GetAccountId()).id()); + + DBusThreadManager::Get()->GetCryptohomeClient()->RemoveEx( + account_identifier, + base::BindOnce(&ExistingUserController::WipePerformed, + weak_factory_.GetWeakPtr(), user_context)); + break; + } case apu::EcryptfsMigrationAction::kMinimalMigrate: // Reset the profile ever initialized flag, so that user policy manager @@ -1167,13 +1174,15 @@ } } -void ExistingUserController::WipePerformed(const UserContext& user_context, - bool success, - cryptohome::MountError return_code) { - if (!success) { +void ExistingUserController::WipePerformed( + const UserContext& user_context, + base::Optional<cryptohome::BaseReply> reply) { + const cryptohome::MountError error = BaseReplyToMountError(reply); + if (error != cryptohome::MOUNT_ERROR_NONE) { LOG(ERROR) << "Removal of cryptohome for " << user_context.GetAccountId().Serialize() - << " failed, return code: " << return_code; + << " failed, return code: " + << BaseReplyToMountError(reply.value()); } // Let the user authenticate online because we lose the OAuth token by
diff --git a/chrome/browser/chromeos/login/existing_user_controller.h b/chrome/browser/chromeos/login/existing_user_controller.h index 12fc553..25745a5 100644 --- a/chrome/browser/chromeos/login/existing_user_controller.h +++ b/chrome/browser/chromeos/login/existing_user_controller.h
@@ -297,8 +297,7 @@ // Called when cryptohome wipe has finished. void WipePerformed(const UserContext& user_context, - bool success, - cryptohome::MountError return_code); + base::Optional<cryptohome::BaseReply> reply); // Triggers online login for the given |account_id|. void ForceOnlineLoginForAccountId(const AccountId& account_id);
diff --git a/chrome/browser/chromeos/login/session/chrome_session_manager.cc b/chrome/browser/chromeos/login/session/chrome_session_manager.cc index ce6f9929..5d58836 100644 --- a/chrome/browser/chromeos/login/session/chrome_session_manager.cc +++ b/chrome/browser/chromeos/login/session/chrome_session_manager.cc
@@ -30,6 +30,7 @@ #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" #include "chrome/browser/chromeos/profiles/profile_helper.h" #include "chrome/browser/chromeos/tether/tether_service.h" +#include "chrome/browser/chromeos/tpm_firmware_update_notification.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/signin/identity_manager_factory.h" #include "chrome/browser/ui/app_list/app_list_client_impl.h" @@ -184,6 +185,7 @@ } UserSessionManager::GetInstance()->CheckEolStatus(user_profile); + tpm_firmware_update::ShowNotificationIfNeeded(user_profile); } } // namespace
diff --git a/chrome/browser/chromeos/login/session/user_session_manager.cc b/chrome/browser/chromeos/login/session/user_session_manager.cc index e6bcdd1..a4830af 100644 --- a/chrome/browser/chromeos/login/session/user_session_manager.cc +++ b/chrome/browser/chromeos/login/session/user_session_manager.cc
@@ -72,6 +72,7 @@ #include "chrome/browser/chromeos/profiles/profile_helper.h" #include "chrome/browser/chromeos/settings/cros_settings.h" #include "chrome/browser/chromeos/tether/tether_service.h" +#include "chrome/browser/chromeos/tpm_firmware_update_notification.h" #include "chrome/browser/component_updater/crl_set_component_installer.h" #include "chrome/browser/component_updater/sth_set_component_installer.h" #include "chrome/browser/first_run/first_run.h" @@ -2024,6 +2025,10 @@ // the message accordingly. CheckEolStatus(profile); + // Check to see if this profile should show TPM Firmware Update Notification + // and show the message accordingly. + tpm_firmware_update::ShowNotificationIfNeeded(profile); + // Show the one-time notification and update the relevant pref about the // completion of the file system migration necessary for ARC, when needed. arc::ShowArcMigrationSuccessNotificationIfNeeded(profile);
diff --git a/chrome/browser/chromeos/login/ui/simple_web_view_dialog.cc b/chrome/browser/chromeos/login/ui/simple_web_view_dialog.cc index cecb35e..a5f08f7 100644 --- a/chrome/browser/chromeos/login/ui/simple_web_view_dialog.cc +++ b/chrome/browser/chromeos/login/ui/simple_web_view_dialog.cc
@@ -17,7 +17,7 @@ #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/content_settings/content_setting_bubble_model_delegate.h" #include "chrome/browser/ui/view_ids.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" #include "chrome/browser/ui/views/toolbar/reload_button.h" #include "chrome/grit/generated_resources.h" #include "chrome/grit/theme_resources.h"
diff --git a/chrome/browser/chromeos/login/users/chrome_user_manager_impl.cc b/chrome/browser/chromeos/login/users/chrome_user_manager_impl.cc index f4de75c6..e294f6f4 100644 --- a/chrome/browser/chromeos/login/users/chrome_user_manager_impl.cc +++ b/chrome/browser/chromeos/login/users/chrome_user_manager_impl.cc
@@ -70,6 +70,9 @@ #include "chrome/common/pref_names.h" #include "chromeos/chromeos_switches.h" #include "chromeos/cryptohome/async_method_caller.h" +#include "chromeos/cryptohome/cryptohome_util.h" +#include "chromeos/dbus/cryptohome/rpc.pb.h" +#include "chromeos/dbus/dbus_thread_manager.h" #include "chromeos/login/login_state.h" #include "chromeos/settings/cros_settings_names.h" #include "chromeos/timezone/timezone_resolver.h" @@ -126,12 +129,11 @@ // Callback that is called after user removal is complete. void OnRemoveUserComplete(const AccountId& account_id, - bool success, - cryptohome::MountError return_code) { - // Log the error, but there's not much we can do. - if (!success) { + base::Optional<cryptohome::BaseReply> reply) { + cryptohome::MountError error = BaseReplyToMountError(reply); + if (error != cryptohome::MOUNT_ERROR_NONE) { LOG(ERROR) << "Removal of cryptohome for " << account_id.Serialize() - << " failed, return code: " << return_code; + << " failed, return code: " << error; } } @@ -1400,9 +1402,11 @@ void ChromeUserManagerImpl::AsyncRemoveCryptohome( const AccountId& account_id) const { - cryptohome::AsyncMethodCaller::GetInstance()->AsyncRemove( - cryptohome::Identification(account_id), - base::Bind(&OnRemoveUserComplete, account_id)); + cryptohome::AccountIdentifier account_id_proto; + account_id_proto.set_account_id(cryptohome::Identification(account_id).id()); + + DBusThreadManager::Get()->GetCryptohomeClient()->RemoveEx( + account_id_proto, base::BindOnce(&OnRemoveUserComplete, account_id)); } bool ChromeUserManagerImpl::IsGuestAccountId(
diff --git a/chrome/browser/chromeos/login/wizard_controller.cc b/chrome/browser/chromeos/login/wizard_controller.cc index fd8c910..be177a6 100644 --- a/chrome/browser/chromeos/login/wizard_controller.cc +++ b/chrome/browser/chromeos/login/wizard_controller.cc
@@ -15,6 +15,7 @@ #include "base/bind.h" #include "base/callback_helpers.h" #include "base/command_line.h" +#include "base/feature_list.h" #include "base/json/json_string_value_serializer.h" #include "base/location.h" #include "base/logging.h" @@ -84,6 +85,7 @@ #include "chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h" #include "chrome/browser/ui/webui/help/help_utils_chromeos.h" #include "chrome/common/chrome_constants.h" +#include "chrome/common/chrome_features.h" #include "chrome/common/pref_names.h" #include "chromeos/audio/cras_audio_handler.h" #include "chromeos/chromeos_constants.h" @@ -251,10 +253,9 @@ return true; } -// Return true if the switch for recommend app screen is on. +// Return true if the feature flag for recommend app screen is on. bool ShouldShowRecommendAppsScreen() { - return base::CommandLine::ForCurrentProcess()->HasSwitch( - chromeos::switches::kEnableOobeRecommendAppsScreen); + return base::FeatureList::IsEnabled(features::kOobeRecommendAppsScreen); } chromeos::LoginDisplayHost* GetLoginDisplayHost() { @@ -1048,7 +1049,7 @@ return; } - // If the switch for recommend app screen is on, show it after the user + // If the feature flag for recommend app screen is on, show it after the user // finished with the PlayStore Terms of Service. Otherwise, advance to the // user image screen. if (ShouldShowRecommendAppsScreen()) {
diff --git a/chrome/browser/chromeos/policy/policy_cert_verifier.cc b/chrome/browser/chromeos/policy/policy_cert_verifier.cc index 53c8ccab..1e160a9 100644 --- a/chrome/browser/chromeos/policy/policy_cert_verifier.cc +++ b/chrome/browser/chromeos/policy/policy_cert_verifier.cc
@@ -93,4 +93,8 @@ return error; } +void PolicyCertVerifier::SetConfig(const Config& config) { + delegate_->SetConfig(config); +} + } // namespace policy
diff --git a/chrome/browser/chromeos/policy/policy_cert_verifier.h b/chrome/browser/chromeos/policy/policy_cert_verifier.h index cb65173..4ade577 100644 --- a/chrome/browser/chromeos/policy/policy_cert_verifier.h +++ b/chrome/browser/chromeos/policy/policy_cert_verifier.h
@@ -50,6 +50,7 @@ net::CompletionOnceCallback callback, std::unique_ptr<Request>* out_req, const net::NetLogWithSource& net_log) override; + void SetConfig(const Config& config) override; private: net::CertificateList trust_anchors_;
diff --git a/chrome/browser/chromeos/power/idle_action_warning_dialog_view.cc b/chrome/browser/chromeos/power/idle_action_warning_dialog_view.cc index ee50963..947175fc 100644 --- a/chrome/browser/chromeos/power/idle_action_warning_dialog_view.cc +++ b/chrome/browser/chromeos/power/idle_action_warning_dialog_view.cc
@@ -9,7 +9,7 @@ #include "base/location.h" #include "base/macros.h" #include "chrome/browser/ui/browser_dialogs.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" #include "chrome/grit/generated_resources.h" #include "ui/aura/window_event_dispatcher.h" #include "ui/base/l10n/l10n_util.h"
diff --git a/chrome/browser/chromeos/preferences.cc b/chrome/browser/chromeos/preferences.cc index 349f17e..03f0cfd 100644 --- a/chrome/browser/chromeos/preferences.cc +++ b/chrome/browser/chromeos/preferences.cc
@@ -505,6 +505,9 @@ // By default showing Sync Consent is set to true. It can changed by policy. registry->RegisterBooleanPref(prefs::kEnableSyncConsent, true); + + registry->RegisterBooleanPref(prefs::kTPMFirmwareUpdateCleanupDismissed, + false); } void Preferences::InitUserPrefs(sync_preferences::PrefServiceSyncable* prefs) {
diff --git a/chrome/browser/chromeos/tpm_firmware_update_notification.cc b/chrome/browser/chromeos/tpm_firmware_update_notification.cc new file mode 100644 index 0000000..005b4ea2 --- /dev/null +++ b/chrome/browser/chromeos/tpm_firmware_update_notification.cc
@@ -0,0 +1,104 @@ +// Copyright 2018 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 "chrome/browser/chromeos/tpm_firmware_update_notification.h" + +#include "base/macros.h" +#include "base/memory/scoped_refptr.h" +#include "base/strings/string16.h" +#include "chrome/browser/chromeos/tpm_firmware_update.h" +#include "chrome/browser/notifications/notification_display_service.h" +#include "chrome/browser/notifications/notification_display_service_factory.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/ui/chrome_pages.h" +#include "chrome/common/pref_names.h" +#include "chrome/common/webui_url_constants.h" +#include "chrome/grit/generated_resources.h" +#include "components/prefs/pref_service.h" +#include "ui/base/l10n/l10n_util.h" +#include "ui/chromeos/devicetype_utils.h" +#include "ui/message_center/public/cpp/notification.h" + +namespace chromeos { +namespace tpm_firmware_update { +namespace { + +constexpr char kTPMFirmwareUpdateNotificationId[] = + "chrome://tpm_firmware_update"; + +class TPMFirmwareUpdateNotificationDelegate + : public message_center::NotificationDelegate { + public: + explicit TPMFirmwareUpdateNotificationDelegate(Profile* profile) + : profile_(profile) {} + + private: + ~TPMFirmwareUpdateNotificationDelegate() override = default; + + // NotificationDelegate: + void Close(bool by_user) override { + if (by_user) { + profile_->GetPrefs()->SetBoolean( + prefs::kTPMFirmwareUpdateCleanupDismissed, true); + } + } + void Click(const base::Optional<int>& button_index, + const base::Optional<base::string16>& reply) override { + // Show the about page which contains the line item allowing the user to + // trigger TPM firmware update installation. + chrome::ShowSettingsSubPageForProfile(profile_, chrome::kHelpSubPage); + + profile_->GetPrefs()->SetBoolean(prefs::kTPMFirmwareUpdateCleanupDismissed, + true); + NotificationDisplayServiceFactory::GetForProfile(profile_)->Close( + NotificationHandler::Type::TRANSIENT, kTPMFirmwareUpdateNotificationId); + } + + Profile* const profile_; + + DISALLOW_COPY_AND_ASSIGN(TPMFirmwareUpdateNotificationDelegate); +}; + +void OnAvailableUpdateModes(Profile* profile, + const std::set<tpm_firmware_update::Mode>& modes) { + if (modes.count(tpm_firmware_update::Mode::kCleanup) == 0) { + return; + } + + std::unique_ptr<message_center::Notification> notification = + message_center::Notification::CreateSystemNotification( + message_center::NOTIFICATION_TYPE_SIMPLE, + kTPMFirmwareUpdateNotificationId, + l10n_util::GetStringUTF16(IDS_TPM_FIRMWARE_UPDATE_NOTIFICATION_TITLE), + l10n_util::GetStringFUTF16( + IDS_TPM_FIRMWARE_UPDATE_NOTIFICATION_MESSAGE, + ui::GetChromeOSDeviceName()), + base::string16(), GURL(kTPMFirmwareUpdateNotificationId), + message_center::NotifierId( + message_center::NotifierId::SYSTEM_COMPONENT, + kTPMFirmwareUpdateNotificationId), + message_center::RichNotificationData(), + base::MakeRefCounted<TPMFirmwareUpdateNotificationDelegate>(profile), + gfx::kNoneIcon, + message_center::SystemNotificationWarningLevel::WARNING); + + NotificationDisplayServiceFactory::GetForProfile(profile)->Display( + NotificationHandler::Type::TRANSIENT, *notification); +} + +} // namespace + +void ShowNotificationIfNeeded(Profile* profile) { + bool cleanup_dismissed = profile->GetPrefs()->GetBoolean( + prefs::kTPMFirmwareUpdateCleanupDismissed); + if (cleanup_dismissed) { + return; + } + + tpm_firmware_update::GetAvailableUpdateModes( + base::BindOnce(&OnAvailableUpdateModes, profile), base::TimeDelta()); +} + +} // namespace tpm_firmware_update +} // namespace chromeos
diff --git a/chrome/browser/chromeos/tpm_firmware_update_notification.h b/chrome/browser/chromeos/tpm_firmware_update_notification.h new file mode 100644 index 0000000..621e71f0 --- /dev/null +++ b/chrome/browser/chromeos/tpm_firmware_update_notification.h
@@ -0,0 +1,21 @@ +// Copyright 2018 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 CHROME_BROWSER_CHROMEOS_TPM_FIRMWARE_UPDATE_NOTIFICATION_H_ +#define CHROME_BROWSER_CHROMEOS_TPM_FIRMWARE_UPDATE_NOTIFICATION_H_ + +class Profile; + +namespace chromeos { +namespace tpm_firmware_update { + +// Displays a message that informs the user about a pending TPM Firmware Update, +// direction the user to the about page to trigger the update and allowing the +// notification to be silenced. +void ShowNotificationIfNeeded(Profile* profile); + +} // namespace tpm_firmware_update +} // namespace chromeos + +#endif // CHROME_BROWSER_CHROMEOS_TPM_FIRMWARE_UPDATE_NOTIFICATION_H_
diff --git a/chrome/browser/chromeos/ui/echo_dialog_view.cc b/chrome/browser/chromeos/ui/echo_dialog_view.cc index 3f5df9a..eede194 100644 --- a/chrome/browser/chromeos/ui/echo_dialog_view.cc +++ b/chrome/browser/chromeos/ui/echo_dialog_view.cc
@@ -8,7 +8,7 @@ #include "chrome/browser/chromeos/ui/echo_dialog_listener.h" #include "chrome/browser/ui/browser_dialogs.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" #include "chrome/grit/generated_resources.h" #include "components/vector_icons/vector_icons.h" #include "ui/base/l10n/l10n_util.h"
diff --git a/chrome/browser/chromeos/ui/request_pin_view.cc b/chrome/browser/chromeos/ui/request_pin_view.cc index 6e7d224..5deaf4b 100644 --- a/chrome/browser/chromeos/ui/request_pin_view.cc +++ b/chrome/browser/chromeos/ui/request_pin_view.cc
@@ -12,7 +12,7 @@ #include "base/strings/utf_string_conversions.h" #include "chrome/browser/chromeos/ui/passphrase_textfield.h" #include "chrome/browser/ui/browser_dialogs.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" #include "chrome/grit/generated_resources.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/resource/resource_bundle.h"
diff --git a/chrome/browser/component_updater/pepper_flash_component_installer.cc b/chrome/browser/component_updater/pepper_flash_component_installer.cc index 7eb598bd..b6ddb1f 100644 --- a/chrome/browser/component_updater/pepper_flash_component_installer.cc +++ b/chrome/browser/component_updater/pepper_flash_component_installer.cc
@@ -208,13 +208,11 @@ std::vector<content::WebPluginInfo> plugins; PluginService::GetInstance()->GetInternalPlugins(&plugins); - base::FilePath placeholder_path = - base::FilePath::FromUTF8Unsafe(ChromeContentClient::kNotPresent); for (const auto& plugin : plugins) { if (!plugin.is_pepper_plugin() || plugin.name != web_plugin.name) continue; - if (plugin.path == placeholder_path) { + if (plugin.path.value() == ChromeContentClient::kNotPresent) { // This is the Flash placeholder; replace it regardless of version or // other considerations. PluginService::GetInstance()->UnregisterInternalPlugin(plugin.path);
diff --git a/chrome/browser/conflicts/enumerate_shell_extensions_win.cc b/chrome/browser/conflicts/enumerate_shell_extensions_win.cc index d59c93b6..2a7c465 100644 --- a/chrome/browser/conflicts/enumerate_shell_extensions_win.cc +++ b/chrome/browser/conflicts/enumerate_shell_extensions_win.cc
@@ -8,7 +8,7 @@ #include "base/files/file_path.h" #include "base/memory/ref_counted.h" -#include "base/metrics/histogram_functions.h" +#include "base/metrics/histogram_macros.h" #include "base/sequenced_task_runner.h" #include "base/strings/string16.h" #include "base/strings/stringprintf.h" @@ -39,7 +39,7 @@ if (clsid.ReadValue(L"", &dll) != ERROR_SUCCESS) continue; - nb_shell_extensions++; + (*nb_shell_extensions)++; callback.Run(base::FilePath(dll)); } } @@ -99,8 +99,8 @@ ReadShellExtensions(HKEY_LOCAL_MACHINE, callback, &nb_shell_extensions); ReadShellExtensions(HKEY_CURRENT_USER, callback, &nb_shell_extensions); - base::UmaHistogramCounts100("ThirdPartyModules.ShellExtensionsCount", - nb_shell_extensions); + UMA_HISTOGRAM_COUNTS_100("ThirdPartyModules.ShellExtensionsCount2", + nb_shell_extensions); } } // namespace internal
diff --git a/chrome/browser/conflicts/incompatible_applications_updater_win.cc b/chrome/browser/conflicts/incompatible_applications_updater_win.cc index 3b535b54..ffe7ee69 100644 --- a/chrome/browser/conflicts/incompatible_applications_updater_win.cc +++ b/chrome/browser/conflicts/incompatible_applications_updater_win.cc
@@ -9,6 +9,7 @@ #include "base/bind.h" #include "base/feature_list.h" +#include "base/metrics/histogram_macros.h" #include "base/strings/utf_string_conversions.h" #include "base/values.h" #include "base/win/registry.h" @@ -365,8 +366,10 @@ // Then check if it can be tied to an installed application on the user's // computer. std::vector<InstalledApplications::ApplicationInfo> associated_applications; - if (!installed_applications_.GetInstalledApplications( - module_key.module_path, &associated_applications)) { + bool tied_to_app = installed_applications_.GetInstalledApplications( + module_key.module_path, &associated_applications); + UMA_HISTOGRAM_BOOLEAN("ThirdPartyModules.Uninstallable", tied_to_app); + if (!tied_to_app) { module_warning_decisions_[module_key.module_id] = ModuleWarningDecision::kNoTiedApplication; return;
diff --git a/chrome/browser/extensions/api/context_menus/context_menu_apitest.cc b/chrome/browser/extensions/api/context_menus/context_menu_apitest.cc index 4554ed65..856b74e 100644 --- a/chrome/browser/extensions/api/context_menus/context_menu_apitest.cc +++ b/chrome/browser/extensions/api/context_menus/context_menu_apitest.cc
@@ -273,11 +273,6 @@ VerifyMenuItem("parent", top_level_model_, top_level_index(), ui::MenuModel::TYPE_SUBMENU, true); - // Since the extension submenu is shown, the previous separator should be in - // the model. - EXPECT_EQ(ui::MenuModel::TYPE_SEPARATOR, - top_level_model_->GetTypeAt(top_level_index() - 1)); - ui::MenuModel* submodel = top_level_model_->GetSubmenuModelAt(top_level_index()); ASSERT_TRUE(submodel); @@ -306,11 +301,6 @@ VerifyMenuItem("parent", top_level_model_, top_level_index(), ui::MenuModel::TYPE_SUBMENU, true); - // Since the extension submenu is shown, the previous separator should be in - // the model. - EXPECT_EQ(ui::MenuModel::TYPE_SEPARATOR, - top_level_model_->GetTypeAt(top_level_index() - 1)); - ui::MenuModel* submodel = top_level_model_->GetSubmenuModelAt(top_level_index()); ASSERT_TRUE(submodel); @@ -339,11 +329,6 @@ VerifyMenuItem(extension()->name(), top_level_model_, top_level_index(), ui::MenuModel::TYPE_SUBMENU, true); - // Since the extension submenu is shown, the previous separator should be in - // the model. - EXPECT_EQ(ui::MenuModel::TYPE_SEPARATOR, - top_level_model_->GetTypeAt(top_level_index() - 1)); - ui::MenuModel* submodel = top_level_model_->GetSubmenuModelAt(top_level_index()); ASSERT_TRUE(submodel); @@ -378,11 +363,6 @@ VerifyMenuItem(extension()->name(), top_level_model_, top_level_index(), ui::MenuModel::TYPE_SUBMENU, true); - // Since the extension submenu is shown, the previous separator should be in - // the model. - EXPECT_EQ(ui::MenuModel::TYPE_SEPARATOR, - top_level_model_->GetTypeAt(top_level_index() - 1)); - ui::MenuModel* submodel = top_level_model_->GetSubmenuModelAt(top_level_index()); ASSERT_TRUE(submodel);
diff --git a/chrome/browser/extensions/api/web_navigation/web_navigation_api.cc b/chrome/browser/extensions/api/web_navigation/web_navigation_api.cc index efd0a38d..c546379 100644 --- a/chrome/browser/extensions/api/web_navigation/web_navigation_api.cc +++ b/chrome/browser/extensions/api/web_navigation/web_navigation_api.cc
@@ -88,25 +88,32 @@ return profile_->IsSameProfile(browser->profile()); } -void WebNavigationEventRouter::TabReplacedAt( +void WebNavigationEventRouter::OnTabStripModelChanged( TabStripModel* tab_strip_model, - content::WebContents* old_contents, - content::WebContents* new_contents, - int index) { - WebNavigationTabObserver* tab_observer = - WebNavigationTabObserver::Get(old_contents); - if (!tab_observer) { - // If you hit this DCHECK(), please add reproduction steps to - // http://crbug.com/109464. - DCHECK(GetViewType(old_contents) != VIEW_TYPE_TAB_CONTENTS); - return; - } - if (!FrameNavigationState::IsValidUrl(old_contents->GetURL()) || - !FrameNavigationState::IsValidUrl(new_contents->GetURL())) + const TabStripModelChange& change, + const TabStripSelectionChange& selection) { + if (change.type() != TabStripModelChange::kReplaced) return; - web_navigation_api_helpers::DispatchOnTabReplaced(old_contents, profile_, - new_contents); + for (const auto& delta : change.deltas()) { + content::WebContents* old_contents = delta.replace.old_contents; + content::WebContents* new_contents = delta.replace.new_contents; + + WebNavigationTabObserver* tab_observer = + WebNavigationTabObserver::Get(old_contents); + if (!tab_observer) { + // If you hit this DCHECK(), please add reproduction steps to + // http://crbug.com/109464. + DCHECK(GetViewType(old_contents) != VIEW_TYPE_TAB_CONTENTS); + continue; + } + if (!FrameNavigationState::IsValidUrl(old_contents->GetURL()) || + !FrameNavigationState::IsValidUrl(new_contents->GetURL())) + continue; + + web_navigation_api_helpers::DispatchOnTabReplaced(old_contents, profile_, + new_contents); + } } void WebNavigationEventRouter::Observe(
diff --git a/chrome/browser/extensions/api/web_navigation/web_navigation_api.h b/chrome/browser/extensions/api/web_navigation/web_navigation_api.h index 1b4b664..30e90fc 100644 --- a/chrome/browser/extensions/api/web_navigation/web_navigation_api.h +++ b/chrome/browser/extensions/api/web_navigation/web_navigation_api.h
@@ -148,10 +148,10 @@ bool ShouldTrackBrowser(Browser* browser) override; // TabStripModelObserver implementation. - void TabReplacedAt(TabStripModel* tab_strip_model, - content::WebContents* old_contents, - content::WebContents* new_contents, - int index) override; + void OnTabStripModelChanged( + TabStripModel* tab_strip_model, + const TabStripModelChange& change, + const TabStripSelectionChange& selection) override; // content::NotificationObserver implementation. void Observe(int type,
diff --git a/chrome/browser/extensions/extension_context_menu_browsertest.cc b/chrome/browser/extensions/extension_context_menu_browsertest.cc index caed3e96..50f65867 100644 --- a/chrome/browser/extensions/extension_context_menu_browsertest.cc +++ b/chrome/browser/extensions/extension_context_menu_browsertest.cc
@@ -571,28 +571,20 @@ // We expect to see the following items in the menu: // radio1 // radio2 - // --separator-- (automatically added) // normal1 - // --separator-- // normal2 - // --separator-- // radio3 // radio4 - // --separator-- // normal3 int index = 0; - ASSERT_EQ(11, menu.GetItemCount()); + ASSERT_EQ(7, menu.GetItemCount()); ExpectLabelAndType("radio1", MenuModel::TYPE_RADIO, menu, index++); ExpectLabelAndType("radio2", MenuModel::TYPE_RADIO, menu, index++); - EXPECT_EQ(MenuModel::TYPE_SEPARATOR, menu.GetTypeAt(index++)); ExpectLabelAndType("normal1", MenuModel::TYPE_COMMAND, menu, index++); - EXPECT_EQ(MenuModel::TYPE_SEPARATOR, menu.GetTypeAt(index++)); ExpectLabelAndType("normal2", MenuModel::TYPE_COMMAND, menu, index++); - EXPECT_EQ(MenuModel::TYPE_SEPARATOR, menu.GetTypeAt(index++)); ExpectLabelAndType("radio3", MenuModel::TYPE_RADIO, menu, index++); ExpectLabelAndType("radio4", MenuModel::TYPE_RADIO, menu, index++); - EXPECT_EQ(MenuModel::TYPE_SEPARATOR, menu.GetTypeAt(index++)); ExpectLabelAndType("normal3", MenuModel::TYPE_COMMAND, menu, index++); }
diff --git a/chrome/browser/extensions/extension_nacl_browsertest.cc b/chrome/browser/extensions/extension_nacl_browsertest.cc index 8ccc8b49..4b08748 100644 --- a/chrome/browser/extensions/extension_nacl_browsertest.cc +++ b/chrome/browser/extensions/extension_nacl_browsertest.cc
@@ -4,7 +4,6 @@ #include "base/command_line.h" #include "base/files/file_path.h" -#include "base/path_service.h" #include "base/strings/utf_string_conversions.h" #include "base/test/bind_test_util.h" #include "chrome/browser/extensions/crx_installer.h" @@ -13,7 +12,7 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" -#include "chrome/common/chrome_paths.h" +#include "chrome/common/chrome_content_client.h" #include "chrome/common/chrome_switches.h" #include "chrome/test/base/ui_test_utils.h" #include "components/prefs/pref_service.h" @@ -115,22 +114,19 @@ } bool IsNaClPluginLoaded() { - base::FilePath path; - if (base::PathService::Get(chrome::FILE_NACL_PLUGIN, &path)) { - // Make sure plugins are loaded off disk first. - { - base::RunLoop run_loop; - PluginService::GetInstance()->GetPlugins(base::BindLambdaForTesting( - [&](const std::vector<content::WebPluginInfo>&) { - run_loop.Quit(); - })); - run_loop.Run(); - } - - content::WebPluginInfo info; - return PluginService::GetInstance()->GetPluginInfoByPath(path, &info); + // Make sure plugins are loaded off disk first. + { + base::RunLoop run_loop; + PluginService::GetInstance()->GetPlugins(base::BindLambdaForTesting( + [&](const std::vector<content::WebPluginInfo>&) { + run_loop.Quit(); + })); + run_loop.Run(); } - return false; + + static const base::FilePath path(ChromeContentClient::kNaClPluginFileName); + content::WebPluginInfo info; + return PluginService::GetInstance()->GetPluginInfoByPath(path, &info); } void CheckPluginsCreated(const GURL& url, PluginType expected_to_succeed) {
diff --git a/chrome/browser/extensions/plugin_manager.cc b/chrome/browser/extensions/plugin_manager.cc index 06ddedcf..48294801 100644 --- a/chrome/browser/extensions/plugin_manager.cc +++ b/chrome/browser/extensions/plugin_manager.cc
@@ -6,11 +6,11 @@ #include "base/files/file_path.h" #include "base/lazy_instance.h" -#include "base/path_service.h" #include "base/strings/utf_string_conversions.h" #include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/plugins/chrome_plugin_service_filter.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/common/chrome_content_client.h" #include "chrome/common/chrome_paths.h" #include "content/public/browser/plugin_service.h" #include "content/public/common/pepper_plugin_info.h" @@ -143,9 +143,7 @@ // there is a MIME type that module wants to handle, so we need to add that // MIME type to plugins which handle NaCl modules in order to allow the // individual modules to handle these types. - base::FilePath path; - if (!base::PathService::Get(chrome::FILE_NACL_PLUGIN, &path)) - return; + static const base::FilePath path(ChromeContentClient::kNaClPluginFileName); const content::PepperPluginInfo* pepper_info = PluginService::GetInstance()->GetRegisteredPpapiPluginInfo(path); if (!pepper_info)
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index 8792fa1d..25ccc34b 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -80,6 +80,11 @@ "When enabled, autofill will cache the responses it receives from the " "crowd-sourced field type prediction server."; +const char kAutofillEnableCompanyNameName[] = + "Enable Autofill Company Name field"; +const char kAutofillEnableCompanyNameDescription[] = + "When enabled, Company Name fields will be auto filled"; + const char kAutofillDynamicFormsName[] = "Autofill Dynamic Forms"; const char kAutofillDynamicFormsDescription[] = "Allows autofill to fill dynamically changing forms"; @@ -3489,6 +3494,12 @@ "Enable Zero State Suggestions feature in Launcher, which will show " "suggetions when launcher search box is active with an empty query"; +const char kEnableOobeRecommendAppsScreenName[] = + "Enable OOBE Recommend Apps Screen"; +const char kEnableOobeRecommendAppsScreenDescription[] = + "Enable the Recommend Apps Screen in OOBE which allows user to install apps" + "from other devices"; + #endif // defined(OS_CHROMEOS) // Random platform combinations -----------------------------------------------
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index 9178091..07311c4 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -76,6 +76,9 @@ extern const char kAutofillCacheQueryResponsesName[]; extern const char kAutofillCacheQueryResponsesDescription[]; +extern const char kAutofillEnableCompanyNameName[]; +extern const char kAutofillEnableCompanyNameDescription[]; + extern const char kAutofillDynamicFormsName[]; extern const char kAutofillDynamicFormsDescription[]; @@ -2127,6 +2130,9 @@ extern const char kEnableZeroStateSuggestionsName[]; extern const char kEnableZeroStateSuggestionsDescription[]; +extern const char kEnableOobeRecommendAppsScreenName[]; +extern const char kEnableOobeRecommendAppsScreenDescription[]; + #endif // #if defined(OS_CHROMEOS) // Random platform combinations -----------------------------------------------
diff --git a/chrome/browser/io_thread.cc b/chrome/browser/io_thread.cc index 7ac138b..f29a64b 100644 --- a/chrome/browser/io_thread.cc +++ b/chrome/browser/io_thread.cc
@@ -135,6 +135,12 @@ return g_cert_verifier_for_io_thread_testing->Verify( params, crl_set, verify_result, std::move(callback), out_req, net_log); } + + void SetConfig(const Config& config) override { + if (!g_cert_verifier_for_io_thread_testing) + return; + return g_cert_verifier_for_io_thread_testing->SetConfig(config); + } }; #if defined(OS_MACOSX)
diff --git a/chrome/browser/metrics/chrome_metrics_service_client.cc b/chrome/browser/metrics/chrome_metrics_service_client.cc index e89716e..a0655218 100644 --- a/chrome/browser/metrics/chrome_metrics_service_client.cc +++ b/chrome/browser/metrics/chrome_metrics_service_client.cc
@@ -152,6 +152,10 @@ #include "chrome/browser/metrics/upgrade_metrics_provider.h" #endif // !defined(OS_ANDROID) && !defined(OS_CHROMEOS) +#if defined(OS_MACOSX) +#include "chrome/browser/metrics/power_metrics_provider_mac.h" +#endif + namespace { #if defined(OS_ANDROID) || defined(OS_CHROMEOS) @@ -716,6 +720,11 @@ metrics_service_->RegisterMetricsProvider( std::make_unique<UpgradeMetricsProvider>()); #endif //! defined(OS_ANDROID) && !defined(OS_CHROMEOS) + +#if defined(OS_MACOSX) + metrics_service_->RegisterMetricsProvider( + std::make_unique<PowerMetricsProvider>()); +#endif } void ChromeMetricsServiceClient::RegisterUKMProviders() {
diff --git a/chrome/browser/metrics/power_metrics_provider_mac.h b/chrome/browser/metrics/power_metrics_provider_mac.h new file mode 100644 index 0000000..53988e0 --- /dev/null +++ b/chrome/browser/metrics/power_metrics_provider_mac.h
@@ -0,0 +1,29 @@ +// Copyright 2018 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 CHROME_BROWSER_METRICS_POWER_METRICS_PROVIDER_MAC_H_ +#define CHROME_BROWSER_METRICS_POWER_METRICS_PROVIDER_MAC_H_ + +#include "components/metrics/metrics_provider.h" + +#include "base/macros.h" +#include "base/memory/scoped_refptr.h" + +class PowerMetricsProvider : public metrics::MetricsProvider { + public: + PowerMetricsProvider(); + ~PowerMetricsProvider() override; + + // metrics::MetricsProvider overrides + void OnRecordingEnabled() override; + void OnRecordingDisabled() override; + + private: + class Impl; + scoped_refptr<Impl> impl_; + + DISALLOW_COPY_AND_ASSIGN(PowerMetricsProvider); +}; + +#endif // CHROME_BROWSER_METRICS_POWER_METRICS_PROVIDER_MAC_H_
diff --git a/chrome/browser/metrics/power_metrics_provider_mac.mm b/chrome/browser/metrics/power_metrics_provider_mac.mm new file mode 100644 index 0000000..1908f742 --- /dev/null +++ b/chrome/browser/metrics/power_metrics_provider_mac.mm
@@ -0,0 +1,267 @@ +// Copyright 2018 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 "chrome/browser/metrics/power_metrics_provider_mac.h" +#include "base/mac/scoped_ioobject.h" +#include "base/macros.h" +#include "base/metrics/histogram_functions.h" +#include "base/metrics/histogram_macros.h" +#include "base/process/process_info.h" +#include "base/sequenced_task_runner.h" +#include "base/task/post_task.h" +#include "base/time/time.h" +#include "chrome/browser/ui/browser_finder.h" + +#include <IOKit/IOKitLib.h> +#include <libkern/OSByteOrder.h> + +namespace { +constexpr base::TimeDelta kStartupPowerMetricsCollectionDuration = + base::TimeDelta::FromSeconds(30); +constexpr base::TimeDelta kStartupPowerMetricsCollectionInterval = + base::TimeDelta::FromSeconds(1); +constexpr base::TimeDelta kPostStartupPowerMetricsCollectionInterval = + base::TimeDelta::FromSeconds(60); + +// This API is undocumented. It can read hardware sensors including +// temperature, voltage, and power. A useful tool for discovering new keys is +// <https://github.com/theopolis/smc-fuzzer>. The following definitions are +// from +// <https://opensource.apple.com/source/PowerManagement/PowerManagement-271.1.1/pmconfigd/PrivateLib.c.auto.html>. +struct SMCParamStruct { + enum { + kSMCUserClientOpen = 0, + kSMCUserClientClose = 1, + kSMCHandleYPCEvent = 2, + kSMCReadKey = 5, + kSMCGetKeyInfo = 9, + }; + + enum class SMCKey : uint32_t { + TotalPower = 'PSTR', // Power: System Total Rail (watts) + CPUPower = 'PCPC', // Power: CPU Package CPU (watts) + iGPUPower = 'PCPG', // Power: CPU Package GPU (watts) + GPU0Power = 'PG0R', // Power: GPU 0 Rail (watts) + GPU1Power = 'PG1R', // Power: GPU 1 Rail (watts) + }; + + // SMC keys are typed, and there are a number of numeric types. Support for + // decoding the ones in this enum is implemented below, but there are more + // types (and more may appear in future hardware). Implement as needed. + enum class DataType : uint32_t { + flt = 'flt ', // Floating point + sp78 = 'sp78', // Fixed point: SIIIIIIIFFFFFFFF + sp87 = 'sp87', // Fixed point: SIIIIIIIIFFFFFFF + spa5 = 'spa5', // Fixed point: SIIIIIIIIIIFFFFF + }; + + struct SMCVersion { + unsigned char major; + unsigned char minor; + unsigned char build; + unsigned char reserved; + unsigned short release; + }; + + struct SMCPLimitData { + uint16_t version; + uint16_t length; + uint32_t cpuPLimit; + uint32_t gpuPLimit; + uint32_t memPLimit; + }; + + struct SMCKeyInfoData { + IOByteCount dataSize; + DataType dataType; + uint8_t dataAttributes; + }; + + SMCKey key; + SMCVersion vers; + SMCPLimitData pLimitData; + SMCKeyInfoData keyInfo; + uint8_t result; + uint8_t status; + uint8_t data8; + uint32_t data32; + uint8_t bytes[32]; +}; + +float FromSMCFixedPoint(uint8_t* bytes, size_t fraction_bits) { + return static_cast<int16_t>(OSReadBigInt16(bytes, 0)) / + static_cast<float>(1 << fraction_bits); +} + +class SMCKey { + public: + SMCKey(base::mac::ScopedIOObject<io_object_t> connect, + SMCParamStruct::SMCKey key) + : connect_(std::move(connect)), key_(key) { + SMCParamStruct out{}; + if (CallSMCFunction(SMCParamStruct::kSMCGetKeyInfo, &out)) + keyInfo_ = out.keyInfo; + } + + bool Exists() { return keyInfo_.dataSize > 0; } + + float Read() { + if (!Exists()) + return 0; + + SMCParamStruct out{}; + if (!CallSMCFunction(SMCParamStruct::kSMCReadKey, &out)) + return 0; + switch (keyInfo_.dataType) { + case SMCParamStruct::DataType::flt: + return *reinterpret_cast<float*>(out.bytes); + case SMCParamStruct::DataType::sp78: + return FromSMCFixedPoint(out.bytes, 8); + case SMCParamStruct::DataType::sp87: + return FromSMCFixedPoint(out.bytes, 7); + case SMCParamStruct::DataType::spa5: + return FromSMCFixedPoint(out.bytes, 5); + default: + break; + } + return 0; + } + + private: + bool CallSMCFunction(uint8_t which, SMCParamStruct* out) { + if (!connect_) + return false; + if (IOConnectCallMethod(connect_, SMCParamStruct::kSMCUserClientOpen, + nullptr, 0, nullptr, 0, nullptr, nullptr, nullptr, + nullptr)) { + connect_.reset(); + return false; + } + + SMCParamStruct in{}; + in.key = key_; + in.keyInfo.dataSize = keyInfo_.dataSize; + in.data8 = which; + + size_t out_size = sizeof(*out); + bool success = IOConnectCallStructMethod( + connect_, SMCParamStruct::kSMCHandleYPCEvent, &in, + sizeof(in), out, &out_size) == kIOReturnSuccess; + + if (IOConnectCallMethod(connect_, SMCParamStruct::kSMCUserClientClose, + nullptr, 0, nullptr, 0, nullptr, nullptr, nullptr, + nullptr)) + connect_.reset(); + + // Even if the close failed, report whether the actual call succeded. + return success; + } + + base::mac::ScopedIOObject<io_object_t> connect_; + SMCParamStruct::SMCKey key_; + SMCParamStruct::SMCKeyInfoData keyInfo_{}; +}; + +} // namespace + +class PowerMetricsProvider::Impl : public base::RefCountedThreadSafe<Impl> { + public: + static scoped_refptr<Impl> Create( + base::mac::ScopedIOObject<io_object_t> connect) { + scoped_refptr<Impl> impl = new Impl(std::move(connect)); + impl->ScheduleCollection(); + return impl; + } + + private: + friend class base::RefCountedThreadSafe<Impl>; + Impl(base::mac::ScopedIOObject<io_object_t> connect) + : task_runner_(base::CreateSequencedTaskRunnerWithTraits( + {base::MayBlock(), base::TaskPriority::BEST_EFFORT, + base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN})), + system_total_power_key_(connect, SMCParamStruct::SMCKey::TotalPower), + cpu_package_cpu_power_key_(connect, SMCParamStruct::SMCKey::CPUPower), + cpu_package_gpu_power_key_(connect, SMCParamStruct::SMCKey::iGPUPower), + gpu_0_power_key_(connect, SMCParamStruct::SMCKey::GPU0Power), + gpu_1_power_key_(connect, SMCParamStruct::SMCKey::GPU0Power) + + {} + + ~Impl() = default; + + bool IsInStartup() { + if (could_be_in_startup_) { + const base::TimeDelta process_uptime = + base::Time::Now() - base::CurrentProcessInfo::CreationTime(); + if (process_uptime >= kStartupPowerMetricsCollectionDuration) + could_be_in_startup_ = false; + } + return could_be_in_startup_; + } + + void ScheduleCollection() { + task_runner_->PostDelayedTask( + FROM_HERE, base::BindOnce(&Impl::Collect, this), + IsInStartup() ? kStartupPowerMetricsCollectionInterval + : kPostStartupPowerMetricsCollectionInterval); + } + + void Collect() { + ScheduleCollection(); + + if (IsInStartup()) + Record("DuringStartup"); + else + Record("All"); + } + + void Record(const std::string& suffix) { + if (system_total_power_key_.Exists()) + base::UmaHistogramCounts100000("Power.Mac.Total." + suffix, + system_total_power_key_.Read() * 1000); + if (cpu_package_cpu_power_key_.Exists()) + base::UmaHistogramCounts100000("Power.Mac.CPU." + suffix, + cpu_package_cpu_power_key_.Read() * 1000); + if (cpu_package_gpu_power_key_.Exists()) + base::UmaHistogramCounts100000("Power.Mac.GPUi." + suffix, + cpu_package_gpu_power_key_.Read() * 1000); + if (gpu_0_power_key_.Exists()) + base::UmaHistogramCounts100000("Power.Mac.GPU0." + suffix, + gpu_0_power_key_.Read() * 1000); + if (gpu_1_power_key_.Exists()) + base::UmaHistogramCounts100000("Power.Mac.GPU1." + suffix, + gpu_1_power_key_.Read() * 1000); + } + + scoped_refptr<base::SequencedTaskRunner> task_runner_; + bool could_be_in_startup_ = true; + + SMCKey system_total_power_key_; + SMCKey cpu_package_cpu_power_key_; + SMCKey cpu_package_gpu_power_key_; + SMCKey gpu_0_power_key_; + SMCKey gpu_1_power_key_; + + DISALLOW_COPY_AND_ASSIGN(Impl); +}; + +PowerMetricsProvider::PowerMetricsProvider() = default; +PowerMetricsProvider::~PowerMetricsProvider() = default; + +void PowerMetricsProvider::OnRecordingEnabled() { + const base::mac::ScopedIOObject<io_service_t> smc_service( + IOServiceGetMatchingService(kIOMasterPortDefault, + IOServiceMatching("AppleSMC"))); + io_object_t connect; + bool service_opened = IOServiceOpen(smc_service, mach_task_self(), 1, + &connect) == kIOReturnSuccess; + UMA_HISTOGRAM_BOOLEAN("Power.Consumption.AppleSMCOpened", service_opened); + if (!service_opened) + return; + impl_ = Impl::Create(base::mac::ScopedIOObject<io_object_t>(connect)); +} + +void PowerMetricsProvider::OnRecordingDisabled() { + impl_.reset(); +}
diff --git a/chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_io_data.cc b/chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_io_data.cc index 71e8f7b..5ce825b 100644 --- a/chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_io_data.cc +++ b/chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_io_data.cc
@@ -10,9 +10,9 @@ #include "build/build_config.h" #include "chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_settings.h" #include "chrome/browser/previews/previews_infobar_delegate.h" -#include "chrome/browser/previews/previews_infobar_tab_helper.h" #include "chrome/browser/previews/previews_service.h" #include "chrome/browser/previews/previews_service_factory.h" +#include "chrome/browser/previews/previews_ui_tab_helper.h" #include "chrome/browser/profiles/profile.h" #include "chrome/common/channel_info.h" #include "chrome/common/chrome_content_client.h" @@ -67,12 +67,12 @@ previews::PreviewsUIService* previews_ui_service = previews_service ? previews_service->previews_ui_service() : nullptr; - PreviewsInfoBarTabHelper* infobar_tab_helper = - PreviewsInfoBarTabHelper::FromWebContents(web_contents); + PreviewsUITabHelper* ui_tab_helper = + PreviewsUITabHelper::FromWebContents(web_contents); uint64_t page_id = 0; - if (infobar_tab_helper && infobar_tab_helper->previews_user_data()) { - page_id = infobar_tab_helper->previews_user_data()->page_id(); + if (ui_tab_helper && ui_tab_helper->previews_user_data()) { + page_id = ui_tab_helper->previews_user_data()->page_id(); } PreviewsInfoBarDelegate::Create(
diff --git a/chrome/browser/net/trial_comparison_cert_verifier.cc b/chrome/browser/net/trial_comparison_cert_verifier.cc index b856e3d7..abec22e 100644 --- a/chrome/browser/net/trial_comparison_cert_verifier.cc +++ b/chrome/browser/net/trial_comparison_cert_verifier.cc
@@ -44,9 +44,7 @@ namespace { -bool CheckTrialEligibility(void* profile_id, - base::TimeDelta primary_latency, - bool is_first_job) { +bool CheckTrialEligibility(void* profile_id) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); // g_browser_process is valid until after all threads are stopped. So it must @@ -59,29 +57,12 @@ // Only allow on non-incognito profiles which have SBER2 (Scout) opt-in set. // See design doc for more details: // https://docs.google.com/document/d/1AM1CD42bC6LHWjKg-Hkid_RLr2DH6OMzstH9-pGSi-g - bool allowed = !profile->IsOffTheRecord() && safe_browsing::IsScout(prefs) && - safe_browsing::IsExtendedReportingEnabled(prefs); - - if (allowed) { - // Only record the TrialPrimary histograms for the same set of requests - // that TrialSecondary histograms will be recorded for, in order to get a - // direct comparison. - UMA_HISTOGRAM_CUSTOM_TIMES("Net.CertVerifier_Job_Latency_TrialPrimary", - primary_latency, - base::TimeDelta::FromMilliseconds(1), - base::TimeDelta::FromMinutes(10), 100); - if (is_first_job) { - UMA_HISTOGRAM_CUSTOM_TIMES( - "Net.CertVerifier_First_Job_Latency_TrialPrimary", primary_latency, - base::TimeDelta::FromMilliseconds(1), - base::TimeDelta::FromMinutes(10), 100); - } - } - - return allowed; + return !profile->IsOffTheRecord() && safe_browsing::IsScout(prefs) && + safe_browsing::IsExtendedReportingEnabled(prefs); } void SendTrialVerificationReport(void* profile_id, + const net::CertVerifier::Config& config, const net::CertVerifier::RequestParams& params, const net::CertVerifyResult& primary_result, const net::CertVerifyResult& trial_result) { @@ -91,7 +72,7 @@ Profile* profile = reinterpret_cast<Profile*>(profile_id); CertificateErrorReport report(params.hostname(), *params.certificate(), - params.flags(), primary_result, trial_result); + config, primary_result, trial_result); report.AddNetworkTimeInfo(g_browser_process->network_time_tracker()); report.AddChromeChannel(chrome::GetChannel()); @@ -200,14 +181,17 @@ class TrialComparisonCertVerifier::TrialVerificationJob { public: - TrialVerificationJob(const net::CertVerifier::RequestParams& params, + TrialVerificationJob(const net::CertVerifier::Config& config, + const net::CertVerifier::RequestParams& params, const net::NetLogWithSource& source_net_log, scoped_refptr<net::CRLSet> crl_set, TrialComparisonCertVerifier* cert_verifier, int primary_error, const net::CertVerifyResult& primary_result, void* profile_id) - : params_(params), + : config_(config), + config_changed_(false), + params_(params), net_log_(net::NetLogWithSource::Make( source_net_log.net_log(), net::NetLogSourceType::TRIAL_CERT_VERIFIER_JOB)), @@ -241,6 +225,8 @@ OnJobCompleted(rv); } + void OnConfigChanged() { config_changed_ = true; } + void Finish(bool is_success, TrialComparisonResult result_code) { TrialComparisonCertVerifier* cert_verifier = cert_verifier_; cert_verifier_ = nullptr; @@ -256,9 +242,9 @@ !base::GetFieldTrialParamByFeatureAsBool( features::kCertDualVerificationTrialFeature, "uma_only", false)) { content::BrowserThread::GetTaskRunnerForThread(content::BrowserThread::UI) - ->PostTask(FROM_HERE, - base::BindOnce(&SendTrialVerificationReport, profile_id_, - params_, primary_result_, trial_result_)); + ->PostTask(FROM_HERE, base::BindOnce(&SendTrialVerificationReport, + profile_id_, config_, params_, + primary_result_, trial_result_)); } // |this| is deleted after RemoveJob returns. @@ -304,22 +290,21 @@ #if defined(OS_MACOSX) if (primary_error_ == net::ERR_CERT_REVOKED && - !(params_.flags() & net::CertVerifier::VERIFY_REV_CHECKING_ENABLED) && + !config_.enable_rev_checking && !(primary_result_.cert_status & net::CERT_STATUS_REV_CHECKING_ENABLED) && !(trial_result_.cert_status & (net::CERT_STATUS_REVOKED | net::CERT_STATUS_REV_CHECKING_ENABLED))) { + if (config_changed_) { + FinishSuccess(kIgnoredConfigurationChanged); + return; + } // CertVerifyProcMac does some revocation checking even if we didn't want // it. Try verifying with the trial verifier with revocation checking // enabled, see if it then returns REVOKED. - RequestParams reverification_params( - params_.certificate(), params_.hostname(), - params_.flags() | net::CertVerifier::VERIFY_REV_CHECKING_ENABLED, - params_.ocsp_response(), params_.additional_trust_anchors()); - - int rv = cert_verifier_->trial_verifier()->Verify( - reverification_params, crl_set_.get(), &reverification_result_, + int rv = cert_verifier_->revocation_trial_verifier()->Verify( + params_, crl_set_.get(), &reverification_result_, base::BindOnce( &TrialVerificationJob::OnMacRevcheckingReverificationJobCompleted, base::Unretained(this)), @@ -336,6 +321,10 @@ if (!chains_equal && (trial_error_ == net::OK || primary_error_ != net::OK)) { + if (config_changed_) { + FinishSuccess(kIgnoredConfigurationChanged); + return; + } // Chains were different, reverify the trial_result_.verified_cert chain // using the platform verifier and compare results again. RequestParams reverification_params( @@ -436,6 +425,8 @@ } private: + const net::CertVerifier::Config config_; + bool config_changed_; const net::CertVerifier::RequestParams params_; const net::NetLogWithSource net_log_; scoped_refptr<net::CRLSet> crl_set_; @@ -483,7 +474,20 @@ &TrialComparisonCertVerifier::OnTrialVerifierComplete, base::Unretained(this)), false /* should_record_histograms */)), - weak_ptr_factory_(this) {} + revocation_trial_verifier_( + net::MultiThreadedCertVerifier::CreateForDualVerificationTrial( + trial_verify_proc, + // Unretained is safe since the callback won't be called after + // |trial_verifier_| is destroyed. + base::BindRepeating( + &TrialComparisonCertVerifier::OnTrialVerifierComplete, + base::Unretained(this)), + false /* should_record_histograms */)), + weak_ptr_factory_(this) { + net::CertVerifier::Config config; + config.enable_rev_checking = true; + revocation_trial_verifier_->SetConfig(config); +} TrialComparisonCertVerifier::~TrialComparisonCertVerifier() = default; @@ -504,6 +508,25 @@ std::move(callback), out_req, net_log); } +void TrialComparisonCertVerifier::SetConfig(const Config& config) { + config_ = config; + config_id_++; + + primary_verifier_->SetConfig(config); + primary_reverifier_->SetConfig(config); + trial_verifier_->SetConfig(config); + + // Always enable revocation checking for the revocation trial verifier. + net::CertVerifier::Config config_with_revocation = config; + config_with_revocation.enable_rev_checking = true; + revocation_trial_verifier_->SetConfig(config_with_revocation); + + // Notify all in-process jobs that the underlying configuration has changed. + for (auto& job : jobs_) { + job->OnConfigChanged(); + } +} + void TrialComparisonCertVerifier::OnPrimaryVerifierComplete( const RequestParams& params, scoped_refptr<net::CRLSet> crl_set, @@ -526,12 +549,11 @@ base::PostTaskAndReplyWithResult( content::BrowserThread::GetTaskRunnerForThread(content::BrowserThread::UI) .get(), - FROM_HERE, - base::BindOnce(CheckTrialEligibility, profile_id_, primary_latency, - is_first_job), + FROM_HERE, base::BindOnce(CheckTrialEligibility, profile_id_), base::BindOnce(&TrialComparisonCertVerifier::MaybeDoTrialVerification, weak_ptr_factory_.GetWeakPtr(), params, std::move(crl_set), - net_log, primary_error, primary_result, profile_id_)); + net_log, primary_error, primary_result, primary_latency, + is_first_job, config_id_, profile_id_)); } void TrialComparisonCertVerifier::OnTrialVerifierComplete( @@ -561,16 +583,35 @@ const net::NetLogWithSource& net_log, int primary_error, const net::CertVerifyResult& primary_result, + base::TimeDelta primary_latency, + bool is_first_job, + uint32_t config_id, void* profile_id, bool trial_allowed) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - if (!trial_allowed) + // If the trial is not allowed, or the configuration has changed while + // determining if the trial is allowed, no need to continue. + if (!trial_allowed || config_id != config_id_) return; + // Only record the TrialPrimary histograms for the same set of requests + // that TrialSecondary histograms will be recorded for, in order to get a + // direct comparison. + UMA_HISTOGRAM_CUSTOM_TIMES("Net.CertVerifier_Job_Latency_TrialPrimary", + primary_latency, + base::TimeDelta::FromMilliseconds(1), + base::TimeDelta::FromMinutes(10), 100); + if (is_first_job) { + UMA_HISTOGRAM_CUSTOM_TIMES( + "Net.CertVerifier_First_Job_Latency_TrialPrimary", primary_latency, + base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromMinutes(10), + 100); + } + std::unique_ptr<TrialVerificationJob> job = std::make_unique<TrialVerificationJob>( - params, net_log, std::move(crl_set), this, primary_error, + config_, params, net_log, std::move(crl_set), this, primary_error, primary_result, profile_id); TrialVerificationJob* job_ptr = job.get(); jobs_.insert(std::move(job));
diff --git a/chrome/browser/net/trial_comparison_cert_verifier.h b/chrome/browser/net/trial_comparison_cert_verifier.h index b7bdea2..08d0a88 100644 --- a/chrome/browser/net/trial_comparison_cert_verifier.h +++ b/chrome/browser/net/trial_comparison_cert_verifier.h
@@ -5,6 +5,8 @@ #ifndef CHROME_BROWSER_NET_TRIAL_COMPARISON_CERT_VERIFIER_H_ #define CHROME_BROWSER_NET_TRIAL_COMPARISON_CERT_VERIFIER_H_ +#include <stdint.h> + #include "base/containers/unique_ptr_adapters.h" #include "base/macros.h" #include "base/memory/ref_counted.h" @@ -32,7 +34,8 @@ kIgnoredMultipleEVPoliciesAndOneMatchesRoot = 7, kIgnoredDifferentPathReVerifiesEquivalent = 8, kIgnoredLocallyTrustedLeaf = 9, - kMaxValue = kIgnoredLocallyTrustedLeaf + kIgnoredConfigurationChanged = 10, + kMaxValue = kIgnoredConfigurationChanged }; TrialComparisonCertVerifier( @@ -53,6 +56,7 @@ net::CompletionOnceCallback callback, std::unique_ptr<Request>* out_req, const net::NetLogWithSource& net_log) override; + void SetConfig(const Config& config) override; // Returns a CertVerifier using the primary CertVerifyProc, which will not // cause OnPrimaryVerifierComplete to be called. This can be used to @@ -62,6 +66,9 @@ return primary_reverifier_.get(); } net::CertVerifier* trial_verifier() const { return trial_verifier_.get(); } + net::CertVerifier* revocation_trial_verifier() const { + return revocation_trial_verifier_.get(); + } private: class TrialVerificationJob; @@ -71,7 +78,7 @@ const net::NetLogWithSource& net_log, int primary_error, const net::CertVerifyResult& primary_result, - base::TimeDelta latency, + base::TimeDelta primary_latency, bool is_first_job); void OnTrialVerifierComplete(const RequestParams& params, scoped_refptr<net::CRLSet> crl_set, @@ -85,6 +92,9 @@ const net::NetLogWithSource& net_log, int primary_error, const net::CertVerifyResult& primary_result, + base::TimeDelta primary_latency, + bool is_first_job, + uint32_t config_id, void* profile_id, bool trial_allowed); @@ -94,9 +104,17 @@ // accidentally using it on IO thread. void* profile_id_; + // Unique identifier for the current configuration, to determine if a + // configuration has changed in between primary and trial verifications. + uint32_t config_id_; + net::CertVerifier::Config config_; + std::unique_ptr<net::CertVerifier> primary_verifier_; std::unique_ptr<net::CertVerifier> primary_reverifier_; std::unique_ptr<net::CertVerifier> trial_verifier_; + // Similar to |trial_verifier_|, except configured to always check + // revocation information. + std::unique_ptr<net::CertVerifier> revocation_trial_verifier_; std::set<std::unique_ptr<TrialVerificationJob>, base::UniquePtrComparator> jobs_;
diff --git a/chrome/browser/net/trial_comparison_cert_verifier_unittest.cc b/chrome/browser/net/trial_comparison_cert_verifier_unittest.cc index a8d7432..7112634 100644 --- a/chrome/browser/net/trial_comparison_cert_verifier_unittest.cc +++ b/chrome/browser/net/trial_comparison_cert_verifier_unittest.cc
@@ -900,12 +900,14 @@ base::MakeRefCounted<FakeCertVerifyProc>(net::OK, secondary_result); TrialComparisonCertVerifier verifier(profile(), verify_proc1, verify_proc2); + net::CertVerifier::Config config; + config.enable_rev_checking = true; + config.enable_sha1_local_anchors = true; + verifier.SetConfig(config); - net::CertVerifier::RequestParams params( - leaf_cert_1_, "127.0.0.1", - net::CertVerifier::VERIFY_ENABLE_SHA1_LOCAL_ANCHORS | - net::CertVerifier::VERIFY_REV_CHECKING_ENABLED, - std::string() /* ocsp_response */, {} /* additional_trust_anchors */); + net::CertVerifier::RequestParams params(leaf_cert_1_, "127.0.0.1", 0, + std::string() /* ocsp_response */, + {} /* additional_trust_anchors */); net::CertVerifyResult result; net::TestCompletionCallback callback; std::unique_ptr<net::CertVerifier::Request> request; @@ -1172,7 +1174,64 @@ histograms_.ExpectTotalCount("Net.CertVerifier_TrialComparisonResult", 0); } -TEST_F(TrialComparisonCertVerifierTest, DeletedDuringTrialVerification) { +TEST_F(TrialComparisonCertVerifierTest, DeletedBeforeTrialVerificationStarted) { + // Primary verifier returns an error status. + net::CertVerifyResult primary_result; + primary_result.verified_cert = cert_chain_1_; + primary_result.cert_status = net::CERT_STATUS_DATE_INVALID; + scoped_refptr<FakeCertVerifyProc> verify_proc1 = + base::MakeRefCounted<FakeCertVerifyProc>(net::ERR_CERT_DATE_INVALID, + primary_result); + + // Trial verifier has ok status. + net::CertVerifyResult secondary_result; + secondary_result.verified_cert = cert_chain_1_; + scoped_refptr<NotCalledCertVerifyProc> verify_proc2 = + base::MakeRefCounted<NotCalledCertVerifyProc>(); + + auto verifier = std::make_unique<TrialComparisonCertVerifier>( + profile(), verify_proc1, verify_proc2); + + net::CertVerifier::RequestParams params( + leaf_cert_1_, "127.0.0.1", 0 /* flags */, + std::string() /* ocsp_response */, {} /* additional_trust_anchors */); + net::CertVerifyResult result; + net::TestCompletionCallback callback; + std::unique_ptr<net::CertVerifier::Request> request; + int error = + verifier->Verify(params, nullptr /* crl_set */, &result, + callback.callback(), &request, net::NetLogWithSource()); + ASSERT_THAT(error, IsError(net::ERR_IO_PENDING)); + EXPECT_TRUE(request); + + // Wait for primary verifier to finish. + error = callback.WaitForResult(); + EXPECT_THAT(error, IsError(net::ERR_CERT_DATE_INVALID)); + + // Delete the TrialComparisonCertVerifier. + verifier.reset(); + + // Trial verification has not yet started, as it was waiting on the profile + // to determine whether or not it would be permitted. + + // Wait for any tasks to finish. + content::RunAllTasksUntilIdle(); + + // Expect no report. + reporting_service_test_helper()->ExpectNoRequests(service()); + + // The actual verification job should be completed, but neither the + // primary nor secondary job metrics should be recorded, as the verifier + // was deleted prior to determining whether a trial verification would be + // run. + histograms_.ExpectTotalCount("Net.CertVerifier_Job_Latency", 1); + histograms_.ExpectTotalCount("Net.CertVerifier_Job_Latency_TrialPrimary", 0); + histograms_.ExpectTotalCount("Net.CertVerifier_Job_Latency_TrialSecondary", + 0); + histograms_.ExpectTotalCount("Net.CertVerifier_TrialComparisonResult", 0); +} + +TEST_F(TrialComparisonCertVerifierTest, DeletedAfterTrialVerificationStarted) { // Primary verifier returns an error status. net::CertVerifyResult primary_result; primary_result.verified_cert = cert_chain_1_; @@ -1206,7 +1265,23 @@ error = callback.WaitForResult(); EXPECT_THAT(error, IsError(net::ERR_CERT_DATE_INVALID)); - // Delete the TrialComparisonCertVerifier. + // Allow the lookup on the UI thread for the profile to determine trial + // status. + std::unique_ptr<base::RunLoop> run_loop(std::make_unique<base::RunLoop>()); + content::BrowserThread::GetTaskRunnerForThread(content::BrowserThread::UI) + ->PostTask(FROM_HERE, run_loop->QuitClosure()); + run_loop->Run(); + + // Allow recording the metrics back on the IO thread, and starting the + // second verification, to run. + run_loop = std::make_unique<base::RunLoop>(); + content::BrowserThread::GetTaskRunnerForThread(content::BrowserThread::IO) + ->PostTask(FROM_HERE, run_loop->QuitClosure()); + run_loop->Run(); + + // Delete the TrialComparisonCertVerifier. The trial verification is still + // running on the task scheduler (or, depending on timing, has posted back + // to the IO thread after the Quit event). verifier.reset(); // The callback to the trial verifier does not run. The verification task @@ -1304,8 +1379,8 @@ // ...unless it was called with REV_CHECKING_ENABLED. EXPECT_CALL( *verify_proc2, - VerifyInternal(_, _, _, net::CertVerifier::VERIFY_REV_CHECKING_ENABLED, _, - _, _)) + VerifyInternal(_, _, _, net::CertVerifyProc::VERIFY_REV_CHECKING_ENABLED, + _, _, _)) .WillRepeatedly(DoAll(SetArgPointee<6>(revoked_result), Return(net::ERR_CERT_REVOKED)));
diff --git a/chrome/browser/pdf/pdf_extension_test.cc b/chrome/browser/pdf/pdf_extension_test.cc index 896d0140..901e7f32 100644 --- a/chrome/browser/pdf/pdf_extension_test.cc +++ b/chrome/browser/pdf/pdf_extension_test.cc
@@ -353,7 +353,7 @@ void CountPDFProcessesOnIOThread(int* result) { auto* service = content::PluginService::GetInstance(); *result = service->CountPpapiPluginProcessesForProfile( - base::FilePath::FromUTF8Unsafe(ChromeContentClient::kPDFPluginPath), + base::FilePath(ChromeContentClient::kPDFPluginPath), browser()->profile()->GetPath()); } };
diff --git a/chrome/browser/plugins/chrome_plugin_service_filter.cc b/chrome/browser/plugins/chrome_plugin_service_filter.cc index 9f0645f8..3c2de25 100644 --- a/chrome/browser/plugins/chrome_plugin_service_filter.cc +++ b/chrome/browser/plugins/chrome_plugin_service_filter.cc
@@ -104,11 +104,6 @@ host_content_settings_map->RemoveObserver(&observer); } -ChromePluginServiceFilter::OverriddenPlugin::OverriddenPlugin() - : render_frame_id(MSG_ROUTING_NONE) {} - -ChromePluginServiceFilter::OverriddenPlugin::~OverriddenPlugin() {} - ChromePluginServiceFilter::ProcessDetails::ProcessDetails() {} ChromePluginServiceFilter::ProcessDetails::ProcessDetails( @@ -142,15 +137,10 @@ void ChromePluginServiceFilter::OverridePluginForFrame( int render_process_id, int render_frame_id, - const GURL& url, const content::WebPluginInfo& plugin) { base::AutoLock auto_lock(lock_); ProcessDetails* details = GetOrRegisterProcess(render_process_id); - OverriddenPlugin overridden_plugin; - overridden_plugin.render_frame_id = render_frame_id; - overridden_plugin.url = url; - overridden_plugin.plugin = plugin; - details->overridden_plugins.push_back(overridden_plugin); + details->overridden_plugins.push_back({render_frame_id, plugin}); } void ChromePluginServiceFilter::AuthorizePlugin( @@ -186,9 +176,7 @@ // Check whether the plugin is overridden. if (details) { for (const auto& plugin_override : details->overridden_plugins) { - if (plugin_override.render_frame_id == render_frame_id && - (plugin_override.url.is_empty() || - plugin_override.url == plugin_content_url)) { + if (plugin_override.render_frame_id == render_frame_id) { bool use = plugin_override.plugin.path == plugin->path; if (use) *plugin = plugin_override.plugin;
diff --git a/chrome/browser/plugins/chrome_plugin_service_filter.h b/chrome/browser/plugins/chrome_plugin_service_filter.h index 133145db..c707c87 100644 --- a/chrome/browser/plugins/chrome_plugin_service_filter.h +++ b/chrome/browser/plugins/chrome_plugin_service_filter.h
@@ -40,11 +40,10 @@ void UnregisterResourceContext(const void* context); - // Overrides the plugin lookup mechanism for a given tab and object URL to use - // a specific plugin. + // Overrides the plugin lookup mechanism for a given tab to use a specific + // plugin. void OverridePluginForFrame(int render_process_id, int render_frame_id, - const GURL& url, const content::WebPluginInfo& plugin); // Authorizes a given plugin for a given process. @@ -79,12 +78,8 @@ struct ContextInfo; struct OverriddenPlugin { - OverriddenPlugin(); - ~OverriddenPlugin(); - - int render_frame_id; - GURL url; // If empty, the override applies to all urls in render_frame. - content::WebPluginInfo plugin; + const int render_frame_id; + const content::WebPluginInfo plugin; }; struct ProcessDetails {
diff --git a/chrome/browser/plugins/pdf_iframe_navigation_throttle.cc b/chrome/browser/plugins/pdf_iframe_navigation_throttle.cc index 0a458b1..1b4fd2b 100644 --- a/chrome/browser/plugins/pdf_iframe_navigation_throttle.cc +++ b/chrome/browser/plugins/pdf_iframe_navigation_throttle.cc
@@ -4,6 +4,8 @@ #include "chrome/browser/plugins/pdf_iframe_navigation_throttle.h" +#include <string> + #include "base/feature_list.h" #include "chrome/common/chrome_content_client.h" #include "chrome/common/chrome_features.h" @@ -42,8 +44,8 @@ #if BUILDFLAG(ENABLE_PLUGINS) content::WebPluginInfo pdf_plugin_info; - base::FilePath pdf_plugin_path = - base::FilePath::FromUTF8Unsafe(ChromeContentClient::kPDFPluginPath); + static const base::FilePath pdf_plugin_path( + ChromeContentClient::kPDFPluginPath); content::PluginService::GetInstance()->GetPluginInfoByPath(pdf_plugin_path, &pdf_plugin_info);
diff --git a/chrome/browser/plugins/plugin_info_host_impl.cc b/chrome/browser/plugins/plugin_info_host_impl.cc index 7092c5d..52d374d 100644 --- a/chrome/browser/plugins/plugin_info_host_impl.cc +++ b/chrome/browser/plugins/plugin_info_host_impl.cc
@@ -366,12 +366,11 @@ PluginService::GetInstance()->GetPluginInfoArray( url, mime_type, allow_wildcard, &matching_plugins, &mime_types); #if defined(GOOGLE_CHROME_BUILD) - base::FilePath not_present = - base::FilePath::FromUTF8Unsafe(ChromeContentClient::kNotPresent); matching_plugins.erase( std::remove_if(matching_plugins.begin(), matching_plugins.end(), - [¬_present](const WebPluginInfo& info) { - return info.path == not_present; + [&](const WebPluginInfo& info) { + return info.path.value() == + ChromeContentClient::kNotPresent; }), matching_plugins.end()); #endif // defined(GOOGLE_CHROME_BUILD)
diff --git a/chrome/browser/plugins/plugin_response_interceptor_url_loader_throttle_browsertest.cc b/chrome/browser/plugins/plugin_response_interceptor_url_loader_throttle_browsertest.cc index 5f444ea..946ef7f61 100644 --- a/chrome/browser/plugins/plugin_response_interceptor_url_loader_throttle_browsertest.cc +++ b/chrome/browser/plugins/plugin_response_interceptor_url_loader_throttle_browsertest.cc
@@ -60,7 +60,7 @@ void CountPDFProcessesOnIOThread(int* result) { auto* service = content::PluginService::GetInstance(); *result = service->CountPpapiPluginProcessesForProfile( - base::FilePath::FromUTF8Unsafe(ChromeContentClient::kPDFPluginPath), + base::FilePath(ChromeContentClient::kPDFPluginPath), browser()->profile()->GetPath()); } };
diff --git a/chrome/browser/prefs/pref_metrics_service.cc b/chrome/browser/prefs/pref_metrics_service.cc index a8026b5..d0c2d9e 100644 --- a/chrome/browser/prefs/pref_metrics_service.cc +++ b/chrome/browser/prefs/pref_metrics_service.cc
@@ -4,15 +4,12 @@ #include "chrome/browser/prefs/pref_metrics_service.h" -#include <stddef.h> +#include <string> -#include "base/bind.h" -#include "base/command_line.h" #include "base/metrics/histogram_macros.h" -#include "base/strings/string_number_conversions.h" +#include "base/values.h" #include "build/build_config.h" #include "chrome/browser/browser_process.h" -#include "chrome/browser/prefs/pref_service_syncable_util.h" #include "chrome/browser/prefs/session_startup_pref.h" #include "chrome/browser/profiles/incognito_helpers.h" #include "chrome/browser/profiles/profile.h" @@ -21,21 +18,15 @@ #include "chrome/common/pref_names.h" #include "chrome/common/url_constants.h" #include "components/keyed_service/content/browser_context_dependency_manager.h" -#include "components/prefs/pref_registry_simple.h" #include "components/prefs/pref_service.h" #include "components/rappor/public/rappor_utils.h" #include "components/rappor/rappor_service_impl.h" #include "components/search_engines/template_url_prepopulate_data.h" -#include "components/sync_preferences/pref_service_syncable.h" -#include "components/sync_preferences/synced_pref_change_registrar.h" #include "content/public/browser/browser_url_handler.h" -#include "crypto/hmac.h" -#include "net/base/registry_controlled_domains/registry_controlled_domain.h" +#include "url/gurl.h" namespace { -const int kSessionStartupPrefValueMax = SessionStartupPref::kPrefValueMax; - #if !defined(OS_ANDROID) // Record a sample for the Settings.NewTabPage rappor metric. void SampleNewTabPageURL(Profile* profile) { @@ -57,25 +48,8 @@ PrefMetricsService::PrefMetricsService(Profile* profile) : profile_(profile), prefs_(profile_->GetPrefs()), - local_state_(g_browser_process->local_state()), weak_factory_(this) { RecordLaunchPrefs(); - - sync_preferences::PrefServiceSyncable* prefs = - PrefServiceSyncableFromProfile(profile_); - synced_pref_change_registrar_.reset( - new sync_preferences::SyncedPrefChangeRegistrar(prefs)); - - RegisterSyncedPrefObservers(); -} - -// For unit testing only. -PrefMetricsService::PrefMetricsService(Profile* profile, - PrefService* local_state) - : profile_(profile), - prefs_(profile->GetPrefs()), - local_state_(local_state), - weak_factory_(this) { } PrefMetricsService::~PrefMetricsService() { @@ -132,8 +106,9 @@ // applicable. Also, startup pages are not supported on Android #if !defined(OS_ANDROID) int restore_on_startup = prefs_->GetInteger(prefs::kRestoreOnStartup); - UMA_HISTOGRAM_ENUMERATION("Settings.StartupPageLoadSettings", - restore_on_startup, kSessionStartupPrefValueMax); + UMA_HISTOGRAM_ENUMERATION( + "Settings.StartupPageLoadSettings", restore_on_startup, + static_cast<int>(SessionStartupPref::kPrefValueMax)); if (restore_on_startup == SessionStartupPref::kPrefValueURLs) { const base::ListValue* url_list = prefs_->GetList(prefs::kURLsToRestoreOnStartup); @@ -177,70 +152,6 @@ #endif } -void PrefMetricsService::RegisterSyncedPrefObservers() { - LogHistogramValueCallback booleanHandler = base::Bind( - &PrefMetricsService::LogBooleanPrefChange, base::Unretained(this)); - - AddPrefObserver(prefs::kShowHomeButton, "ShowHomeButton", booleanHandler); - AddPrefObserver(prefs::kHomePageIsNewTabPage, "HomePageIsNewTabPage", - booleanHandler); - - AddPrefObserver(prefs::kRestoreOnStartup, "StartupPageLoadSettings", - base::Bind(&PrefMetricsService::LogIntegerPrefChange, - base::Unretained(this), - kSessionStartupPrefValueMax)); -} - -void PrefMetricsService::AddPrefObserver( - const std::string& path, - const std::string& histogram_name_prefix, - const LogHistogramValueCallback& callback) { - synced_pref_change_registrar_->Add(path.c_str(), - base::Bind(&PrefMetricsService::OnPrefChanged, - base::Unretained(this), - histogram_name_prefix, callback)); -} - -void PrefMetricsService::OnPrefChanged( - const std::string& histogram_name_prefix, - const LogHistogramValueCallback& callback, - const std::string& path, - bool from_sync) { - sync_preferences::PrefServiceSyncable* prefs = - PrefServiceSyncableFromProfile(profile_); - const PrefService::Preference* pref = prefs->FindPreference(path); - DCHECK(pref); - std::string source_name( - from_sync ? ".PulledFromSync" : ".PushedToSync"); - std::string histogram_name("Settings." + histogram_name_prefix + source_name); - callback.Run(histogram_name, pref->GetValue()); -} - -void PrefMetricsService::LogBooleanPrefChange(const std::string& histogram_name, - const base::Value* value) { - bool boolean_value = false; - if (!value->GetAsBoolean(&boolean_value)) - return; - base::HistogramBase* histogram = base::BooleanHistogram::FactoryGet( - histogram_name, base::HistogramBase::kUmaTargetedHistogramFlag); - histogram->Add(boolean_value); -} - -void PrefMetricsService::LogIntegerPrefChange(int boundary_value, - const std::string& histogram_name, - const base::Value* value) { - int integer_value = 0; - if (!value->GetAsInteger(&integer_value)) - return; - base::HistogramBase* histogram = base::LinearHistogram::FactoryGet( - histogram_name, - 1, - boundary_value, - boundary_value + 1, - base::HistogramBase::kUmaTargetedHistogramFlag); - histogram->Add(integer_value); -} - // static PrefMetricsService::Factory* PrefMetricsService::Factory::GetInstance() { return base::Singleton<PrefMetricsService::Factory>::get();
diff --git a/chrome/browser/prefs/pref_metrics_service.h b/chrome/browser/prefs/pref_metrics_service.h index 36f1c5e..a2caba11 100644 --- a/chrome/browser/prefs/pref_metrics_service.h +++ b/chrome/browser/prefs/pref_metrics_service.h
@@ -5,17 +5,14 @@ #ifndef CHROME_BROWSER_PREFS_PREF_METRICS_SERVICE_H_ #define CHROME_BROWSER_PREFS_PREF_METRICS_SERVICE_H_ -#include <map> -#include <memory> -#include <string> - #include "base/macros.h" #include "base/memory/singleton.h" #include "base/memory/weak_ptr.h" -#include "chrome/browser/profiles/profile.h" #include "components/keyed_service/content/browser_context_keyed_service_factory.h" #include "components/keyed_service/core/keyed_service.h" -#include "components/sync_preferences/synced_pref_change_registrar.h" +#include "url/gurl.h" + +class Profile; // PrefMetricsService is responsible for recording prefs-related UMA stats. class PrefMetricsService : public KeyedService { @@ -48,47 +45,11 @@ }; private: - friend class PrefMetricsServiceTest; - - // Function to log a Value to a histogram - typedef base::Callback<void(const std::string&, const base::Value*)> - LogHistogramValueCallback; - - // For unit testing only. - PrefMetricsService(Profile* profile, PrefService* local_settings); - // Record prefs state on browser context creation. void RecordLaunchPrefs(); - // Register callbacks for synced pref changes. - void RegisterSyncedPrefObservers(); - - // Registers a histogram logging callback for a synced pref change. - void AddPrefObserver(const std::string& path, - const std::string& histogram_name_prefix, - const LogHistogramValueCallback& callback); - - // Generic callback to observe a synced pref change. - void OnPrefChanged(const std::string& histogram_name_prefix, - const LogHistogramValueCallback& callback, - const std::string& path, - bool from_sync); - - // Callback for a boolean pref change histogram. - void LogBooleanPrefChange(const std::string& histogram_name, - const base::Value* value); - - // Callback for an integer pref change histogram. - void LogIntegerPrefChange(int boundary_value, - const std::string& histogram_name, - const base::Value* value); - Profile* profile_; PrefService* prefs_; - PrefService* local_state_; - - std::unique_ptr<sync_preferences::SyncedPrefChangeRegistrar> - synced_pref_change_registrar_; base::WeakPtrFactory<PrefMetricsService> weak_factory_;
diff --git a/chrome/browser/previews/previews_browsertest.cc b/chrome/browser/previews/previews_browsertest.cc index 194d1726..ff5b7855 100644 --- a/chrome/browser/previews/previews_browsertest.cc +++ b/chrome/browser/previews/previews_browsertest.cc
@@ -9,10 +9,12 @@ #include "base/metrics/field_trial_param_associator.h" #include "base/metrics/field_trial_params.h" #include "base/run_loop.h" +#include "base/strings/string_number_conversions.h" #include "base/test/metrics/histogram_tester.h" #include "base/test/scoped_feature_list.h" #include "build/build_config.h" #include "chrome/browser/browser_process.h" +#include "chrome/browser/previews/previews_lite_page_navigation_throttle.h" #include "chrome/browser/ui/browser.h" #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/ui_test_utils.h" @@ -22,6 +24,7 @@ #include "components/optimization_guide/test_component_creator.h" #include "components/previews/core/previews_features.h" #include "content/public/test/browser_test_utils.h" +#include "net/http/http_status_code.h" #include "net/test/embedded_test_server/http_request.h" #include "net/test/embedded_test_server/http_response.h" @@ -193,9 +196,9 @@ }; // Previews InfoBar (which these tests triggers) does not work on Mac. -// See crbug.com/782322 for detail. -// Also occasional flakes on win7 (crbug.com/789542). -// Also occasional flakes on Linux Xenial (crbug.com/869781). +// See https://crbug.com/782322 for detail. +// Also occasional flakes on win7 (https://crbug.com/789542). +// Also occasional flakes on Linux Xenial (https://crbug.com/869781). #if defined(OS_ANDROID) #define MAYBE_NoScriptPreviewsEnabled NoScriptPreviewsEnabled #define MAYBE_NoScriptPreviewsEnabledHttpRedirectToHttps \ @@ -231,7 +234,8 @@ EXPECT_FALSE(noscript_css_requested()); } -// Flaky in all platforms except Android. See crbug.com/803626 for detail. +// Flaky in all platforms except Android. See https://crbug.com/803626 for +// detail. #if defined(OS_ANDROID) #define MAYBE_NoScriptPreviewsEnabledButNoTransformDirective \ NoScriptPreviewsEnabledButNoTransformDirective @@ -303,9 +307,9 @@ }; // Previews InfoBar (which this test triggers) does not work on Mac. -// See crbug.com/782322 for detail. -// Also occasional flakes on win7 (crbug.com/789948) and Ubuntu 16.04 -// (crbug.com/831838) +// See https://crbug.com/782322 for detail. +// Also occasional flakes on win7 (https://crbug.com/789948) and Ubuntu 16.04 +// (https://crbug.com/831838) #if defined(OS_ANDROID) #define MAYBE_NoScriptPreviewsEnabledByWhitelist \ NoScriptPreviewsEnabledByWhitelist @@ -348,8 +352,6 @@ EXPECT_FALSE(noscript_css_requested()); } -static const std::string kTestPreviewsServer = "https://litepages.test.com/"; - // This test class enables LitePageServerPreviews. class PreviewsLitePageServerBrowserTest : public PreviewsBrowserTest { public: @@ -358,16 +360,23 @@ ~PreviewsLitePageServerBrowserTest() override {} void SetUp() override { + // Set up previews server with resource handler. + previews_server_.reset( + new net::EmbeddedTestServer(net::EmbeddedTestServer::TYPE_HTTPS)); + previews_server_->RegisterRequestHandler(base::BindRepeating( + &PreviewsLitePageServerBrowserTest::HandleResourceRequest, + base::Unretained(this))); + ASSERT_TRUE(previews_server_->Start()); + std::unique_ptr<base::FeatureList> feature_list(new base::FeatureList); { // The trial and group names are dummy values. scoped_refptr<base::FieldTrial> trial = base::FieldTrialList::CreateFieldTrial("TrialName1", "GroupName1"); std::map<std::string, std::string> feature_parameters = { - {"previews_host", kTestPreviewsServer}}; - ASSERT_TRUE(base::FieldTrialParamAssociator::GetInstance() - ->AssociateFieldTrialParams("TrialName1", "GroupName1", - feature_parameters)); + {"previews_host", previews_server().spec()}}; + base::FieldTrialParamAssociator::GetInstance()->AssociateFieldTrialParams( + "TrialName1", "GroupName1", feature_parameters); feature_list->RegisterFieldTrialOverride( previews::features::kLitePageServerPreviews.name, @@ -386,25 +395,98 @@ PreviewsBrowserTest::SetUp(); } + void SetUpCommandLine(base::CommandLine* cmd) override { + PreviewsBrowserTest::SetUpCommandLine(cmd); + // Resolve all localhost subdomains to plain localhost so that Chrome's Test + // DNS resolver doesn't get upset. + cmd->AppendSwitchASCII( + "host-rules", "MAP *.localhost 127.0.0.1, MAP *.127.0.0.1 127.0.0.1"); + } + + std::unique_ptr<net::test_server::HttpResponse> HandleResourceRequest( + const net::test_server::HttpRequest& request) { + std::unique_ptr<net::test_server::BasicHttpResponse> response( + new net::test_server::BasicHttpResponse); + std::string original_url; + + // Ignore anything that's not a previews request with an unused status. + if (!PreviewsLitePageNavigationThrottle::GetOriginalURL(request.GetURL(), + &original_url)) { + response->set_code(net::HttpStatusCode::HTTP_BAD_REQUEST); + return response; + } + + std::string query_param; + int return_code = 0; + if (net::GetValueForKeyInQuery(GURL(original_url), "resp", &query_param)) + base::StringToInt(query_param, &return_code); + + switch (return_code) { + case 200: + response->set_code(net::HTTP_OK); + break; + case 307: + response->set_code(net::HTTP_TEMPORARY_REDIRECT); + response->AddCustomHeader("Location", https_lite_page_url(200).spec()); + break; + case 404: + response->set_code(net::HTTP_NOT_FOUND); + break; + case 503: + response->set_code(net::HTTP_SERVICE_UNAVAILABLE); + break; + default: + response->set_code(net::HTTP_BAD_REQUEST); + response->set_code(net::HTTP_OK); + break; + } + return std::move(response); + } + + GURL previews_server() { return previews_server_->base_url(); } + + GURL http_lite_page_url(int return_code) { + std::string query = "resp=" + base::IntToString(return_code); + GURL::Replacements replacements; + replacements.SetQuery(query.c_str(), url::Component(0, query.length())); + return http_url().ReplaceComponents(replacements); + } + + GURL https_lite_page_url(int return_code) { + std::string query = "resp=" + base::IntToString(return_code); + GURL::Replacements replacements; + replacements.SetQuery(query.c_str(), url::Component(0, query.length())); + return https_url().ReplaceComponents(replacements); + } + GURL NavigatedURL() { return browser()->tab_strip_model()->GetActiveWebContents()->GetURL(); } void VerifyPreviewLoaded() { - EXPECT_TRUE(NavigatedURL().DomainIs(GURL(kTestPreviewsServer).host())); + const GURL navigated_url = NavigatedURL(); + const GURL previews_host = previews_server(); + EXPECT_TRUE(navigated_url.DomainIs(previews_host.host()) && + navigated_url.EffectiveIntPort() == + previews_host.EffectiveIntPort()); } void VerifyPreviewNotLoaded() { - EXPECT_FALSE(NavigatedURL().DomainIs(GURL(kTestPreviewsServer).host())); + const GURL navigated_url = NavigatedURL(); + const GURL previews_host = previews_server(); + EXPECT_FALSE(navigated_url.DomainIs(previews_host.host()) && + navigated_url.EffectiveIntPort() == + previews_host.EffectiveIntPort()); } private: base::test::ScopedFeatureList scoped_feature_list_; + std::unique_ptr<net::EmbeddedTestServer> previews_server_; }; // Previews InfoBar (which these tests trigger) does not work on Mac. -// See crbug.com/782322 for detail. -// Also occasional flakes on win7 (crbug.com/789542). +// See https://crbug.com/782322 for detail. +// Also occasional flakes on win7 (https://crbug.com/789542). #if defined(OS_ANDROID) || defined(OS_LINUX) #define MAYBE_LitePagePreviewsTriggering LitePagePreviewsTriggering #else @@ -414,15 +496,11 @@ IN_PROC_BROWSER_TEST_F(PreviewsLitePageServerBrowserTest, MAYBE_LitePagePreviewsTriggering) { // Verify the preview is not triggered on HTTP pageloads. - ui_test_utils::NavigateToURL(browser(), http_url()); + ui_test_utils::NavigateToURL(browser(), http_lite_page_url(200)); VerifyPreviewNotLoaded(); // Verify the preview is triggered on HTTPS pageloads. - ui_test_utils::NavigateToURL(browser(), https_url()); - VerifyPreviewLoaded(); - - // Verify the preview is triggered when an HTTP page redirects to HTTPS. - ui_test_utils::NavigateToURL(browser(), redirect_url()); + ui_test_utils::NavigateToURL(browser(), https_lite_page_url(200)); VerifyPreviewLoaded(); // Verify the preview is not triggered for POST navigations. @@ -438,8 +516,8 @@ VerifyPreviewNotLoaded(); // Verify the preview is not triggered when navigating to the previews server. - ui_test_utils::NavigateToURL(browser(), GURL(kTestPreviewsServer)); - EXPECT_EQ(NavigatedURL(), GURL(kTestPreviewsServer)); + ui_test_utils::NavigateToURL(browser(), previews_server()); + EXPECT_EQ(NavigatedURL(), previews_server()); // Verify a subframe navigation does not trigger a preview. const int starting_https_url_count = https_url_count(); @@ -448,6 +526,44 @@ EXPECT_EQ(https_url_count(), starting_https_url_count + 1); } +// Previews InfoBar (which these tests trigger) does not work on Mac. +// See https://crbug.com/782322 for detail. +// Also occasional flakes on win7 (https://crbug.com/789542). +#if defined(OS_ANDROID) || defined(OS_LINUX) +#define MAYBE_LitePagePreviewsRedirect LitePagePreviewsRedirect +#else +#define MAYBE_LitePagePreviewsRedirect DISABLED_LitePagePreviewsRedirect +#endif +IN_PROC_BROWSER_TEST_F(PreviewsLitePageServerBrowserTest, + MAYBE_LitePagePreviewsRedirect) { + // Verify the preview is triggered when an HTTP page redirects to HTTPS. + ui_test_utils::NavigateToURL(browser(), redirect_url()); + VerifyPreviewLoaded(); + + // Verify the preview is triggered when an HTTPS page redirects to HTTPS. + ui_test_utils::NavigateToURL(browser(), https_lite_page_url(307)); + VerifyPreviewLoaded(); +} + +// Previews InfoBar (which these tests trigger) does not work on Mac. +// See https://crbug.com/782322 for detail. +// Also occasional flakes on win7 (https://crbug.com/789542). +#if defined(OS_ANDROID) || defined(OS_LINUX) +#define MAYBE_LitePagePreviewsResponse LitePagePreviewsResponse +#else +#define MAYBE_LitePagePreviewsResponse DISABLED_LitePagePreviewsResponse +#endif +IN_PROC_BROWSER_TEST_F(PreviewsLitePageServerBrowserTest, + MAYBE_LitePagePreviewsResponse) { + // Verify the preview is not triggered when the server responds with 404. + ui_test_utils::NavigateToURL(browser(), https_lite_page_url(404)); + VerifyPreviewNotLoaded(); + + // Verify the preview is not triggered when the server responds with 503. + ui_test_utils::NavigateToURL(browser(), https_lite_page_url(503)); + VerifyPreviewNotLoaded(); +} + class PreviewsLitePageServerDataSaverBrowserTest : public PreviewsLitePageServerBrowserTest { public: @@ -462,9 +578,17 @@ } }; +// Previews InfoBar (which these tests trigger) does not work on Mac. +// See https://crbug.com/782322 for detail. +// Also occasional flakes on win7 (https://crbug.com/789542). +#if defined(OS_ANDROID) || defined(OS_LINUX) +#define MAYBE_LitePagePreviewsDSTriggering LitePagePreviewsDSTriggering +#else +#define MAYBE_LitePagePreviewsDSTriggering DISABLED_LitePagePreviewsDSTriggering +#endif IN_PROC_BROWSER_TEST_F(PreviewsLitePageServerDataSaverBrowserTest, - MAYBE_LitePagePreviewsTriggering) { + MAYBE_LitePagePreviewsDSTriggering) { // Verify the preview is not triggered on HTTPS pageloads without DataSaver. - ui_test_utils::NavigateToURL(browser(), https_url()); + ui_test_utils::NavigateToURL(browser(), https_lite_page_url(200)); VerifyPreviewNotLoaded(); }
diff --git a/chrome/browser/previews/previews_infobar_delegate.cc b/chrome/browser/previews/previews_infobar_delegate.cc index bd2d1a8..1cfcd42 100644 --- a/chrome/browser/previews/previews_infobar_delegate.cc +++ b/chrome/browser/previews/previews_infobar_delegate.cc
@@ -17,7 +17,7 @@ #include "chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_settings.h" #include "chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_settings_factory.h" #include "chrome/browser/page_load_metrics/metrics_web_contents_observer.h" -#include "chrome/browser/previews/previews_infobar_tab_helper.h" +#include "chrome/browser/previews/previews_ui_tab_helper.h" #include "chrome/grit/generated_resources.h" #include "components/data_reduction_proxy/core/common/data_reduction_proxy_params.h" #include "components/infobars/core/infobar.h" @@ -117,20 +117,20 @@ bool is_reload, OnDismissPreviewsInfobarCallback on_dismiss_callback, previews::PreviewsUIService* previews_ui_service) { - PreviewsInfoBarTabHelper* infobar_tab_helper = - PreviewsInfoBarTabHelper::FromWebContents(web_contents); + PreviewsUITabHelper* ui_tab_helper = + PreviewsUITabHelper::FromWebContents(web_contents); InfoBarService* infobar_service = InfoBarService::FromWebContents(web_contents); // The WebContents may not have TabHelpers set. If TabHelpers are not set, // don't show Previews infobars. - if (!infobar_tab_helper || !infobar_service) + if (!ui_tab_helper || !infobar_service) return; - if (infobar_tab_helper->displayed_preview_infobar()) + if (ui_tab_helper->displayed_preview_ui()) return; std::unique_ptr<PreviewsInfoBarDelegate> delegate(new PreviewsInfoBarDelegate( - infobar_tab_helper, previews_type, previews_freshness, is_data_saver_user, + ui_tab_helper, previews_type, previews_freshness, is_data_saver_user, is_reload, std::move(on_dismiss_callback))); #if defined(OS_ANDROID) @@ -142,8 +142,8 @@ #endif infobar_service->AddInfoBar(std::move(infobar_ptr)); - uint64_t page_id = (infobar_tab_helper->previews_user_data()) - ? infobar_tab_helper->previews_user_data()->page_id() + uint64_t page_id = (ui_tab_helper->previews_user_data()) + ? ui_tab_helper->previews_user_data()->page_id() : 0; if (previews_ui_service) { @@ -158,18 +158,18 @@ } RecordPreviewsInfoBarAction(previews_type, INFOBAR_SHOWN); - infobar_tab_helper->set_displayed_preview_infobar(true); + ui_tab_helper->set_displayed_preview_ui(true); } PreviewsInfoBarDelegate::PreviewsInfoBarDelegate( - PreviewsInfoBarTabHelper* infobar_tab_helper, + PreviewsUITabHelper* ui_tab_helper, previews::PreviewsType previews_type, base::Time previews_freshness, bool is_data_saver_user, bool is_reload, OnDismissPreviewsInfobarCallback on_dismiss_callback) : ConfirmInfoBarDelegate(), - infobar_tab_helper_(infobar_tab_helper), + ui_tab_helper_(ui_tab_helper), previews_type_(previews_type), previews_freshness_(previews_freshness), is_reload_(is_reload), @@ -285,8 +285,8 @@ if (staleness_in_minutes < min_staleness_in_minutes) { if (is_reload_) { RecordStaleness(TIMESTAMP_UPDATED_NOW_SHOWN); - if (infobar_tab_helper_) - infobar_tab_helper_->set_displayed_preview_timestamp(true); + if (ui_tab_helper_) + ui_tab_helper_->set_displayed_preview_timestamp(true); return l10n_util::GetStringUTF16( IDS_PREVIEWS_INFOBAR_TIMESTAMP_UPDATED_NOW); } @@ -299,8 +299,8 @@ } RecordStaleness(TIMESTAMP_SHOWN); - if (infobar_tab_helper_) - infobar_tab_helper_->set_displayed_preview_timestamp(true); + if (ui_tab_helper_) + ui_tab_helper_->set_displayed_preview_timestamp(true); if (staleness_in_minutes < 60) { return l10n_util::GetStringFUTF16(
diff --git a/chrome/browser/previews/previews_infobar_delegate.h b/chrome/browser/previews/previews_infobar_delegate.h index b83cf06..99f7bdb0 100644 --- a/chrome/browser/previews/previews_infobar_delegate.h +++ b/chrome/browser/previews/previews_infobar_delegate.h
@@ -11,7 +11,7 @@ #include "components/infobars/core/confirm_infobar_delegate.h" #include "components/previews/core/previews_experiments.h" -class PreviewsInfoBarTabHelper; +class PreviewsUITabHelper; namespace content { class WebContents; @@ -81,7 +81,7 @@ static const void* OptOutEventKey(); private: - PreviewsInfoBarDelegate(PreviewsInfoBarTabHelper* infobar_tab_helper, + PreviewsInfoBarDelegate(PreviewsUITabHelper* ui_tab_helper, previews::PreviewsType previews_type, base::Time previews_freshness, bool is_data_saver_user, @@ -95,7 +95,7 @@ int GetButtons() const override; bool LinkClicked(WindowOpenDisposition disposition) override; - PreviewsInfoBarTabHelper* infobar_tab_helper_; + PreviewsUITabHelper* ui_tab_helper_; previews::PreviewsType previews_type_; // The time at which the preview associated with this infobar was created. A // value of zero means that the creation time is unknown.
diff --git a/chrome/browser/previews/previews_infobar_delegate_unittest.cc b/chrome/browser/previews/previews_infobar_delegate_unittest.cc index 8e7392c..1e844ec14 100644 --- a/chrome/browser/previews/previews_infobar_delegate_unittest.cc +++ b/chrome/browser/previews/previews_infobar_delegate_unittest.cc
@@ -31,7 +31,7 @@ #include "chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_settings_factory.h" #include "chrome/browser/page_load_metrics/observers/page_load_metrics_observer_test_harness.h" #include "chrome/browser/page_load_metrics/page_load_tracker.h" -#include "chrome/browser/previews/previews_infobar_tab_helper.h" +#include "chrome/browser/previews/previews_ui_tab_helper.h" #include "chrome/grit/generated_resources.h" #include "chrome/test/base/chrome_render_view_host_test_harness.h" #include "chrome/test/base/testing_browser_process.h" @@ -163,7 +163,7 @@ void SetUp() override { PageLoadMetricsObserverTestHarness::SetUp(); MockInfoBarService::CreateForWebContents(web_contents()); - PreviewsInfoBarTabHelper::CreateForWebContents(web_contents()); + PreviewsUITabHelper::CreateForWebContents(web_contents()); TestPreviewsWebContentsObserver::CreateForWebContents(web_contents()); drp_test_context_ = @@ -266,8 +266,8 @@ 1); // Dismiss the infobar. infobar_service()->RemoveAllInfoBars(false); - PreviewsInfoBarTabHelper::FromWebContents(web_contents()) - ->set_displayed_preview_infobar(false); + PreviewsUITabHelper::FromWebContents(web_contents()) + ->set_displayed_preview_ui(false); } void OnDismissPreviewsInfobar(bool user_opt_out) {
diff --git a/chrome/browser/previews/previews_infobar_tab_helper.h b/chrome/browser/previews/previews_infobar_tab_helper.h deleted file mode 100644 index ea009a7..0000000 --- a/chrome/browser/previews/previews_infobar_tab_helper.h +++ /dev/null
@@ -1,70 +0,0 @@ -// Copyright 2016 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 CHROME_BROWSER_PREVIEWS_PREVIEWS_INFOBAR_TAB_HELPER_H_ -#define CHROME_BROWSER_PREVIEWS_PREVIEWS_INFOBAR_TAB_HELPER_H_ - -#include "base/macros.h" -#include "base/optional.h" -#include "components/previews/core/previews_user_data.h" -#include "content/public/browser/web_contents_observer.h" -#include "content/public/browser/web_contents_user_data.h" - -// Tracks whether a previews infobar has been shown for a page. Handles showing -// the infobar when the main frame response indicates a Lite Page. -class PreviewsInfoBarTabHelper - : public content::WebContentsObserver, - public content::WebContentsUserData<PreviewsInfoBarTabHelper> { - public: - ~PreviewsInfoBarTabHelper() override; - - // Indicates whether the InfoBar for a preview has been shown for the page. - bool displayed_preview_infobar() const { - return displayed_preview_infobar_; - } - - // Sets whether the InfoBar for a preview has been shown for the page. - // |displayed_preview_infobar_| is reset to false on - // DidStartProvisionalLoadForFrame for the main frame. - void set_displayed_preview_infobar(bool displayed) { - displayed_preview_infobar_ = displayed; - } - - // Sets whether the timestamp on the InfoBar for a preview has been shown for - // the page. |displayed_preview_timestamp_| is reset to false on - // DidStartProvisionalLoadForFrame for the main frame. - void set_displayed_preview_timestamp(bool displayed_preview_timestamp) { - displayed_preview_timestamp_ = displayed_preview_timestamp; - } - - // The Previews information related to the navigation that was most recently - // finished. - previews::PreviewsUserData* previews_user_data() const { - return previews_user_data_.get(); - } - - private: - friend class content::WebContentsUserData<PreviewsInfoBarTabHelper>; - friend class PreviewsInfoBarTabHelperUnitTest; - - explicit PreviewsInfoBarTabHelper(content::WebContents* web_contents); - - // Overridden from content::WebContentsObserver: - void DidFinishNavigation( - content::NavigationHandle* navigation_handle) override; - - // True if the InfoBar for a preview has been shown for the page. - bool displayed_preview_infobar_; - - // True if the InfoBar with a timestamp was shown for the page. - bool displayed_preview_timestamp_; - - // The Previews information related to the navigation that was most recently - // finished. - std::unique_ptr<previews::PreviewsUserData> previews_user_data_; - - DISALLOW_COPY_AND_ASSIGN(PreviewsInfoBarTabHelper); -}; - -#endif // CHROME_BROWSER_PREVIEWS_PREVIEWS_INFOBAR_TAB_HELPER_H_
diff --git a/chrome/browser/previews/previews_lite_page_decider.cc b/chrome/browser/previews/previews_lite_page_decider.cc index 2221c75..7e79ea0 100644 --- a/chrome/browser/previews/previews_lite_page_decider.cc +++ b/chrome/browser/previews/previews_lite_page_decider.cc
@@ -5,6 +5,7 @@ #include "chrome/browser/previews/previews_lite_page_decider.h" #include "base/memory/ptr_util.h" +#include "base/time/default_tick_clock.h" #include "chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_settings.h" #include "chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_settings_factory.h" #include "chrome/browser/previews/previews_lite_page_navigation_throttle.h" @@ -17,7 +18,8 @@ #include "content/public/browser/navigation_throttle.h" #include "content/public/browser/web_contents.h" -PreviewsLitePageDecider::PreviewsLitePageDecider() = default; +PreviewsLitePageDecider::PreviewsLitePageDecider() + : clock_(base::DefaultTickClock::GetInstance()) {} PreviewsLitePageDecider::~PreviewsLitePageDecider() = default; @@ -54,6 +56,10 @@ return nullptr; } +void PreviewsLitePageDecider::SetClockForTesting(const base::TickClock* clock) { + clock_ = clock; +} + bool PreviewsLitePageDecider::IsDataSaverEnabled( content::NavigationHandle* handle) const { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); @@ -84,3 +90,34 @@ retry_at_.reset(); return server_loadshedding; } + +void PreviewsLitePageDecider::AddSingleBypass(std::string url) { + // Garbage collect any old entries while looking for the one for |url|. + auto entry = single_bypass_.end(); + for (auto iter = single_bypass_.begin(); iter != single_bypass_.end(); + /* no increment */) { + if (iter->second < clock_->NowTicks()) { + iter = single_bypass_.erase(iter); + continue; + } + if (iter->first == url) + entry = iter; + ++iter; + } + + // Update the entry for |url|. + const base::TimeTicks ttl = + clock_->NowTicks() + base::TimeDelta::FromMinutes(5); + if (entry == single_bypass_.end()) { + single_bypass_.emplace(url, ttl); + return; + } + entry->second = ttl; +} + +bool PreviewsLitePageDecider::CheckSingleBypass(std::string url) { + auto entry = single_bypass_.find(url); + if (entry == single_bypass_.end()) + return false; + return entry->second >= clock_->NowTicks(); +}
diff --git a/chrome/browser/previews/previews_lite_page_decider.h b/chrome/browser/previews/previews_lite_page_decider.h index 656898b..dc923dc 100644 --- a/chrome/browser/previews/previews_lite_page_decider.h +++ b/chrome/browser/previews/previews_lite_page_decider.h
@@ -5,13 +5,14 @@ #ifndef CHROME_BROWSER_PREVIEWS_PREVIEWS_LITE_PAGE_DECIDER_H_ #define CHROME_BROWSER_PREVIEWS_PREVIEWS_LITE_PAGE_DECIDER_H_ -#include <map> #include <memory> +#include <unordered_map> #include "base/gtest_prod_util.h" #include "base/macros.h" #include "base/optional.h" #include "base/sequence_checker.h" +#include "base/time/tick_clock.h" #include "base/time/time.h" #include "chrome/browser/previews/previews_lite_page_navigation_throttle_manager.h" @@ -35,20 +36,33 @@ static std::unique_ptr<content::NavigationThrottle> MaybeCreateThrottleFor( content::NavigationHandle* handle); + // Sets the internal clock for testing. + void SetClockForTesting(const base::TickClock* clock); + protected: // Virtual for testing. virtual bool IsDataSaverEnabled(content::NavigationHandle* handle) const; private: FRIEND_TEST_ALL_PREFIXES(PreviewsLitePageDeciderTest, TestServerUnavailable); + FRIEND_TEST_ALL_PREFIXES(PreviewsLitePageDeciderTest, TestSingleBypass); // PreviewsLitePageNavigationThrottleManager: void SetServerUnavailableUntil(base::TimeTicks retry_at) override; bool IsServerUnavailable(base::TimeTicks now) override; + void AddSingleBypass(std::string url) override; + bool CheckSingleBypass(std::string url) override; // The time after which it is ok to send the server more preview requests. base::Optional<base::TimeTicks> retry_at_; + // A map that tracks the time at which a URL will stop being bypassed. + std::unordered_map<std::string, base::TimeTicks> single_bypass_; + + // The clock used for getting the current time ticks. Use |SetClockForTesting| + // in tests. + const base::TickClock* clock_; + SEQUENCE_CHECKER(sequence_checker_); DISALLOW_COPY_AND_ASSIGN(PreviewsLitePageDecider);
diff --git a/chrome/browser/previews/previews_lite_page_decider_unittest.cc b/chrome/browser/previews/previews_lite_page_decider_unittest.cc index c9a79fc..41cbe5a 100644 --- a/chrome/browser/previews/previews_lite_page_decider_unittest.cc +++ b/chrome/browser/previews/previews_lite_page_decider_unittest.cc
@@ -7,6 +7,7 @@ #include <memory> #include "base/test/scoped_task_environment.h" +#include "base/test/simple_test_tick_clock.h" #include "testing/gtest/include/gtest/gtest.h" class PreviewsLitePageDeciderTest : public testing::Test { @@ -43,3 +44,46 @@ test_case.want_is_unavailable); } } + +TEST_F(PreviewsLitePageDeciderTest, TestSingleBypass) { + const std::string kUrl = "http://test.com"; + struct TestCase { + std::string add_url; + base::TimeDelta clock_advance; + std::string check_url; + bool want_check; + }; + const TestCase kTestCases[]{ + { + kUrl, base::TimeDelta::FromMinutes(1), kUrl, true, + }, + { + kUrl, base::TimeDelta::FromMinutes(6), kUrl, false, + }, + { + "bad", base::TimeDelta::FromMinutes(1), kUrl, false, + }, + { + "bad", base::TimeDelta::FromMinutes(6), kUrl, false, + }, + { + kUrl, base::TimeDelta::FromMinutes(1), "bad", false, + }, + { + kUrl, base::TimeDelta::FromMinutes(6), "bad", false, + }, + }; + + for (const TestCase& test_case : kTestCases) { + std::unique_ptr<PreviewsLitePageDecider> decider = + std::make_unique<PreviewsLitePageDecider>(); + std::unique_ptr<base::SimpleTestTickClock> clock = + std::make_unique<base::SimpleTestTickClock>(); + decider->SetClockForTesting(clock.get()); + + decider->AddSingleBypass(test_case.add_url); + clock->Advance(test_case.clock_advance); + EXPECT_EQ(decider->CheckSingleBypass(test_case.check_url), + test_case.want_check); + } +}
diff --git a/chrome/browser/previews/previews_lite_page_navigation_throttle.cc b/chrome/browser/previews/previews_lite_page_navigation_throttle.cc index c164e80..3fbc54e 100644 --- a/chrome/browser/previews/previews_lite_page_navigation_throttle.cc +++ b/chrome/browser/previews/previews_lite_page_navigation_throttle.cc
@@ -16,6 +16,9 @@ #include "content/public/common/referrer.h" #include "crypto/sha2.h" #include "net/base/escape.h" +#include "net/base/url_util.h" +#include "net/http/http_status_code.h" +#include "ui/base/window_open_disposition.h" #include "url/gurl.h" namespace { @@ -26,6 +29,19 @@ url.EffectiveIntPort() == previews_host.EffectiveIntPort(); } +content::OpenURLParams MakeOpenURLParams(content::NavigationHandle* handle, + GURL url) { + content::OpenURLParams url_params( + url, handle->GetReferrer(), WindowOpenDisposition::CURRENT_TAB, + handle->GetPageTransition(), handle->IsRendererInitiated()); + // TODO(crbug.com/864652): Add chrome-proxy headers if this is a Preview. + url_params.redirect_chain = handle->GetRedirectChain(); + url_params.frame_tree_node_id = handle->GetFrameTreeNodeId(); + url_params.user_gesture = handle->HasUserGesture(); + url_params.started_from_context_menu = handle->WasStartedFromContextMenu(); + return url_params; +} + } // namespace class WebContentsLifetimeHelper @@ -79,6 +95,24 @@ return true; } +// static +bool PreviewsLitePageNavigationThrottle::GetOriginalURL( + GURL url, + std::string* original_url) { + if (!url.is_valid()) + return false; + + if (!IsPreviewsDomain(url)) + return false; + + std::string original_url_query_param; + if (!net::GetValueForKeyInQuery(url, "u", &original_url_query_param)) + return false; + + *original_url = original_url_query_param; + return true; +} + GURL PreviewsLitePageNavigationThrottle::GetPreviewsURL() const { GURL original_url = navigation_handle()->GetURL(); DCHECK(original_url.is_valid()); @@ -101,23 +135,8 @@ } content::NavigationThrottle::ThrottleCheckResult -PreviewsLitePageNavigationThrottle::MaybeNavigateToPreview() const { - if (!IsEligibleForPreview()) { - return content::NavigationThrottle::PROCEED; - } - - content::OpenURLParams url_params(GetPreviewsURL(), - navigation_handle()->GetReferrer(), - WindowOpenDisposition::CURRENT_TAB, - navigation_handle()->GetPageTransition(), - navigation_handle()->IsRendererInitiated()); - // TODO(crbug.com/864652): Add chrome-proxy headers. - url_params.redirect_chain = navigation_handle()->GetRedirectChain(); - url_params.frame_tree_node_id = navigation_handle()->GetFrameTreeNodeId(); - url_params.user_gesture = navigation_handle()->HasUserGesture(); - url_params.started_from_context_menu = - navigation_handle()->WasStartedFromContextMenu(); - +PreviewsLitePageNavigationThrottle::CreateNewNavigation( + content::OpenURLParams url_params) const { // The helper class and its weak pointer protect against the WebContents // dying in-between the PostTask and its execution, resulting in a use after // free bug. Since the helper is a WebContentsUserData, it will be @@ -135,6 +154,26 @@ } content::NavigationThrottle::ThrottleCheckResult +PreviewsLitePageNavigationThrottle::TriggerPreview() const { + content::OpenURLParams url_params = + MakeOpenURLParams(navigation_handle(), GetPreviewsURL()); + return CreateNewNavigation(url_params); +} + +content::NavigationThrottle::ThrottleCheckResult +PreviewsLitePageNavigationThrottle::MaybeNavigateToPreview() const { + const GURL url = navigation_handle()->GetURL(); + if (!IsEligibleForPreview()) + return content::NavigationThrottle::PROCEED; + + // Make sure we're not trying to bypass this navigation. + if (manager_->CheckSingleBypass(url.spec())) + return content::NavigationThrottle::PROCEED; + + return TriggerPreview(); +} + +content::NavigationThrottle::ThrottleCheckResult PreviewsLitePageNavigationThrottle::WillStartRequest() { return MaybeNavigateToPreview(); } @@ -146,12 +185,50 @@ content::NavigationThrottle::ThrottleCheckResult PreviewsLitePageNavigationThrottle::WillFailRequest() { - return content::NavigationThrottle::PROCEED; + std::string original_url; + if (!GetOriginalURL(navigation_handle()->GetURL(), &original_url)) + return content::NavigationThrottle::PROCEED; + + // The Preview was triggered but there was some irrecoverable issue (like + // there is no network connection). Load the original page and let it go + // through the normal process for whatever error it is. + manager_->AddSingleBypass(original_url); + content::OpenURLParams url_params = + MakeOpenURLParams(navigation_handle(), GURL(original_url)); + + return CreateNewNavigation(url_params); } content::NavigationThrottle::ThrottleCheckResult PreviewsLitePageNavigationThrottle::WillProcessResponse() { - return content::NavigationThrottle::PROCEED; + const net::HttpResponseHeaders* response_headers = + navigation_handle()->GetResponseHeaders(); + if (!response_headers) + return content::NavigationThrottle::PROCEED; + + std::string original_url; + if (!GetOriginalURL(navigation_handle()->GetURL(), &original_url)) { + // Return early if this request was not for a Preview. + return content::NavigationThrottle::PROCEED; + } + + // After this point, the given response is known to be for a Preview. + // The Previews server will only send the following response codes: 200, 307, + // 404, and 503. 200 and 307 should proceed as normal, 404 and 503 request the + // client to load the original page instead because the server is not capable + // of generating a lite page. All other response codes are treated as a 404. + + const int response_code = response_headers->response_code(); + + if (response_code == net::HTTP_OK || + response_code == net::HTTP_TEMPORARY_REDIRECT) + return content::NavigationThrottle::PROCEED; + + manager_->AddSingleBypass(original_url); + content::OpenURLParams url_params = + MakeOpenURLParams(navigation_handle(), GURL(original_url)); + + return CreateNewNavigation(url_params); } const char* PreviewsLitePageNavigationThrottle::GetNameForLogging() {
diff --git a/chrome/browser/previews/previews_lite_page_navigation_throttle.h b/chrome/browser/previews/previews_lite_page_navigation_throttle.h index 3cc8c858..228ec04 100644 --- a/chrome/browser/previews/previews_lite_page_navigation_throttle.h +++ b/chrome/browser/previews/previews_lite_page_navigation_throttle.h
@@ -10,6 +10,10 @@ #include "content/public/browser/navigation_handle.h" #include "content/public/browser/navigation_throttle.h" +namespace content { +struct OpenURLParams; +} + // This class does the actual decision making about when to serve a Lite Page // Server Preview, and the legwork to trigger the Preview navigation. When a // Preview is triggered, it will cancel the incoming navigation and PostTask a @@ -22,6 +26,10 @@ ~PreviewsLitePageNavigationThrottle() override; + // Attempts to extract the original URL from the given Previews URL. Returns + // false if |url| is not a valid Preview URL. + static bool GetOriginalURL(GURL url, std::string* original_url); + private: FRIEND_TEST_ALL_PREFIXES(PreviewsLitePageNavigationThrottleTest, TestGetPreviewsURL); @@ -44,6 +52,19 @@ content::NavigationThrottle::ThrottleCheckResult MaybeNavigateToPreview() const; + // Can be called by any of the content::NavigationThrottle implementation + // methods to create a new navigation with the give |content::OpenURLParams|. + // Returns the |content::NavigationThrottle::ThrottleCheckResult| for the + // implemented method to return. + content::NavigationThrottle::ThrottleCheckResult CreateNewNavigation( + content::OpenURLParams url_params) const; + + // Can be called by any of the content::NavigationThrottle implementation + // methods to trigger the preview. Returns the + // |content::NavigationThrottle::ThrottleCheckResult| for the implemented + // method to return. + content::NavigationThrottle::ThrottleCheckResult TriggerPreview() const; + // content::NavigationThrottle implementation: content::NavigationThrottle::ThrottleCheckResult WillStartRequest() override; content::NavigationThrottle::ThrottleCheckResult WillRedirectRequest()
diff --git a/chrome/browser/previews/previews_lite_page_navigation_throttle_manager.h b/chrome/browser/previews/previews_lite_page_navigation_throttle_manager.h index 152abdda..8df5bb7 100644 --- a/chrome/browser/previews/previews_lite_page_navigation_throttle_manager.h +++ b/chrome/browser/previews/previews_lite_page_navigation_throttle_manager.h
@@ -21,6 +21,13 @@ // Returns true if a Preview should not be triggered because the server is // unavailable. virtual bool IsServerUnavailable(base::TimeTicks now) = 0; + + // Informs the manager that the given URL should be bypassed one time. + virtual void AddSingleBypass(std::string url) = 0; + + // Queries the manager if the given URL should be bypassed one time, returning + // true if yes. + virtual bool CheckSingleBypass(std::string url) = 0; }; #endif // CHROME_BROWSER_PREVIEWS_PREVIEWS_LITE_PAGE_NAVIGATION_THROTTLE_MANAGER_H_
diff --git a/chrome/browser/previews/previews_lite_page_navigation_throttle_unittest.cc b/chrome/browser/previews/previews_lite_page_navigation_throttle_unittest.cc index da2cf073..1fa185fe 100644 --- a/chrome/browser/previews/previews_lite_page_navigation_throttle_unittest.cc +++ b/chrome/browser/previews/previews_lite_page_navigation_throttle_unittest.cc
@@ -135,3 +135,48 @@ SimulateWillProcessResponse(); CallDidFinishNavigation(); } + +TEST_F(PreviewsLitePageNavigationThrottleTest, TestGetOriginalURL) { + struct TestCase { + std::string previews_host; + std::string original_url; + std::string previews_url; + bool want_ok; + }; + const TestCase kTestCases[]{ + // Use https://play.golang.org/p/HUM2HxmUTOW to compute |previews_url|. + { + "https://previews.host.com", + "https://original.host.com/path/path/path?query=yes", + "https://shta44dh4bi7rc6fnpjnkrtytwlabygjhk53v2trlot2wddylwua." + "previews.host.com/p?u=" + "https%3A%2F%2Foriginal.host.com%2Fpath%2Fpath%2Fpath%3Fquery%3Dyes", + true, + }, + { + "https://previews.host.com", + "http://original.host.com/path/path/path?query=yes", + "https://6p7dar4ju6r4ynz7x3pucmlcltuqsf7z5auhvckzln7voglkt56q." + "previews.host.com/p?u=" + "http%3A%2F%2Foriginal.host.com%2Fpath%2Fpath%2Fpath%3Fquery%3Dyes", + true, + }, + }; + + for (const TestCase& test_case : kTestCases) { + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitAndEnableFeatureWithParameters( + previews::features::kLitePageServerPreviews, + {{"previews_host", test_case.previews_host}}); + + std::string original_url; + bool got_ok = PreviewsLitePageNavigationThrottle::GetOriginalURL( + GURL(test_case.previews_url), &original_url); + EXPECT_EQ(got_ok, test_case.want_ok); + EXPECT_EQ(original_url, test_case.original_url); + } + + // Boilerplate navigation to keep the test harness happy. + SimulateWillProcessResponse(); + CallDidFinishNavigation(); +}
diff --git a/chrome/browser/previews/previews_infobar_tab_helper.cc b/chrome/browser/previews/previews_ui_tab_helper.cc similarity index 92% rename from chrome/browser/previews/previews_infobar_tab_helper.cc rename to chrome/browser/previews/previews_ui_tab_helper.cc index 99ccc6e..1c63309 100644 --- a/chrome/browser/previews/previews_infobar_tab_helper.cc +++ b/chrome/browser/previews/previews_ui_tab_helper.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 "chrome/browser/previews/previews_infobar_tab_helper.h" +#include "chrome/browser/previews/previews_ui_tab_helper.h" #include "base/bind.h" #include "base/bind_helpers.h" @@ -51,19 +51,18 @@ } // namespace -PreviewsInfoBarTabHelper::~PreviewsInfoBarTabHelper() {} +PreviewsUITabHelper::~PreviewsUITabHelper() {} -PreviewsInfoBarTabHelper::PreviewsInfoBarTabHelper( - content::WebContents* web_contents) +PreviewsUITabHelper::PreviewsUITabHelper(content::WebContents* web_contents) : content::WebContentsObserver(web_contents), - displayed_preview_infobar_(false), + displayed_preview_ui_(false), displayed_preview_timestamp_(false) { DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); } -void PreviewsInfoBarTabHelper::DidFinishNavigation( +void PreviewsUITabHelper::DidFinishNavigation( content::NavigationHandle* navigation_handle) { - // Only show the infobar if this is a full main frame navigation. + // Only show the ui if this is a full main frame navigation. if (!navigation_handle->IsInMainFrame() || !navigation_handle->HasCommitted() || navigation_handle->IsSameDocument()) return; @@ -78,13 +77,13 @@ uint64_t page_id = (previews_user_data_) ? previews_user_data_->page_id() : 0; - // The infobar should only be told if the page was a reload if the previous + // The ui should only be told if the page was a reload if the previous // page displayed a timestamp. bool is_reload = displayed_preview_timestamp_ ? navigation_handle->GetReloadType() != content::ReloadType::NONE : false; - displayed_preview_infobar_ = false; + displayed_preview_ui_ = false; displayed_preview_timestamp_ = false; // Retrieve PreviewsUIService* from |web_contents| if available. @@ -139,7 +138,7 @@ navigation_handle->GetRedirectChain()[0], previews::PreviewsType::OFFLINE, page_id), previews_ui_service); - // Don't try to show other infobars if this is an offline preview. + // Don't try to show other UIs if this is an offline preview. return; } #endif // BUILDFLAG(ENABLE_OFFLINE_PAGES)
diff --git a/chrome/browser/previews/previews_ui_tab_helper.h b/chrome/browser/previews/previews_ui_tab_helper.h new file mode 100644 index 0000000..2143bf9 --- /dev/null +++ b/chrome/browser/previews/previews_ui_tab_helper.h
@@ -0,0 +1,68 @@ +// Copyright 2018 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 CHROME_BROWSER_PREVIEWS_PREVIEWS_UI_TAB_HELPER_H_ +#define CHROME_BROWSER_PREVIEWS_PREVIEWS_UI_TAB_HELPER_H_ + +#include "base/macros.h" +#include "base/optional.h" +#include "components/previews/core/previews_user_data.h" +#include "content/public/browser/web_contents_observer.h" +#include "content/public/browser/web_contents_user_data.h" + +// Tracks whether a previews UI has been shown for a page. Handles showing +// the UI when the main frame response indicates a Lite Page. +class PreviewsUITabHelper + : public content::WebContentsObserver, + public content::WebContentsUserData<PreviewsUITabHelper> { + public: + ~PreviewsUITabHelper() override; + + // Indicates whether the UI for a preview has been shown for the page. + bool displayed_preview_ui() const { return displayed_preview_ui_; } + + // Sets whether the UI for a preview has been shown for the page. + // |displayed_preview_ui_| is reset to false on + // DidStartProvisionalLoadForFrame for the main frame. + void set_displayed_preview_ui(bool displayed) { + displayed_preview_ui_ = displayed; + } + + // Sets whether the timestamp on the UI for a preview has been shown for + // the page. |displayed_preview_timestamp_| is reset to false on + // DidStartProvisionalLoadForFrame for the main frame. + void set_displayed_preview_timestamp(bool displayed_preview_timestamp) { + displayed_preview_timestamp_ = displayed_preview_timestamp; + } + + // The Previews information related to the navigation that was most recently + // finished. + previews::PreviewsUserData* previews_user_data() const { + return previews_user_data_.get(); + } + + private: + friend class content::WebContentsUserData<PreviewsUITabHelper>; + friend class PreviewsUITabHelperUnitTest; + + explicit PreviewsUITabHelper(content::WebContents* web_contents); + + // Overridden from content::WebContentsObserver: + void DidFinishNavigation( + content::NavigationHandle* navigation_handle) override; + + // True if the UI for a preview has been shown for the page. + bool displayed_preview_ui_; + + // True if the UI with a timestamp was shown for the page. + bool displayed_preview_timestamp_; + + // The Previews information related to the navigation that was most recently + // finished. + std::unique_ptr<previews::PreviewsUserData> previews_user_data_; + + DISALLOW_COPY_AND_ASSIGN(PreviewsUITabHelper); +}; + +#endif // CHROME_BROWSER_PREVIEWS_PREVIEWS_UI_TAB_HELPER_H_
diff --git a/chrome/browser/previews/previews_infobar_tab_helper_unittest.cc b/chrome/browser/previews/previews_ui_tab_helper_unittest.cc similarity index 82% rename from chrome/browser/previews/previews_infobar_tab_helper_unittest.cc rename to chrome/browser/previews/previews_ui_tab_helper_unittest.cc index 4f0038f..f29381a5 100644 --- a/chrome/browser/previews/previews_infobar_tab_helper_unittest.cc +++ b/chrome/browser/previews/previews_ui_tab_helper_unittest.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 "chrome/browser/previews/previews_infobar_tab_helper.h" +#include "chrome/browser/previews/previews_ui_tab_helper.h" #include <memory> #include <string> @@ -15,7 +15,7 @@ #include "chrome/browser/loader/chrome_navigation_data.h" #include "chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_settings.h" #include "chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_settings_factory.h" -#include "chrome/browser/previews/previews_infobar_tab_helper.h" +#include "chrome/browser/previews/previews_ui_tab_helper.h" #include "chrome/test/base/chrome_render_view_host_test_harness.h" #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats.h" #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_service.h" @@ -44,17 +44,16 @@ const char kTestUrl[] = "http://www.test.com/"; } -class PreviewsInfoBarTabHelperUnitTest - : public ChromeRenderViewHostTestHarness { +class PreviewsUITabHelperUnitTest : public ChromeRenderViewHostTestHarness { protected: void SetUp() override { ChromeRenderViewHostTestHarness::SetUp(); -// Insert an OfflinePageTabHelper before PreviewsInfoBarTabHelper. +// Insert an OfflinePageTabHelper before PreviewsUITabHelper. #if BUILDFLAG(ENABLE_OFFLINE_PAGES) offline_pages::OfflinePageTabHelper::CreateForWebContents(web_contents()); #endif // BUILDFLAG(ENABLE_OFFLINE_PAGES) MockInfoBarService::CreateForWebContents(web_contents()); - PreviewsInfoBarTabHelper::CreateForWebContents(web_contents()); + PreviewsUITabHelper::CreateForWebContents(web_contents()); test_handle_ = content::NavigationHandle::CreateNavigationHandleForTesting( GURL(kTestUrl), main_rfh()); content::RenderFrameHostTester::For(main_rfh()) @@ -151,63 +150,62 @@ std::unique_ptr<content::NavigationHandle> test_handle_; }; -TEST_F(PreviewsInfoBarTabHelperUnitTest, - DidFinishNavigationCreatesLitePageInfoBar) { - PreviewsInfoBarTabHelper* infobar_tab_helper = - PreviewsInfoBarTabHelper::FromWebContents(web_contents()); - EXPECT_FALSE(infobar_tab_helper->displayed_preview_infobar()); +TEST_F(PreviewsUITabHelperUnitTest, DidFinishNavigationCreatesLitePageInfoBar) { + PreviewsUITabHelper* ui_tab_helper = + PreviewsUITabHelper::FromWebContents(web_contents()); + EXPECT_FALSE(ui_tab_helper->displayed_preview_ui()); SetCommittedPreviewsType(previews::PreviewsType::LITE_PAGE); SimulateWillProcessResponse(); CallDidFinishNavigation(); EXPECT_EQ(1U, infobar_service()->infobar_count()); - EXPECT_TRUE(infobar_tab_helper->displayed_preview_infobar()); + EXPECT_TRUE(ui_tab_helper->displayed_preview_ui()); // Navigate to reset the displayed state. content::WebContentsTester::For(web_contents()) ->NavigateAndCommit(GURL(kTestUrl)); - EXPECT_FALSE(infobar_tab_helper->displayed_preview_infobar()); + EXPECT_FALSE(ui_tab_helper->displayed_preview_ui()); } -TEST_F(PreviewsInfoBarTabHelperUnitTest, +TEST_F(PreviewsUITabHelperUnitTest, DidFinishNavigationCreatesNoScriptPreviewsInfoBar) { - PreviewsInfoBarTabHelper* infobar_tab_helper = - PreviewsInfoBarTabHelper::FromWebContents(web_contents()); - EXPECT_FALSE(infobar_tab_helper->displayed_preview_infobar()); + PreviewsUITabHelper* ui_tab_helper = + PreviewsUITabHelper::FromWebContents(web_contents()); + EXPECT_FALSE(ui_tab_helper->displayed_preview_ui()); SetCommittedPreviewsType(previews::PreviewsType::NOSCRIPT); SimulateWillProcessResponse(); CallDidFinishNavigation(); EXPECT_EQ(1U, infobar_service()->infobar_count()); - EXPECT_TRUE(infobar_tab_helper->displayed_preview_infobar()); + EXPECT_TRUE(ui_tab_helper->displayed_preview_ui()); // Navigate to reset the displayed state. content::WebContentsTester::For(web_contents()) ->NavigateAndCommit(GURL(kTestUrl)); - EXPECT_FALSE(infobar_tab_helper->displayed_preview_infobar()); + EXPECT_FALSE(ui_tab_helper->displayed_preview_ui()); } -TEST_F(PreviewsInfoBarTabHelperUnitTest, +TEST_F(PreviewsUITabHelperUnitTest, DidFinishNavigationDoesNotCreateLoFiPreviewsInfoBar) { - PreviewsInfoBarTabHelper* infobar_tab_helper = - PreviewsInfoBarTabHelper::FromWebContents(web_contents()); - EXPECT_FALSE(infobar_tab_helper->displayed_preview_infobar()); + PreviewsUITabHelper* ui_tab_helper = + PreviewsUITabHelper::FromWebContents(web_contents()); + EXPECT_FALSE(ui_tab_helper->displayed_preview_ui()); SetCommittedPreviewsType(previews::PreviewsType::LOFI); SimulateWillProcessResponse(); CallDidFinishNavigation(); EXPECT_EQ(0U, infobar_service()->infobar_count()); - EXPECT_FALSE(infobar_tab_helper->displayed_preview_infobar()); + EXPECT_FALSE(ui_tab_helper->displayed_preview_ui()); } -TEST_F(PreviewsInfoBarTabHelperUnitTest, TestPreviewsIDSet) { - PreviewsInfoBarTabHelper* infobar_tab_helper = - PreviewsInfoBarTabHelper::FromWebContents(web_contents()); +TEST_F(PreviewsUITabHelperUnitTest, TestPreviewsIDSet) { + PreviewsUITabHelper* ui_tab_helper = + PreviewsUITabHelper::FromWebContents(web_contents()); SimulateCommit(); @@ -217,21 +215,21 @@ set_previews_user_data(std::move(previews_user_data)); CallDidFinishNavigation(); - EXPECT_TRUE(infobar_tab_helper->previews_user_data()); - EXPECT_EQ(id, infobar_tab_helper->previews_user_data()->page_id()); + EXPECT_TRUE(ui_tab_helper->previews_user_data()); + EXPECT_EQ(id, ui_tab_helper->previews_user_data()->page_id()); // Navigate to reset the displayed state. content::WebContentsTester::For(web_contents()) ->NavigateAndCommit(GURL(kTestUrl)); - EXPECT_FALSE(infobar_tab_helper->previews_user_data()); + EXPECT_FALSE(ui_tab_helper->previews_user_data()); } #if BUILDFLAG(ENABLE_OFFLINE_PAGES) -TEST_F(PreviewsInfoBarTabHelperUnitTest, CreateOfflineInfoBar) { - PreviewsInfoBarTabHelper* infobar_tab_helper = - PreviewsInfoBarTabHelper::FromWebContents(web_contents()); - EXPECT_FALSE(infobar_tab_helper->displayed_preview_infobar()); +TEST_F(PreviewsUITabHelperUnitTest, CreateOfflineInfoBar) { + PreviewsUITabHelper* ui_tab_helper = + PreviewsUITabHelper::FromWebContents(web_contents()); + EXPECT_FALSE(ui_tab_helper->displayed_preview_ui()); content::WebContentsTester::For(web_contents()) ->SetMainFrameMimeType("multipart/related"); @@ -266,7 +264,7 @@ CallDidFinishNavigation(); EXPECT_EQ(1U, infobar_service()->infobar_count()); - EXPECT_TRUE(infobar_tab_helper->displayed_preview_infobar()); + EXPECT_TRUE(ui_tab_helper->displayed_preview_ui()); // Navigate to reset the displayed state. content::WebContentsTester::For(web_contents()) @@ -301,6 +299,6 @@ .find(host) ->second->original_size()); - EXPECT_FALSE(infobar_tab_helper->displayed_preview_infobar()); + EXPECT_FALSE(ui_tab_helper->displayed_preview_ui()); } #endif // BUILDFLAG(ENABLE_OFFLINE_PAGES)
diff --git a/chrome/browser/printing/print_preview_dialog_controller_browsertest.cc b/chrome/browser/printing/print_preview_dialog_controller_browsertest.cc index db1126fc..3c4afe7 100644 --- a/chrome/browser/printing/print_preview_dialog_controller_browsertest.cc +++ b/chrome/browser/printing/print_preview_dialog_controller_browsertest.cc
@@ -129,7 +129,7 @@ } bool GetPdfPluginInfo(content::WebPluginInfo* info) { - base::FilePath pdf_plugin_path = base::FilePath::FromUTF8Unsafe( + static const base::FilePath pdf_plugin_path( ChromeContentClient::kPDFPluginPath); return content::PluginService::GetInstance()->GetPluginInfoByPath( pdf_plugin_path, info);
diff --git a/chrome/browser/printing/print_view_manager.cc b/chrome/browser/printing/print_view_manager.cc index 3ca5056..64ba0f74 100644 --- a/chrome/browser/printing/print_view_manager.cc +++ b/chrome/browser/printing/print_view_manager.cc
@@ -5,6 +5,7 @@ #include "chrome/browser/printing/print_view_manager.h" #include <map> +#include <memory> #include <utility> #include "base/bind.h" @@ -37,17 +38,16 @@ void EnableInternalPDFPluginForContents(int render_process_id, int render_frame_id) { // Always enable the internal PDF plugin for the print preview page. - base::FilePath pdf_plugin_path = base::FilePath::FromUTF8Unsafe( + static const base::FilePath pdf_plugin_path( ChromeContentClient::kPDFPluginPath); - - content::WebPluginInfo pdf_plugin; - if (!content::PluginService::GetInstance()->GetPluginInfoByPath( - pdf_plugin_path, &pdf_plugin)) { + auto* plugin_service = content::PluginService::GetInstance(); + const content::PepperPluginInfo* info = + plugin_service->GetRegisteredPpapiPluginInfo(pdf_plugin_path); + if (!info) return; - } ChromePluginServiceFilter::GetInstance()->OverridePluginForFrame( - render_process_id, render_frame_id, GURL(), pdf_plugin); + render_process_id, render_frame_id, info->ToWebPluginInfo()); } } // namespace
diff --git a/chrome/browser/profiles/profile_impl_io_data.cc b/chrome/browser/profiles/profile_impl_io_data.cc index 9b5d03b..7998a03 100644 --- a/chrome/browser/profiles/profile_impl_io_data.cc +++ b/chrome/browser/profiles/profile_impl_io_data.cc
@@ -82,6 +82,7 @@ #include "net/url_request/url_request_context_builder.h" #include "net/url_request/url_request_intercepting_job_factory.h" #include "net/url_request/url_request_job_factory_impl.h" +#include "services/network/public/cpp/features.h" #include "services/network/public/cpp/shared_url_loader_factory.h" #include "services/network/public/mojom/network_service.mojom.h" #include "storage/browser/quota/special_storage_policy.h" @@ -247,7 +248,11 @@ DataReductionProxyChromeSettingsFactory::GetForBrowserContext(profile_) ->InitDataReductionProxySettings( io_data_->data_reduction_proxy_io_data(), profile_->GetPrefs(), - main_request_context_getter_.get(), + // TODO(crbug.com/721403) Switch DRP to mojo. For now it is disabled + // with network service. + base::FeatureList::IsEnabled(network::features::kNetworkService) + ? nullptr + : main_request_context_getter_.get(), content::BrowserContext::GetDefaultStoragePartition(profile_) ->GetURLLoaderFactoryForBrowserProcess(), std::move(store),
diff --git a/chrome/browser/profiles/profile_io_data.cc b/chrome/browser/profiles/profile_io_data.cc index 65dc6d3a..3bf4c0fd 100644 --- a/chrome/browser/profiles/profile_io_data.cc +++ b/chrome/browser/profiles/profile_io_data.cc
@@ -204,6 +204,11 @@ return g_cert_verifier_for_profile_io_data_testing->Verify( params, crl_set, verify_result, std::move(callback), out_req, net_log); } + void SetConfig(const Config& config) override { + if (!g_cert_verifier_for_profile_io_data_testing) + return; + return g_cert_verifier_for_profile_io_data_testing->SetConfig(config); + } }; #if BUILDFLAG(DEBUG_DEVTOOLS)
diff --git a/chrome/browser/resource_coordinator/render_process_probe.cc b/chrome/browser/resource_coordinator/render_process_probe.cc index 1a77413..270b212 100644 --- a/chrome/browser/resource_coordinator/render_process_probe.cc +++ b/chrome/browser/resource_coordinator/render_process_probe.cc
@@ -186,10 +186,6 @@ UMA_HISTOGRAM_COUNTS_1000("ResourceCoordinator.Measurement.TotalProcesses", batch->measurements.size()); - // TODO(siggi): Because memory dump requests may be combined with earlier, - // in-progress requests, this is an upper bound for the start time. - // It would be more accurate to get the start time from the memory dump - // and use the minimum of the two here. batch->batch_started_time = collection_start_time; batch->batch_ended_time = base::TimeTicks::Now();
diff --git a/chrome/browser/resources/chromeos/arc_support/recommend_app_list_view.css b/chrome/browser/resources/chromeos/arc_support/recommend_app_list_view.css index 612c5e4c..b2b61b8 100644 --- a/chrome/browser/resources/chromeos/arc_support/recommend_app_list_view.css +++ b/chrome/browser/resources/chromeos/arc_support/recommend_app_list_view.css
@@ -36,6 +36,7 @@ #recommend-apps-container .item { float: left; position: relative; + user-select: none; } #recommend-apps-container .item:not(:nth-child(3n)) {
diff --git a/chrome/browser/resources/chromeos/multidevice_setup/fake_mojo_service.js b/chrome/browser/resources/chromeos/multidevice_setup/fake_mojo_service.js index 1b6aa47..48e3eaa4 100644 --- a/chrome/browser/resources/chromeos/multidevice_setup/fake_mojo_service.js +++ b/chrome/browser/resources/chromeos/multidevice_setup/fake_mojo_service.js
@@ -21,10 +21,22 @@ } /** @override */ - setAccountStatusChangeDelegate(delegate) {} + setAccountStatusChangeDelegate(delegate) { + // Unimplemented; never called from setup flow. + assertNotReached(); + } /** @override */ - addHostStatusObserver(observer) {} + addHostStatusObserver(observer) { + // Unimplemented; never called from setup flow. + assertNotReached(); + } + + /** @override */ + addFeatureStateObserver(observer) { + // Unimplemented; never called from setup flow. + assertNotReached(); + } /** @override */ getEligibleHostDevices() { @@ -67,6 +79,20 @@ } /** @override */ + setFeatureEnabledState() { + return new Promise((resolve, reject) => { + reject('Unimplemented; never called from setup flow.'); + }); + } + + /** @override */ + getFeatureStates() { + return new Promise((resolve, reject) => { + reject('Unimplemented; never called from setup flow.'); + }); + } + + /** @override */ retrySetHostNow() { return new Promise((resolve, reject) => { reject('Unimplemented; never called from setup flow.');
diff --git a/chrome/browser/resources/local_ntp/custom_backgrounds.js b/chrome/browser/resources/local_ntp/custom_backgrounds.js index 20c56886..3506f9d 100644 --- a/chrome/browser/resources/local_ntp/custom_backgrounds.js +++ b/chrome/browser/resources/local_ntp/custom_backgrounds.js
@@ -116,6 +116,7 @@ HAS_LINK: 'has-link', HIDE_MSG_BOX: 'message-box-hide', IMAGE_DIALOG: 'is-img-sel', + OPTION: 'bg-option', OPTION_DISABLED: 'bg-option-disabled', // The menu option is disabled. PLUS_ICON: 'plus-icon', MOUSE_NAV: 'using-mouse-nav', @@ -780,21 +781,26 @@ editDialog.classList.add(customBackgrounds.CLASSES.MOUSE_NAV); editBackgroundInteraction(); }; + + // Find the first menu option that is not hidden or disabled. + let findFirstMenuOption = () => { + for (let i = 1; i < editDialog.children.length; i++) { + let option = editDialog.children[i]; + if (option.classList.contains(customBackgrounds.CLASSES.OPTION) + && !option.hidden && !option.classList.contains( + customBackgrounds.CLASSES.OPTION_DISABLED)) { + option.focus(); + return; + } + } + }; + $(customBackgrounds.IDS.EDIT_BG).onkeyup = function(event) { if (event.keyCode === customBackgrounds.KEYCODES.ENTER || event.keyCode === customBackgrounds.KEYCODES.SPACE) { editDialog.classList.remove(customBackgrounds.CLASSES.MOUSE_NAV); editBackgroundInteraction(); - // Find the first menu option that is not hidden or disabled. - for (let i = 1; i < editDialog.children.length; i++) { - let option = editDialog.children[i]; - if (!option.hidden && - !option.classList.contains( - customBackgrounds.CLASSES.OPTION_DISABLED)) { - option.focus(); - return; - } - } + findFirstMenuOption(); } }; @@ -816,6 +822,15 @@ if (event.keyCode === customBackgrounds.KEYCODES.ESC) { editDialogInteraction(); } + // When using tab in mouse navigation mode, select the first option available. + else if (editDialog.classList.contains(customBackgrounds.CLASSES.MOUSE_NAV) + && (event.keyCode === customBackgrounds.KEYCODES.TAB || event.keyCode + === customBackgrounds.KEYCODES.UP || event.keyCode + === customBackgrounds.KEYCODES.DOWN)) { + event.preventDefault(); + findFirstMenuOption(); + editDialog.classList.remove(customBackgrounds.CLASSES.MOUSE_NAV); + } // If keyboard navigation is attempted, remove mouse-only mode. else if ( event.keyCode === customBackgrounds.KEYCODES.TAB ||
diff --git a/chrome/browser/resources/local_ntp/custom_links_edit.html b/chrome/browser/resources/local_ntp/custom_links_edit.html index 208ebe0b..ee8874e 100644 --- a/chrome/browser/resources/local_ntp/custom_links_edit.html +++ b/chrome/browser/resources/local_ntp/custom_links_edit.html
@@ -31,9 +31,9 @@ <div id="invalid-url" class="error-msg"></div> </div> <div class="buttons-container"> - <button id="delete" class="secondary" tabindex="0"></button> + <button id="delete" class="secondary" type="button" tabindex="0"></button> <span class="right"> - <button id="cancel" class="secondary" tabindex="0"></button> + <button id="cancel" class="secondary" type="button" tabindex="0"></button> <button type="submit" id="done" class="primary" tabindex="0"></button> </span> </div>
diff --git a/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_runner_win.cc b/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_runner_win.cc index 88f97432..6d075083 100644 --- a/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_runner_win.cc +++ b/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_runner_win.cc
@@ -150,6 +150,9 @@ ChromeCleanerRunner::ProcessStatus ChromeCleanerRunner::LaunchAndWaitForExitOnBackgroundThread() { + TRACE_EVENT0("safe_browsing", + "ChromeCleanerRunner::LaunchAndWaitForExitOnBackgroundThread"); + mojo::OutgoingInvitation invitation; std::string pipe_name = base::NumberToString(base::RandUint64()); mojo::ScopedMessagePipeHandle request_pipe =
diff --git a/chrome/browser/safe_browsing/chrome_cleaner/reporter_runner_win.cc b/chrome/browser/safe_browsing/chrome_cleaner/reporter_runner_win.cc index 9bd69e99..9af73ec 100644 --- a/chrome/browser/safe_browsing/chrome_cleaner/reporter_runner_win.cc +++ b/chrome/browser/safe_browsing/chrome_cleaner/reporter_runner_win.cc
@@ -486,6 +486,8 @@ // external that could be shut down beforehand. int LaunchAndWaitForExitOnBackgroundThread( const SwReporterInvocation& invocation) { + TRACE_EVENT0("safe_browsing", + "ReporterRunner::LaunchAndWaitForExitOnBackgroundThread"); if (g_testing_delegate_) return g_testing_delegate_->LaunchReporter(invocation);
diff --git a/chrome/browser/ssl/certificate_error_report.cc b/chrome/browser/ssl/certificate_error_report.cc index 2942cf64..2d8e6d6f 100644 --- a/chrome/browser/ssl/certificate_error_report.cc +++ b/chrome/browser/ssl/certificate_error_report.cc
@@ -75,18 +75,24 @@ } void AddVerifyFlagsToReport( - int verify_flags, + const net::CertVerifier::Config& config, ::google::protobuf::RepeatedField<int>* report_flags) { -#define COPY_VERIFY_FLAGS(flag) \ - if (verify_flags & net::CertVerifier::VERIFY_##flag) \ - report_flags->Add(chrome_browser_ssl::TrialVerificationInfo::VERIFY_##flag); - - COPY_VERIFY_FLAGS(REV_CHECKING_ENABLED); - COPY_VERIFY_FLAGS(REV_CHECKING_REQUIRED_LOCAL_ANCHORS); - COPY_VERIFY_FLAGS(ENABLE_SHA1_LOCAL_ANCHORS); - COPY_VERIFY_FLAGS(DISABLE_SYMANTEC_ENFORCEMENT); - -#undef COPY_VERIFY_FLAGS + if (config.enable_rev_checking) { + report_flags->Add( + chrome_browser_ssl::TrialVerificationInfo::VERIFY_REV_CHECKING_ENABLED); + } + if (config.require_rev_checking_local_anchors) { + report_flags->Add(chrome_browser_ssl::TrialVerificationInfo:: + VERIFY_REV_CHECKING_REQUIRED_LOCAL_ANCHORS); + } + if (config.enable_sha1_local_anchors) { + report_flags->Add(chrome_browser_ssl::TrialVerificationInfo:: + VERIFY_ENABLE_SHA1_LOCAL_ANCHORS); + } + if (config.disable_symantec_enforcement) { + report_flags->Add(chrome_browser_ssl::TrialVerificationInfo:: + VERIFY_DISABLE_SYMANTEC_ENFORCEMENT); + } } bool CertificateChainToString(const net::X509Certificate& cert, @@ -117,7 +123,7 @@ CertificateErrorReport::CertificateErrorReport( const std::string& hostname, const net::X509Certificate& unverified_cert, - int verify_flags, + const net::CertVerifier::Config& verifier_config, const net::CertVerifyResult& primary_result, const net::CertVerifyResult& trial_result) : CertificateErrorReport(hostname, @@ -139,7 +145,7 @@ trial_report->mutable_cert_error()); AddCertStatusToReportStatus(trial_result.cert_status, trial_report->mutable_cert_status()); - AddVerifyFlagsToReport(verify_flags, trial_report->mutable_verify_flags()); + AddVerifyFlagsToReport(verifier_config, trial_report->mutable_verify_flags()); } CertificateErrorReport::~CertificateErrorReport() {}
diff --git a/chrome/browser/ssl/certificate_error_report.h b/chrome/browser/ssl/certificate_error_report.h index e163e839..ab66e3a 100644 --- a/chrome/browser/ssl/certificate_error_report.h +++ b/chrome/browser/ssl/certificate_error_report.h
@@ -11,6 +11,7 @@ #include "chrome/browser/ssl/cert_logger.pb.h" #include "components/version_info/version_info.h" #include "net/cert/cert_status_flags.h" +#include "net/cert/cert_verifier.h" namespace base { class Time; @@ -62,7 +63,7 @@ // TODO(mattm): remove this when the trial is done. (https://crbug.com/649026) CertificateErrorReport(const std::string& hostname, const net::X509Certificate& unverified_cert, - int verify_flags, + const net::CertVerifier::Config& config, const net::CertVerifyResult& primary_result, const net::CertVerifyResult& trial_result);
diff --git a/chrome/browser/ssl/common_name_mismatch_handler.cc b/chrome/browser/ssl/common_name_mismatch_handler.cc index 2435d25..37db7700 100644 --- a/chrome/browser/ssl/common_name_mismatch_handler.cc +++ b/chrome/browser/ssl/common_name_mismatch_handler.cc
@@ -75,7 +75,7 @@ })"); auto resource_request = std::make_unique<network::ResourceRequest>(); - // Can't safely use net::LOAD_DISABLE_CERT_REVOCATION_CHECKING here, + // Can't safely use net::LOAD_DISABLE_CERT_NETWORK_FETCHES here, // since then the connection may be reused without checking the cert. resource_request->url = check_url_; resource_request->method = "HEAD";
diff --git a/chrome/browser/ssl/ssl_config_service_manager_pref.cc b/chrome/browser/ssl/ssl_config_service_manager_pref.cc index f95bd9dd..bf28ee9 100644 --- a/chrome/browser/ssl/ssl_config_service_manager_pref.cc +++ b/chrome/browser/ssl/ssl_config_service_manager_pref.cc
@@ -24,6 +24,7 @@ #include "components/prefs/pref_registry_simple.h" #include "components/prefs/pref_service.h" #include "mojo/public/cpp/bindings/interface_ptr_set.h" +#include "net/cert/cert_verifier.h" #include "net/ssl/ssl_cipher_suite_names.h" #include "net/ssl/ssl_config_service.h" #include "url/url_canon.h" @@ -228,14 +229,18 @@ // static void SSLConfigServiceManagerPref::RegisterPrefs(PrefRegistrySimple* registry) { net::SSLConfig default_config; + net::CertVerifier::Config default_verifier_config; registry->RegisterBooleanPref(prefs::kCertRevocationCheckingEnabled, - default_config.rev_checking_enabled); + default_verifier_config.enable_rev_checking); registry->RegisterBooleanPref( prefs::kCertRevocationCheckingRequiredLocalAnchors, - default_config.rev_checking_required_local_anchors); - registry->RegisterBooleanPref(prefs::kCertEnableSha1LocalAnchors, false); - registry->RegisterBooleanPref(prefs::kCertEnableSymantecLegacyInfrastructure, - default_config.symantec_enforcement_disabled); + default_verifier_config.require_rev_checking_local_anchors); + registry->RegisterBooleanPref( + prefs::kCertEnableSha1LocalAnchors, + default_verifier_config.enable_sha1_local_anchors); + registry->RegisterBooleanPref( + prefs::kCertEnableSymantecLegacyInfrastructure, + default_verifier_config.disable_symantec_enforcement); registry->RegisterStringPref(prefs::kSSLVersionMin, std::string()); registry->RegisterStringPref(prefs::kSSLVersionMax, std::string()); registry->RegisterStringPref(prefs::kTLS13Variant, std::string());
diff --git a/chrome/browser/ssl/ssl_config_service_manager_pref_unittest.cc b/chrome/browser/ssl/ssl_config_service_manager_pref_unittest.cc index 74cadbc2..bbba430 100644 --- a/chrome/browser/ssl/ssl_config_service_manager_pref_unittest.cc +++ b/chrome/browser/ssl/ssl_config_service_manager_pref_unittest.cc
@@ -16,6 +16,7 @@ #include "components/prefs/testing_pref_service.h" #include "components/variations/variations_params_manager.h" #include "mojo/public/cpp/bindings/binding.h" +#include "net/cert/cert_verifier.h" #include "net/ssl/ssl_config.h" #include "services/network/public/mojom/network_service.mojom.h" #include "services/network/public/mojom/ssl_config.mojom.h" @@ -364,7 +365,7 @@ // By default, SHA-1 local trust anchors should not be enabled when not // not using any pref service. - EXPECT_FALSE(net::SSLConfig().sha1_local_anchors_enabled); + EXPECT_FALSE(net::CertVerifier::Config().enable_sha1_local_anchors); EXPECT_FALSE(network::mojom::SSLConfig::New()->sha1_local_anchors_enabled); // Using a pref service without any preference set should result in @@ -402,7 +403,7 @@ // By default, Symantec's legacy infrastructure should be disabled when // not using any pref service. - EXPECT_FALSE(net::SSLConfig().symantec_enforcement_disabled); + EXPECT_FALSE(net::CertVerifier::Config().disable_symantec_enforcement); EXPECT_FALSE(network::mojom::SSLConfig::New()->symantec_enforcement_disabled); // Using a pref service without any preference set should result in
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index 2a9ae635..cce40021 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -2836,12 +2836,20 @@ "views/bookmarks/bookmark_editor_view.cc", "views/bookmarks/bookmark_editor_view.h", "views/bubble_anchor_util_views.h", + "views/bulleted_label_list_view.cc", + "views/bulleted_label_list_view.h", "views/chrome_browser_main_extra_parts_views.cc", "views/chrome_browser_main_extra_parts_views.h", "views/chrome_constrained_window_views_client.cc", "views/chrome_constrained_window_views_client.h", + "views/chrome_layout_provider.cc", + "views/chrome_layout_provider.h", "views/chrome_platform_style.cc", "views/chrome_platform_style.h", + "views/chrome_typography.cc", + "views/chrome_typography.h", + "views/chrome_typography_provider.cc", + "views/chrome_typography_provider.h", "views/chrome_views_delegate.cc", "views/chrome_views_delegate.h", "views/collected_cookies_views.cc", @@ -2887,18 +2895,6 @@ "views/fullscreen_control/fullscreen_control_view.h", "views/global_error_bubble_view.cc", "views/global_error_bubble_view.h", - "views/harmony/bulleted_label_list_view.cc", - "views/harmony/bulleted_label_list_view.h", - "views/harmony/chrome_layout_provider.cc", - "views/harmony/chrome_layout_provider.h", - "views/harmony/chrome_typography.cc", - "views/harmony/chrome_typography.h", - "views/harmony/harmony_typography_provider.cc", - "views/harmony/harmony_typography_provider.h", - "views/harmony/material_refresh_layout_provider.cc", - "views/harmony/material_refresh_layout_provider.h", - "views/harmony/textfield_layout.cc", - "views/harmony/textfield_layout.h", "views/hover_button.cc", "views/hover_button.h", "views/importer/import_lock_dialog_view.cc", @@ -2910,6 +2906,8 @@ "views/login_handler_views.cc", "views/login_view.cc", "views/login_view.h", + "views/material_refresh_layout_provider.cc", + "views/material_refresh_layout_provider.h", "views/overlay/close_image_button.cc", "views/overlay/close_image_button.h", "views/overlay/control_image_button.cc", @@ -3011,6 +3009,8 @@ "views/sync/profile_signin_confirmation_dialog_views.h", "views/task_manager_view.cc", "views/task_manager_view.h", + "views/textfield_layout.cc", + "views/textfield_layout.h", "views/toolbar/toolbar_actions_bar_bubble_views.cc", "views/toolbar/toolbar_actions_bar_bubble_views.h", "views/touch_uma/touch_uma.cc",
diff --git a/chrome/browser/ui/ash/chrome_shell_delegate.cc b/chrome/browser/ui/ash/chrome_shell_delegate.cc index c5837ec..1a23157e 100644 --- a/chrome/browser/ui/ash/chrome_shell_delegate.cc +++ b/chrome/browser/ui/ash/chrome_shell_delegate.cc
@@ -94,7 +94,7 @@ } void ChromeShellDelegate::PreInit() { - // TODO: port to mash. http://crbug.com/678949. + // TODO: port to multi-process mash. http://crbug.com/705713. if (!features::IsAshInBrowserProcess()) return;
diff --git a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_unittest.cc b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_unittest.cc index e24c98a7..45631b6d 100644 --- a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_unittest.cc +++ b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_unittest.cc
@@ -2409,7 +2409,7 @@ GetPinnedAppStatus()); } -TEST_P(ChromeLauncherControllerWithArcTest, ArcCustomAppIcon) { +TEST_P(ChromeLauncherControllerWithArcTest, DISABLED_ArcCustomAppIcon) { InitLauncherController(); TestShelfController* shelf_controller = @@ -3530,25 +3530,25 @@ model_->GetShelfItemDelegate(gmail_id); ASSERT_TRUE(item_delegate); EXPECT_EQ(1, browser()->tab_strip_model()->active_index()); - // Execute the second item in the menu, after the title and two separators, + // Execute the second item in the menu, after the title, // this shouldn't do anything since that item is already the active tab. { ash::ShelfApplicationMenuModel menu( base::string16(), launcher_controller_->GetAppMenuItemsForTesting(item_gmail), item_delegate); - menu.ActivatedAt(4); + menu.ActivatedAt(2); } EXPECT_EQ(1, browser()->tab_strip_model()->active_index()); - // Execute the first item in the menu, after the title and two separators, + // Execute the first item in the menu, after the title, // this should activate the other tab. { ash::ShelfApplicationMenuModel menu( base::string16(), launcher_controller_->GetAppMenuItemsForTesting(item_gmail), item_delegate); - menu.ActivatedAt(3); + menu.ActivatedAt(1); } EXPECT_EQ(0, browser()->tab_strip_model()->active_index()); } @@ -3558,7 +3558,6 @@ InitLauncherControllerWithBrowser(); // Add |extension3_| to the launcher and add two items. - GURL gmail = GURL("https://mail.google.com/mail/u"); const ash::ShelfID gmail_id(extension3_->id()); extension_service_->AddExtension(extension3_.get()); launcher_controller_->SetRefocusURLPatternForTest(gmail_id, GURL(kGmailUrl));
diff --git a/chrome/browser/ui/ash/launcher/launcher_context_menu_unittest.cc b/chrome/browser/ui/ash/launcher/launcher_context_menu_unittest.cc index bf04cf6..674bb119 100644 --- a/chrome/browser/ui/ash/launcher/launcher_context_menu_unittest.cc +++ b/chrome/browser/ui/ash/launcher/launcher_context_menu_unittest.cc
@@ -17,6 +17,7 @@ #include "base/strings/utf_string_conversions.h" #include "base/test/bind_test_util.h" #include "chrome/app/chrome_command_ids.h" +#include "chrome/browser/chromeos/arc/icon_decode_request.h" #include "chrome/browser/prefs/incognito_mode_prefs.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/app_list/arc/arc_app_test.h" @@ -78,6 +79,10 @@ tablet_mode_client_ = std::make_unique<TabletModeClient>(); tablet_mode_client_->InitForTesting( fake_tablet_mode_controller_.CreateInterfacePtr()); + + // Disable safe icon decoding to ensure ArcAppShortcutRequests returns in + // the test environment. + arc::IconDecodeRequest::DisableSafeDecodingForTesting(); } std::unique_ptr<LauncherContextMenu> CreateLauncherContextMenu( @@ -346,7 +351,7 @@ } } -TEST_F(LauncherContextMenuTest, ArcLauncherSuspenedAppMenu) { +TEST_F(LauncherContextMenuTest, ArcLauncherSuspendAppMenu) { arc::mojom::AppInfo app = arc_test().fake_apps()[0]; app.suspended = true; arc_test().app_instance()->RefreshAppList(); @@ -436,7 +441,7 @@ } TEST_F(LauncherContextMenuTest, ArcContextMenuOptions) { - // Tests that there are 4 ARC app context menu options. If you're + // Tests that there are 8 ARC app context menu options. If you're // adding a context menu option ensure that you have added the enum to // tools/metrics/enums.xml and that you haven't modified the order of the // existing enums. @@ -457,8 +462,8 @@ std::unique_ptr<ui::MenuModel> menu = GetContextMenu(item_delegate, primary_id); - // Test that there are 4 items in an ARC app context menu. - EXPECT_EQ(4, menu->GetItemCount()); + // Test that there are 8 items in an ARC app context menu. + EXPECT_EQ(8, menu->GetItemCount()); } // Tests that the context menu of internal app is correct. @@ -510,7 +515,7 @@ std::unique_ptr<ui::MenuModel> menu = GetContextMenu(item_delegate, primary_id); - const int expected_options_num = internal_app.show_in_launcher ? 4 : 2; + const int expected_options_num = internal_app.show_in_launcher ? 2 : 1; EXPECT_EQ(expected_options_num, menu->GetItemCount()); } }
diff --git a/chrome/browser/ui/ash/network/enrollment_dialog_view.cc b/chrome/browser/ui/ash/network/enrollment_dialog_view.cc index 9c6ff62..958a06b 100644 --- a/chrome/browser/ui/ash/network/enrollment_dialog_view.cc +++ b/chrome/browser/ui/ash/network/enrollment_dialog_view.cc
@@ -16,7 +16,7 @@ #include "chrome/browser/ui/browser_finder.h" #include "chrome/browser/ui/browser_navigator.h" #include "chrome/browser/ui/browser_navigator_params.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" #include "chrome/grit/generated_resources.h" #include "chromeos/login/login_state.h" #include "chromeos/network/client_cert_util.h"
diff --git a/chrome/browser/ui/hung_renderer/hung_renderer_core.cc b/chrome/browser/ui/hung_renderer/hung_renderer_core.cc index 9f721476..bc2ff477 100644 --- a/chrome/browser/ui/hung_renderer/hung_renderer_core.cc +++ b/chrome/browser/ui/hung_renderer/hung_renderer_core.cc
@@ -45,7 +45,11 @@ if (frame->GetProcess() == hung_process) return frame->GetLastCommittedURL(); } - NOTREACHED(); + + // If a frame is attempting to commit a navigation into a hung renderer + // process, then its |frame->GetProcess()| will still return the process + // hosting the previously committed navigation. In such case, the loop above + // might not find any matching frame. return GURL(); } @@ -63,9 +67,15 @@ std::copy_if(AllTabContentses().begin(), AllTabContentses().end(), std::back_inserter(result), is_hung); - // Move |hung_web_contents| to the front. + // Move |hung_web_contents| to the front. It might be missing from the + // initial |results| when it hasn't yet committed a navigation into the hung + // process. auto first = std::find(result.begin(), result.end(), hung_web_contents); - std::rotate(result.begin(), first, std::next(first)); + if (first != result.end()) + std::rotate(result.begin(), first, std::next(first)); + else + result.insert(result.begin(), hung_web_contents); + return result; } @@ -87,6 +97,8 @@ return page_title; GURL hung_url = GetURLOfAnyHungFrame(affected_web_contents, hung_process); + if (!hung_url.is_valid() || !hung_url.has_host()) + return page_title; // N.B. using just the host here is OK since this is a notification and the // user doesn't need to make a security critical decision about the page in
diff --git a/chrome/browser/ui/tab_helpers.cc b/chrome/browser/ui/tab_helpers.cc index 1934651..69dc4e6 100644 --- a/chrome/browser/ui/tab_helpers.cc +++ b/chrome/browser/ui/tab_helpers.cc
@@ -41,7 +41,7 @@ #include "chrome/browser/predictors/loading_predictor_factory.h" #include "chrome/browser/predictors/loading_predictor_tab_helper.h" #include "chrome/browser/prerender/prerender_tab_helper.h" -#include "chrome/browser/previews/previews_infobar_tab_helper.h" +#include "chrome/browser/previews/previews_ui_tab_helper.h" #include "chrome/browser/previews/resource_loading_hints/resource_loading_hints_web_contents_observer.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/resource_coordinator/tab_helper.h" @@ -240,7 +240,7 @@ web_contents, base::DefaultTickClock::GetInstance()); PrefsTabHelper::CreateForWebContents(web_contents); prerender::PrerenderTabHelper::CreateForWebContents(web_contents); - PreviewsInfoBarTabHelper::CreateForWebContents(web_contents); + PreviewsUITabHelper::CreateForWebContents(web_contents); RecentlyAudibleHelper::CreateForWebContents(web_contents); ResourceLoadingHintsWebContentsObserver::CreateForWebContents(web_contents); safe_browsing::TriggerCreator::MaybeCreateTriggersForWebContents(
diff --git a/chrome/browser/ui/views/accessibility/invert_bubble_view.cc b/chrome/browser/ui/views/accessibility/invert_bubble_view.cc index 8d0d838..10606aa 100644 --- a/chrome/browser/ui/views/accessibility/invert_bubble_view.cc +++ b/chrome/browser/ui/views/accessibility/invert_bubble_view.cc
@@ -8,11 +8,11 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_dialogs.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_typography.h" #include "chrome/browser/ui/views/frame/app_menu_button.h" #include "chrome/browser/ui/views/frame/browser_view.h" #include "chrome/browser/ui/views/frame/toolbar_button_provider.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" -#include "chrome/browser/ui/views/harmony/chrome_typography.h" #include "chrome/common/pref_names.h" #include "chrome/grit/generated_resources.h" #include "components/prefs/pref_service.h"
diff --git a/chrome/browser/ui/views/apps/app_info_dialog/app_info_dialog_views.cc b/chrome/browser/ui/views/apps/app_info_dialog/app_info_dialog_views.cc index bf323cf..8f31638 100644 --- a/chrome/browser/ui/views/apps/app_info_dialog/app_info_dialog_views.cc +++ b/chrome/browser/ui/views/apps/app_info_dialog/app_info_dialog_views.cc
@@ -18,7 +18,7 @@ #include "chrome/browser/ui/views/apps/app_info_dialog/app_info_header_panel.h" #include "chrome/browser/ui/views/apps/app_info_dialog/app_info_permissions_panel.h" #include "chrome/browser/ui/views/apps/app_info_dialog/app_info_summary_panel.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" #include "chrome/common/buildflags.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/extensions/extension_constants.h"
diff --git a/chrome/browser/ui/views/apps/app_info_dialog/app_info_footer_panel.cc b/chrome/browser/ui/views/apps/app_info_dialog/app_info_footer_panel.cc index da423e237..5212f4a 100644 --- a/chrome/browser/ui/views/apps/app_info_dialog/app_info_footer_panel.cc +++ b/chrome/browser/ui/views/apps/app_info_dialog/app_info_footer_panel.cc
@@ -6,7 +6,7 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser_dialogs.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" #include "chrome/common/extensions/extension_constants.h" #include "chrome/grit/generated_resources.h" #include "extensions/browser/extension_system.h"
diff --git a/chrome/browser/ui/views/apps/app_info_dialog/app_info_header_panel.cc b/chrome/browser/ui/views/apps/app_info_dialog/app_info_header_panel.cc index 7e28b7d..88086c4e 100644 --- a/chrome/browser/ui/views/apps/app_info_dialog/app_info_header_panel.cc +++ b/chrome/browser/ui/views/apps/app_info_dialog/app_info_header_panel.cc
@@ -11,7 +11,7 @@ #include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/extensions/extension_util.h" #include "chrome/browser/profiles/profile.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" #include "chrome/common/extensions/extension_constants.h" #include "chrome/grit/generated_resources.h" #include "extensions/browser/extension_system.h"
diff --git a/chrome/browser/ui/views/apps/app_info_dialog/app_info_panel.cc b/chrome/browser/ui/views/apps/app_info_dialog/app_info_panel.cc index 5c9a2b0..868bd7d 100644 --- a/chrome/browser/ui/views/apps/app_info_dialog/app_info_panel.cc +++ b/chrome/browser/ui/views/apps/app_info_dialog/app_info_panel.cc
@@ -6,7 +6,7 @@ #include "chrome/browser/ui/browser_navigator.h" #include "chrome/browser/ui/browser_navigator_params.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" #include "ui/base/resource/resource_bundle.h" #include "ui/gfx/geometry/insets.h" #include "ui/views/controls/label.h"
diff --git a/chrome/browser/ui/views/apps/app_info_dialog/app_info_permissions_panel.cc b/chrome/browser/ui/views/apps/app_info_dialog/app_info_permissions_panel.cc index 3563abd..fc13098 100644 --- a/chrome/browser/ui/views/apps/app_info_dialog/app_info_permissions_panel.cc +++ b/chrome/browser/ui/views/apps/app_info_dialog/app_info_permissions_panel.cc
@@ -13,7 +13,7 @@ #include "base/strings/string_split.h" #include "chrome/browser/apps/platform_apps/app_load_service.h" #include "chrome/browser/profiles/profile.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" #include "chrome/grit/generated_resources.h" #include "extensions/browser/api/device_permissions_manager.h" #include "extensions/browser/api/file_system/saved_file_entry.h"
diff --git a/chrome/browser/ui/views/apps/app_info_dialog/app_info_summary_panel.cc b/chrome/browser/ui/views/apps/app_info_dialog/app_info_summary_panel.cc index 76c5b19..efd6de3 100644 --- a/chrome/browser/ui/views/apps/app_info_dialog/app_info_summary_panel.cc +++ b/chrome/browser/ui/views/apps/app_info_dialog/app_info_summary_panel.cc
@@ -16,7 +16,7 @@ #include "chrome/browser/extensions/extension_util.h" #include "chrome/browser/extensions/launch_util.h" #include "chrome/browser/profiles/profile.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" #include "chrome/common/extensions/extension_constants.h" #include "chrome/grit/generated_resources.h" #include "extensions/browser/extension_prefs.h"
diff --git a/chrome/browser/ui/views/apps/app_info_dialog/arc_app_info_links_panel.cc b/chrome/browser/ui/views/apps/app_info_dialog/arc_app_info_links_panel.cc index 8ed6080..6651ddc 100644 --- a/chrome/browser/ui/views/apps/app_info_dialog/arc_app_info_links_panel.cc +++ b/chrome/browser/ui/views/apps/app_info_dialog/arc_app_info_links_panel.cc
@@ -8,7 +8,7 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/app_list/arc/arc_app_utils.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" #include "chrome/grit/generated_resources.h" #include "components/arc/common/app.mojom.h" #include "components/arc/intent_helper/arc_intent_helper_bridge.h"
diff --git a/chrome/browser/ui/views/arc_app_dialog_view.cc b/chrome/browser/ui/views/arc_app_dialog_view.cc index 399f66e..711eca4 100644 --- a/chrome/browser/ui/views/arc_app_dialog_view.cc +++ b/chrome/browser/ui/views/arc_app_dialog_view.cc
@@ -14,7 +14,7 @@ #include "chrome/browser/ui/app_list/arc/arc_app_utils.h" #include "chrome/browser/ui/app_list/arc/arc_usb_host_permission_manager.h" #include "chrome/browser/ui/browser_dialogs.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" #include "chrome/grit/generated_resources.h" #include "components/constrained_window/constrained_window_views.h" #include "components/strings/grit/components_strings.h"
diff --git a/chrome/browser/ui/views/arc_data_removal_dialog_view.cc b/chrome/browser/ui/views/arc_data_removal_dialog_view.cc index 2ccdb6e..ea21bcf 100644 --- a/chrome/browser/ui/views/arc_data_removal_dialog_view.cc +++ b/chrome/browser/ui/views/arc_data_removal_dialog_view.cc
@@ -9,7 +9,7 @@ #include "chrome/browser/ui/app_list/arc/arc_app_icon_loader.h" #include "chrome/browser/ui/app_list/arc/arc_app_utils.h" #include "chrome/browser/ui/browser_dialogs.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" #include "chrome/grit/generated_resources.h" #include "components/constrained_window/constrained_window_views.h" #include "components/strings/grit/components_strings.h"
diff --git a/chrome/browser/ui/views/autofill/autofill_popup_base_view.cc b/chrome/browser/ui/views/autofill/autofill_popup_base_view.cc index 61311a2..70cffcc 100644 --- a/chrome/browser/ui/views/autofill/autofill_popup_base_view.cc +++ b/chrome/browser/ui/views/autofill/autofill_popup_base_view.cc
@@ -12,7 +12,7 @@ #include "chrome/browser/ui/autofill/popup_view_common.h" #include "chrome/browser/ui/browser_finder.h" #include "chrome/browser/ui/browser_window.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" #include "chrome/grit/generated_resources.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/ui_features.h"
diff --git a/chrome/browser/ui/views/autofill/autofill_popup_view_native_views.cc b/chrome/browser/ui/views/autofill/autofill_popup_view_native_views.cc index 3e2e27a6..4d42dfc 100644 --- a/chrome/browser/ui/views/autofill/autofill_popup_view_native_views.cc +++ b/chrome/browser/ui/views/autofill/autofill_popup_view_native_views.cc
@@ -10,9 +10,9 @@ #include "chrome/browser/ui/autofill/autofill_popup_controller.h" #include "chrome/browser/ui/autofill/autofill_popup_layout_model.h" #include "chrome/browser/ui/autofill/popup_view_common.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" -#include "chrome/browser/ui/views/harmony/chrome_typography.h" -#include "chrome/browser/ui/views/harmony/harmony_typography_provider.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_typography.h" +#include "chrome/browser/ui/views/chrome_typography_provider.h" #include "components/autofill/core/browser/popup_item_ids.h" #include "components/autofill/core/browser/suggestion.h" #include "third_party/skia/include/core/SkColor.h"
diff --git a/chrome/browser/ui/views/autofill/card_unmask_prompt_views.cc b/chrome/browser/ui/views/autofill/card_unmask_prompt_views.cc index c4c8d1c..1e6b03fc 100644 --- a/chrome/browser/ui/views/autofill/card_unmask_prompt_views.cc +++ b/chrome/browser/ui/views/autofill/card_unmask_prompt_views.cc
@@ -12,8 +12,8 @@ #include "chrome/browser/ui/autofill/create_card_unmask_prompt_view.h" #include "chrome/browser/ui/browser_dialogs.h" #include "chrome/browser/ui/views/autofill/view_util.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" -#include "chrome/browser/ui/views/harmony/chrome_typography.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_typography.h" #include "components/autofill/core/browser/ui/card_unmask_prompt_controller.h" #include "components/constrained_window/constrained_window_views.h" #include "components/strings/grit/components_strings.h"
diff --git a/chrome/browser/ui/views/autofill/local_card_migration_bubble_views.cc b/chrome/browser/ui/views/autofill/local_card_migration_bubble_views.cc index ef4c3a7..da87d21 100644 --- a/chrome/browser/ui/views/autofill/local_card_migration_bubble_views.cc +++ b/chrome/browser/ui/views/autofill/local_card_migration_bubble_views.cc
@@ -12,8 +12,8 @@ #include "chrome/app/vector_icons/vector_icons.h" #include "chrome/browser/ui/browser_dialogs.h" #include "chrome/browser/ui/views/autofill/dialog_view_ids.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" -#include "chrome/browser/ui/views/harmony/chrome_typography.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_typography.h" #include "components/autofill/core/browser/ui/local_card_migration_bubble_controller.h" #include "components/strings/grit/components_strings.h" #include "ui/base/l10n/l10n_util.h"
diff --git a/chrome/browser/ui/views/autofill/local_card_migration_dialog_view.cc b/chrome/browser/ui/views/autofill/local_card_migration_dialog_view.cc index 2737ab9..3fbb37dc 100644 --- a/chrome/browser/ui/views/autofill/local_card_migration_dialog_view.cc +++ b/chrome/browser/ui/views/autofill/local_card_migration_dialog_view.cc
@@ -10,8 +10,8 @@ #include "chrome/browser/ui/autofill/local_card_migration_dialog_state.h" #include "chrome/browser/ui/browser_dialogs.h" #include "chrome/browser/ui/views/autofill/view_util.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" -#include "chrome/browser/ui/views/harmony/chrome_typography.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_typography.h" #include "components/autofill/core/browser/local_card_migration_manager.h" #include "components/autofill/core/browser/ui/local_card_migration_dialog_controller.h" #include "components/constrained_window/constrained_window_views.h" @@ -220,4 +220,4 @@ return new LocalCardMigrationDialogView(controller, web_contents); } -} // namespace autofill \ No newline at end of file +} // namespace autofill
diff --git a/chrome/browser/ui/views/autofill/save_card_bubble_views.cc b/chrome/browser/ui/views/autofill/save_card_bubble_views.cc index c2e55f44..23cebfd1 100644 --- a/chrome/browser/ui/views/autofill/save_card_bubble_views.cc +++ b/chrome/browser/ui/views/autofill/save_card_bubble_views.cc
@@ -9,8 +9,8 @@ #include "chrome/browser/ui/browser_dialogs.h" #include "chrome/browser/ui/views/autofill/dialog_view_ids.h" #include "chrome/browser/ui/views/autofill/view_util.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" -#include "chrome/browser/ui/views/harmony/chrome_typography.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_typography.h" #include "components/autofill/core/browser/autofill_metrics.h" #include "components/autofill/core/browser/credit_card.h" #include "components/autofill/core/browser/legal_message_line.h"
diff --git a/chrome/browser/ui/views/autofill/save_card_manage_cards_bubble_views.cc b/chrome/browser/ui/views/autofill/save_card_manage_cards_bubble_views.cc index 5d3c32ce..b1410eb 100644 --- a/chrome/browser/ui/views/autofill/save_card_manage_cards_bubble_views.cc +++ b/chrome/browser/ui/views/autofill/save_card_manage_cards_bubble_views.cc
@@ -7,7 +7,7 @@ #include "chrome/browser/signin/account_consistency_mode_manager.h" #include "chrome/browser/ui/browser_dialogs.h" #include "chrome/browser/ui/views/autofill/dialog_view_ids.h" -#include "chrome/browser/ui/views/harmony/chrome_typography.h" +#include "chrome/browser/ui/views/chrome_typography.h" #include "chrome/browser/ui/views/sync/bubble_sync_promo_view.h" #include "components/strings/grit/components_strings.h" #include "ui/base/l10n/l10n_util.h"
diff --git a/chrome/browser/ui/views/autofill/save_card_offer_bubble_views.cc b/chrome/browser/ui/views/autofill/save_card_offer_bubble_views.cc index 52f803e..83377f2 100644 --- a/chrome/browser/ui/views/autofill/save_card_offer_bubble_views.cc +++ b/chrome/browser/ui/views/autofill/save_card_offer_bubble_views.cc
@@ -9,8 +9,8 @@ #include "chrome/app/vector_icons/vector_icons.h" #include "chrome/browser/ui/browser_dialogs.h" #include "chrome/browser/ui/views/autofill/dialog_view_ids.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" -#include "chrome/browser/ui/views/harmony/chrome_typography.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_typography.h" #include "components/autofill/core/browser/autofill_experiments.h" #include "components/autofill/core/browser/autofill_metrics.h" #include "components/autofill/core/browser/credit_card.h"
diff --git a/chrome/browser/ui/views/autofill/save_card_sign_in_promo_bubble_views.cc b/chrome/browser/ui/views/autofill/save_card_sign_in_promo_bubble_views.cc index ed5d516..5cdbe83 100644 --- a/chrome/browser/ui/views/autofill/save_card_sign_in_promo_bubble_views.cc +++ b/chrome/browser/ui/views/autofill/save_card_sign_in_promo_bubble_views.cc
@@ -7,7 +7,7 @@ #include "chrome/browser/signin/account_consistency_mode_manager.h" #include "chrome/browser/ui/browser_dialogs.h" #include "chrome/browser/ui/views/autofill/dialog_view_ids.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" #include "chrome/browser/ui/views/sync/bubble_sync_promo_view.h" #include "chrome/grit/generated_resources.h" #include "components/strings/grit/components_strings.h"
diff --git a/chrome/browser/ui/views/autofill/view_util.cc b/chrome/browser/ui/views/autofill/view_util.cc index 720bb5c..d644faa 100644 --- a/chrome/browser/ui/views/autofill/view_util.cc +++ b/chrome/browser/ui/views/autofill/view_util.cc
@@ -7,7 +7,7 @@ #include <memory> #include "chrome/app/vector_icons/vector_icons.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" #include "components/strings/grit/components_strings.h" #include "ui/base/l10n/l10n_util.h" #include "ui/gfx/color_palette.h"
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc b/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc index 4bcd28a..d57bb04 100644 --- a/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc +++ b/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc
@@ -45,9 +45,9 @@ #include "chrome/browser/ui/views/bookmarks/bookmark_bar_view_observer.h" #include "chrome/browser/ui/views/bookmarks/bookmark_context_menu.h" #include "chrome/browser/ui/views/bookmarks/bookmark_menu_controller_views.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" #include "chrome/browser/ui/views/event_utils.h" #include "chrome/browser/ui/views/frame/browser_view.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" #include "chrome/browser/ui/views/location_bar/location_bar_view.h" #include "chrome/browser/ui/views/toolbar/toolbar_ink_drop_util.h" #include "chrome/common/chrome_switches.h"
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_bar_view_test.cc b/chrome/browser/ui/views/bookmarks/bookmark_bar_view_test.cc index c3e2131..65499f68 100644 --- a/chrome/browser/ui/views/bookmarks/bookmark_bar_view_test.cc +++ b/chrome/browser/ui/views/bookmarks/bookmark_bar_view_test.cc
@@ -26,7 +26,7 @@ #include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/browser/ui/views/chrome_constrained_window_views_client.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" #include "chrome/common/chrome_content_client.h" #include "chrome/test/base/interactive_test_utils.h" #include "chrome/test/base/scoped_testing_local_state.h"
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_bubble_view.cc b/chrome/browser/ui/views/bookmarks/bookmark_bubble_view.cc index b6142098..de2c07e 100644 --- a/chrome/browser/ui/views/bookmarks/bookmark_bubble_view.cc +++ b/chrome/browser/ui/views/bookmarks/bookmark_bubble_view.cc
@@ -16,9 +16,9 @@ #include "chrome/browser/ui/bookmarks/bookmark_editor.h" #include "chrome/browser/ui/browser_dialogs.h" #include "chrome/browser/ui/sync/sync_promo_ui.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" -#include "chrome/browser/ui/views/harmony/textfield_layout.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" #include "chrome/browser/ui/views/sync/bubble_sync_promo_view.h" +#include "chrome/browser/ui/views/textfield_layout.h" #include "chrome/grit/chromium_strings.h" #include "chrome/grit/generated_resources.h" #include "components/bookmarks/browser/bookmark_model.h"
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_editor_view.cc b/chrome/browser/ui/views/bookmarks/bookmark_editor_view.cc index 85eb408..ddaf3da 100644 --- a/chrome/browser/ui/views/bookmarks/bookmark_editor_view.cc +++ b/chrome/browser/ui/views/bookmarks/bookmark_editor_view.cc
@@ -14,7 +14,7 @@ #include "chrome/browser/ui/bookmarks/bookmark_utils.h" #include "chrome/browser/ui/bookmarks/bookmark_utils_desktop.h" #include "chrome/browser/ui/browser_dialogs.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" #include "chrome/grit/generated_resources.h" #include "chrome/grit/locale_settings.h" #include "components/bookmarks/browser/bookmark_model.h"
diff --git a/chrome/browser/ui/views/harmony/bulleted_label_list_view.cc b/chrome/browser/ui/views/bulleted_label_list_view.cc similarity index 94% rename from chrome/browser/ui/views/harmony/bulleted_label_list_view.cc rename to chrome/browser/ui/views/bulleted_label_list_view.cc index b0d59a7..eb842da6 100644 --- a/chrome/browser/ui/views/harmony/bulleted_label_list_view.cc +++ b/chrome/browser/ui/views/bulleted_label_list_view.cc
@@ -2,9 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/ui/views/harmony/bulleted_label_list_view.h" +#include "chrome/browser/ui/views/bulleted_label_list_view.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" #include "ui/gfx/canvas.h" #include "ui/views/controls/label.h" #include "ui/views/layout/grid_layout.h" @@ -48,7 +48,6 @@ BulletedLabelListView::BulletedLabelListView( const std::vector<base::string16>& texts) { - views::GridLayout* layout = SetLayoutManager(std::make_unique<views::GridLayout>(this)); views::ColumnSet* columns = layout->AddColumnSet(kColumnSetId);
diff --git a/chrome/browser/ui/views/harmony/bulleted_label_list_view.h b/chrome/browser/ui/views/bulleted_label_list_view.h similarity index 71% rename from chrome/browser/ui/views/harmony/bulleted_label_list_view.h rename to chrome/browser/ui/views/bulleted_label_list_view.h index b780ae6..d80927cec 100644 --- a/chrome/browser/ui/views/harmony/bulleted_label_list_view.h +++ b/chrome/browser/ui/views/bulleted_label_list_view.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_UI_VIEWS_HARMONY_BULLETED_LABEL_LIST_VIEW_H_ -#define CHROME_BROWSER_UI_VIEWS_HARMONY_BULLETED_LABEL_LIST_VIEW_H_ +#ifndef CHROME_BROWSER_UI_VIEWS_BULLETED_LABEL_LIST_VIEW_H_ +#define CHROME_BROWSER_UI_VIEWS_BULLETED_LABEL_LIST_VIEW_H_ #include "ui/views/view.h" @@ -20,4 +20,4 @@ DISALLOW_COPY_AND_ASSIGN(BulletedLabelListView); }; -#endif // CHROME_BROWSER_UI_VIEWS_HARMONY_BULLETED_LABEL_LIST_VIEW_H_ +#endif // CHROME_BROWSER_UI_VIEWS_BULLETED_LABEL_LIST_VIEW_H_
diff --git a/chrome/browser/ui/views/certificate_selector.cc b/chrome/browser/ui/views/certificate_selector.cc index a1e2188..186116f 100644 --- a/chrome/browser/ui/views/certificate_selector.cc +++ b/chrome/browser/ui/views/certificate_selector.cc
@@ -15,7 +15,7 @@ #include "base/strings/utf_string_conversions.h" #include "build/build_config.h" #include "chrome/browser/certificate_viewer.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" #include "chrome/grit/generated_resources.h" #include "components/constrained_window/constrained_window_views.h" #include "components/guest_view/browser/guest_view_base.h"
diff --git a/chrome/browser/ui/views/chrome_browser_main_extra_parts_views.cc b/chrome/browser/ui/views/chrome_browser_main_extra_parts_views.cc index 9ce59ae..0f7ce9f 100644 --- a/chrome/browser/ui/views/chrome_browser_main_extra_parts_views.cc +++ b/chrome/browser/ui/views/chrome_browser_main_extra_parts_views.cc
@@ -9,8 +9,8 @@ #include "base/command_line.h" #include "build/build_config.h" #include "chrome/browser/ui/views/chrome_constrained_window_views_client.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" #include "chrome/browser/ui/views/chrome_views_delegate.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" #include "chrome/browser/ui/views/relaunch_notification/relaunch_notification_controller.h" #include "components/constrained_window/constrained_window_views.h" #include "services/service_manager/sandbox/switches.h"
diff --git a/chrome/browser/ui/views/chrome_cleaner_dialog_win.cc b/chrome/browser/ui/views/chrome_cleaner_dialog_win.cc index e93f7987..ac42e02 100644 --- a/chrome/browser/ui/views/chrome_cleaner_dialog_win.cc +++ b/chrome/browser/ui/views/chrome_cleaner_dialog_win.cc
@@ -9,7 +9,7 @@ #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_dialogs.h" #include "chrome/browser/ui/browser_window.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" #include "chrome/grit/chromium_strings.h" #include "chrome/grit/generated_resources.h" #include "components/constrained_window/constrained_window_views.h"
diff --git a/chrome/browser/ui/views/chrome_cleaner_reboot_dialog_win.cc b/chrome/browser/ui/views/chrome_cleaner_reboot_dialog_win.cc index 2b4728d..9971be4 100644 --- a/chrome/browser/ui/views/chrome_cleaner_reboot_dialog_win.cc +++ b/chrome/browser/ui/views/chrome_cleaner_reboot_dialog_win.cc
@@ -10,7 +10,7 @@ #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_dialogs.h" #include "chrome/browser/ui/browser_window.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" #include "chrome/grit/chromium_strings.h" #include "chrome/grit/generated_resources.h" #include "ui/base/l10n/l10n_util.h"
diff --git a/chrome/browser/ui/views/harmony/chrome_layout_provider.cc b/chrome/browser/ui/views/chrome_layout_provider.cc similarity index 96% rename from chrome/browser/ui/views/harmony/chrome_layout_provider.cc rename to chrome/browser/ui/views/chrome_layout_provider.cc index 1e14516..6ef093d 100644 --- a/chrome/browser/ui/views/harmony/chrome_layout_provider.cc +++ b/chrome/browser/ui/views/chrome_layout_provider.cc
@@ -2,13 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" #include <algorithm> #include "base/logging.h" -#include "chrome/browser/ui/views/harmony/chrome_typography.h" -#include "chrome/browser/ui/views/harmony/material_refresh_layout_provider.h" +#include "chrome/browser/ui/views/chrome_typography.h" +#include "chrome/browser/ui/views/material_refresh_layout_provider.h" #include "ui/base/material_design/material_design_controller.h" namespace {
diff --git a/chrome/browser/ui/views/harmony/chrome_layout_provider.h b/chrome/browser/ui/views/chrome_layout_provider.h similarity index 91% rename from chrome/browser/ui/views/harmony/chrome_layout_provider.h rename to chrome/browser/ui/views/chrome_layout_provider.h index b5dea54..c764573 100644 --- a/chrome/browser/ui/views/harmony/chrome_layout_provider.h +++ b/chrome/browser/ui/views/chrome_layout_provider.h
@@ -2,13 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_UI_VIEWS_HARMONY_CHROME_LAYOUT_PROVIDER_H_ -#define CHROME_BROWSER_UI_VIEWS_HARMONY_CHROME_LAYOUT_PROVIDER_H_ +#ifndef CHROME_BROWSER_UI_VIEWS_CHROME_LAYOUT_PROVIDER_H_ +#define CHROME_BROWSER_UI_VIEWS_CHROME_LAYOUT_PROVIDER_H_ #include <memory> #include "base/macros.h" -#include "chrome/browser/ui/views/harmony/harmony_typography_provider.h" +#include "chrome/browser/ui/views/chrome_typography_provider.h" #include "ui/gfx/geometry/insets.h" #include "ui/gfx/geometry/size.h" #include "ui/views/layout/grid_layout.h" @@ -94,9 +94,9 @@ virtual bool ShouldShowWindowIcon() const; private: - const HarmonyTypographyProvider typography_provider_; + const ChromeTypographyProvider typography_provider_; DISALLOW_COPY_AND_ASSIGN(ChromeLayoutProvider); }; -#endif // CHROME_BROWSER_UI_VIEWS_HARMONY_CHROME_LAYOUT_PROVIDER_H_ +#endif // CHROME_BROWSER_UI_VIEWS_CHROME_LAYOUT_PROVIDER_H_
diff --git a/chrome/browser/ui/views/harmony/chrome_typography.cc b/chrome/browser/ui/views/chrome_typography.cc similarity index 98% rename from chrome/browser/ui/views/harmony/chrome_typography.cc rename to chrome/browser/ui/views/chrome_typography.cc index 91bc489..f758552 100644 --- a/chrome/browser/ui/views/harmony/chrome_typography.cc +++ b/chrome/browser/ui/views/chrome_typography.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 "chrome/browser/ui/views/harmony/chrome_typography.h" +#include "chrome/browser/ui/views/chrome_typography.h" #include "build/build_config.h" #include "chrome/browser/ui/views/location_bar/location_bar_view.h"
diff --git a/chrome/browser/ui/views/harmony/chrome_typography.h b/chrome/browser/ui/views/chrome_typography.h similarity index 93% rename from chrome/browser/ui/views/harmony/chrome_typography.h rename to chrome/browser/ui/views/chrome_typography.h index de81fbe..b275e5c 100644 --- a/chrome/browser/ui/views/harmony/chrome_typography.h +++ b/chrome/browser/ui/views/chrome_typography.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_UI_VIEWS_HARMONY_CHROME_TYPOGRAPHY_H_ -#define CHROME_BROWSER_UI_VIEWS_HARMONY_CHROME_TYPOGRAPHY_H_ +#ifndef CHROME_BROWSER_UI_VIEWS_CHROME_TYPOGRAPHY_H_ +#define CHROME_BROWSER_UI_VIEWS_CHROME_TYPOGRAPHY_H_ #include "base/macros.h" #include "ui/gfx/font.h" @@ -86,4 +86,4 @@ int* size_delta, gfx::Font::Weight* weight); -#endif // CHROME_BROWSER_UI_VIEWS_HARMONY_CHROME_TYPOGRAPHY_H_ +#endif // CHROME_BROWSER_UI_VIEWS_CHROME_TYPOGRAPHY_H_
diff --git a/chrome/browser/ui/views/harmony/harmony_typography_provider.cc b/chrome/browser/ui/views/chrome_typography_provider.cc similarity index 93% rename from chrome/browser/ui/views/harmony/harmony_typography_provider.cc rename to chrome/browser/ui/views/chrome_typography_provider.cc index 80ffe31..98d2626 100644 --- a/chrome/browser/ui/views/harmony/harmony_typography_provider.cc +++ b/chrome/browser/ui/views/chrome_typography_provider.cc
@@ -2,9 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/ui/views/harmony/harmony_typography_provider.h" +#include "chrome/browser/ui/views/chrome_typography_provider.h" -#include "chrome/browser/ui/views/harmony/chrome_typography.h" +#include "chrome/browser/ui/views/chrome_typography.h" #include "ui/base/resource/resource_bundle.h" #include "ui/gfx/color_palette.h" #include "ui/gfx/color_utils.h" @@ -85,7 +85,7 @@ #if defined(OS_WIN) // static -int HarmonyTypographyProvider::GetPlatformFontHeight(int font_context) { +int ChromeTypographyProvider::GetPlatformFontHeight(int font_context) { const bool direct_write_enabled = gfx::PlatformFontWin::IsDirectWriteEnabled(); const bool windows_10 = base::win::GetVersion() >= base::win::VERSION_WIN10; @@ -105,8 +105,8 @@ } #endif -const gfx::FontList& HarmonyTypographyProvider::GetFont(int context, - int style) const { +const gfx::FontList& ChromeTypographyProvider::GetFont(int context, + int style) const { // "Target" font size constants from the Harmony spec. constexpr int kHeadlineSize = 20; constexpr int kTitleSize = 15; @@ -159,9 +159,9 @@ size_delta, gfx::Font::NORMAL, font_weight); } -SkColor HarmonyTypographyProvider::GetColor(const views::View& view, - int context, - int style) const { +SkColor ChromeTypographyProvider::GetColor(const views::View& view, + int context, + int style) const { const ui::NativeTheme* native_theme = view.GetNativeTheme(); DCHECK(native_theme); if (ShouldIgnoreHarmonySpec(*native_theme)) { @@ -207,7 +207,7 @@ return gfx::kGoogleGrey900; } -int HarmonyTypographyProvider::GetLineHeight(int context, int style) const { +int ChromeTypographyProvider::GetLineHeight(int context, int style) const { // "Target" line height constants from the Harmony spec. A default OS // configuration should use these heights. However, if the user overrides OS // defaults, then GetLineHeight() should return the height that would add the @@ -221,7 +221,7 @@ constexpr int kButtonAbsoluteHeight = 0; // The platform-specific heights (i.e. gfx::Font::GetHeight()) that result when -// asking for the target size constants in HarmonyTypographyProvider::GetFont() +// asking for the target size constants in ChromeTypographyProvider::GetFont() // in a default OS configuration. #if defined(OS_MACOSX) constexpr int kHeadlinePlatformHeight = 25;
diff --git a/chrome/browser/ui/views/harmony/harmony_typography_provider.h b/chrome/browser/ui/views/chrome_typography_provider.h similarity index 69% rename from chrome/browser/ui/views/harmony/harmony_typography_provider.h rename to chrome/browser/ui/views/chrome_typography_provider.h index 048935f..5354cf4f 100644 --- a/chrome/browser/ui/views/harmony/harmony_typography_provider.h +++ b/chrome/browser/ui/views/chrome_typography_provider.h
@@ -2,17 +2,17 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_UI_VIEWS_HARMONY_HARMONY_TYPOGRAPHY_PROVIDER_H_ -#define CHROME_BROWSER_UI_VIEWS_HARMONY_HARMONY_TYPOGRAPHY_PROVIDER_H_ +#ifndef CHROME_BROWSER_UI_VIEWS_CHROME_TYPOGRAPHY_PROVIDER_H_ +#define CHROME_BROWSER_UI_VIEWS_CHROME_TYPOGRAPHY_PROVIDER_H_ #include "base/macros.h" #include "build/build_config.h" #include "ui/views/style/typography_provider.h" // TypographyProvider implementing the Harmony spec. -class HarmonyTypographyProvider : public views::TypographyProvider { +class ChromeTypographyProvider : public views::TypographyProvider { public: - HarmonyTypographyProvider() = default; + ChromeTypographyProvider() = default; #if defined(OS_WIN) // Returns the expected platform font height for the current system @@ -29,7 +29,7 @@ int GetLineHeight(int context, int style) const override; private: - DISALLOW_COPY_AND_ASSIGN(HarmonyTypographyProvider); + DISALLOW_COPY_AND_ASSIGN(ChromeTypographyProvider); }; -#endif // CHROME_BROWSER_UI_VIEWS_HARMONY_HARMONY_TYPOGRAPHY_PROVIDER_H_ +#endif // CHROME_BROWSER_UI_VIEWS_CHROME_TYPOGRAPHY_PROVIDER_H_
diff --git a/chrome/browser/ui/views/collected_cookies_views.cc b/chrome/browser/ui/views/collected_cookies_views.cc index ae3f872c..13f993c3 100644 --- a/chrome/browser/ui/views/collected_cookies_views.cc +++ b/chrome/browser/ui/views/collected_cookies_views.cc
@@ -23,9 +23,9 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser_dialogs.h" #include "chrome/browser/ui/collected_cookies_infobar_delegate.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_typography.h" #include "chrome/browser/ui/views/cookie_info_view.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" -#include "chrome/browser/ui/views/harmony/chrome_typography.h" #include "chrome/common/pref_names.h" #include "chrome/grit/generated_resources.h" #include "components/constrained_window/constrained_window_views.h"
diff --git a/chrome/browser/ui/views/confirm_bubble_views.cc b/chrome/browser/ui/views/confirm_bubble_views.cc index cd34a56..873121af 100644 --- a/chrome/browser/ui/views/confirm_bubble_views.cc +++ b/chrome/browser/ui/views/confirm_bubble_views.cc
@@ -9,7 +9,7 @@ #include "chrome/browser/ui/browser_dialogs.h" #include "chrome/browser/ui/confirm_bubble.h" #include "chrome/browser/ui/confirm_bubble_model.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" #include "components/constrained_window/constrained_window_views.h" #include "components/strings/grit/components_strings.h" #include "components/vector_icons/vector_icons.h"
diff --git a/chrome/browser/ui/views/content_setting_bubble_contents.cc b/chrome/browser/ui/views/content_setting_bubble_contents.cc index 649b68e..25e4fc4 100644 --- a/chrome/browser/ui/views/content_setting_bubble_contents.cc +++ b/chrome/browser/ui/views/content_setting_bubble_contents.cc
@@ -11,9 +11,9 @@ #include "chrome/browser/plugins/plugin_finder.h" #include "chrome/browser/plugins/plugin_metadata.h" #include "chrome/browser/ui/browser_dialogs.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_typography.h" #include "chrome/browser/ui/views/content_setting_domain_list_view.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" -#include "chrome/browser/ui/views/harmony/chrome_typography.h" #include "chrome/grit/generated_resources.h" #include "components/content_settings/core/browser/host_content_settings_map.h" #include "components/strings/grit/components_strings.h"
diff --git a/chrome/browser/ui/views/content_setting_domain_list_view.cc b/chrome/browser/ui/views/content_setting_domain_list_view.cc index 1616bdc..074e34ff 100644 --- a/chrome/browser/ui/views/content_setting_domain_list_view.cc +++ b/chrome/browser/ui/views/content_setting_domain_list_view.cc
@@ -5,8 +5,8 @@ #include "chrome/browser/ui/views/content_setting_domain_list_view.h" #include "base/strings/utf_string_conversions.h" -#include "chrome/browser/ui/views/harmony/bulleted_label_list_view.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" +#include "chrome/browser/ui/views/bulleted_label_list_view.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" #include "ui/gfx/canvas.h" #include "ui/views/controls/label.h" #include "ui/views/layout/box_layout.h"
diff --git a/chrome/browser/ui/views/cookie_info_view.cc b/chrome/browser/ui/views/cookie_info_view.cc index e480dc29..37aa82f 100644 --- a/chrome/browser/ui/views/cookie_info_view.cc +++ b/chrome/browser/ui/views/cookie_info_view.cc
@@ -11,7 +11,7 @@ #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" #include "chrome/browser/browsing_data/cookies_tree_model.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" #include "chrome/grit/generated_resources.h" #include "net/cookies/canonical_cookie.h" #include "third_party/skia/include/core/SkColor.h"
diff --git a/chrome/browser/ui/views/create_application_shortcut_view.cc b/chrome/browser/ui/views/create_application_shortcut_view.cc index a825c9c..77d1448 100644 --- a/chrome/browser/ui/views/create_application_shortcut_view.cc +++ b/chrome/browser/ui/views/create_application_shortcut_view.cc
@@ -9,7 +9,7 @@ #include "build/build_config.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser_dialogs.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" #include "chrome/common/pref_names.h" #include "chrome/grit/generated_resources.h" #include "components/constrained_window/constrained_window_views.h"
diff --git a/chrome/browser/ui/views/critical_notification_bubble_view.cc b/chrome/browser/ui/views/critical_notification_bubble_view.cc index ef1c791..bb8df70 100644 --- a/chrome/browser/ui/views/critical_notification_bubble_view.cc +++ b/chrome/browser/ui/views/critical_notification_bubble_view.cc
@@ -9,7 +9,7 @@ #include "chrome/browser/browser_process.h" #include "chrome/browser/lifetime/application_lifetime.h" #include "chrome/browser/ui/browser_dialogs.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" #include "chrome/browser/upgrade_detector/upgrade_detector.h" #include "chrome/common/pref_names.h" #include "chrome/grit/chromium_strings.h"
diff --git a/chrome/browser/ui/views/crostini/crostini_installer_view.cc b/chrome/browser/ui/views/crostini/crostini_installer_view.cc index fc173789..50d4304 100644 --- a/chrome/browser/ui/views/crostini/crostini_installer_view.cc +++ b/chrome/browser/ui/views/crostini/crostini_installer_view.cc
@@ -19,7 +19,7 @@ #include "chrome/browser/chromeos/login/startup_utils.h" #include "chrome/browser/chromeos/profiles/profile_helper.h" #include "chrome/browser/ui/browser_dialogs.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" #include "chrome/common/url_constants.h" #include "chrome/grit/chrome_unscaled_resources.h" #include "chrome/grit/generated_resources.h"
diff --git a/chrome/browser/ui/views/crostini/crostini_uninstaller_view.cc b/chrome/browser/ui/views/crostini/crostini_uninstaller_view.cc index 36e00eb..2caa4ef 100644 --- a/chrome/browser/ui/views/crostini/crostini_uninstaller_view.cc +++ b/chrome/browser/ui/views/crostini/crostini_uninstaller_view.cc
@@ -10,7 +10,7 @@ #include "chrome/browser/chromeos/crostini/crostini_util.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser_dialogs.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" #include "chrome/grit/generated_resources.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/resource/resource_bundle.h"
diff --git a/chrome/browser/ui/views/crypto_module_password_dialog_view.cc b/chrome/browser/ui/views/crypto_module_password_dialog_view.cc index 8366b887b..4eb5fcc5 100644 --- a/chrome/browser/ui/views/crypto_module_password_dialog_view.cc +++ b/chrome/browser/ui/views/crypto_module_password_dialog_view.cc
@@ -6,7 +6,7 @@ #include "base/strings/utf_string_conversions.h" #include "chrome/browser/ui/browser_dialogs.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" #include "chrome/grit/generated_resources.h" #include "components/strings/grit/components_strings.h" #include "ui/base/l10n/l10n_util.h"
diff --git a/chrome/browser/ui/views/desktop_capture/desktop_media_picker_views.cc b/chrome/browser/ui/views/desktop_capture/desktop_media_picker_views.cc index b30ebb23..8fbfeb4d 100644 --- a/chrome/browser/ui/views/desktop_capture/desktop_media_picker_views.cc +++ b/chrome/browser/ui/views/desktop_capture/desktop_media_picker_views.cc
@@ -9,9 +9,9 @@ #include "chrome/browser/ui/browser_dialogs.h" #include "chrome/browser/ui/browser_finder.h" #include "chrome/browser/ui/browser_window.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" #include "chrome/browser/ui/views/desktop_capture/desktop_media_list_view.h" #include "chrome/browser/ui/views/desktop_capture/desktop_media_source_view.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" #include "chrome/grit/chromium_strings.h" #include "chrome/grit/generated_resources.h" #include "components/constrained_window/constrained_window_views.h"
diff --git a/chrome/browser/ui/views/desktop_capture/desktop_media_picker_views_unittest.cc b/chrome/browser/ui/views/desktop_capture/desktop_media_picker_views_unittest.cc index d92929e..a40a61b 100644 --- a/chrome/browser/ui/views/desktop_capture/desktop_media_picker_views_unittest.cc +++ b/chrome/browser/ui/views/desktop_capture/desktop_media_picker_views_unittest.cc
@@ -11,9 +11,9 @@ #include "base/run_loop.h" #include "base/strings/utf_string_conversions.h" #include "chrome/browser/media/webrtc/fake_desktop_media_list.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" #include "chrome/browser/ui/views/desktop_capture/desktop_media_list_view.h" #include "chrome/browser/ui/views/desktop_capture/desktop_media_source_view.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" #include "components/web_modal/test_web_contents_modal_dialog_host.h" #include "content/public/test/test_browser_thread_bundle.h" #include "testing/gmock/include/gmock/gmock.h"
diff --git a/chrome/browser/ui/views/desktop_ios_promotion/desktop_ios_promotion_bubble_view.cc b/chrome/browser/ui/views/desktop_ios_promotion/desktop_ios_promotion_bubble_view.cc index f65cbc68..0823bc7 100644 --- a/chrome/browser/ui/views/desktop_ios_promotion/desktop_ios_promotion_bubble_view.cc +++ b/chrome/browser/ui/views/desktop_ios_promotion/desktop_ios_promotion_bubble_view.cc
@@ -9,8 +9,8 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/desktop_ios_promotion/desktop_ios_promotion_bubble_controller.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" -#include "chrome/browser/ui/views/harmony/chrome_typography.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_typography.h" #include "chrome/grit/generated_resources.h" #include "chrome/grit/locale_settings.h" #include "ui/base/l10n/l10n_util.h"
diff --git a/chrome/browser/ui/views/desktop_ios_promotion/desktop_ios_promotion_footnote_view.cc b/chrome/browser/ui/views/desktop_ios_promotion/desktop_ios_promotion_footnote_view.cc index 79def83..0a22c520 100644 --- a/chrome/browser/ui/views/desktop_ios_promotion/desktop_ios_promotion_footnote_view.cc +++ b/chrome/browser/ui/views/desktop_ios_promotion/desktop_ios_promotion_footnote_view.cc
@@ -13,7 +13,7 @@ #include "chrome/browser/ui/desktop_ios_promotion/desktop_ios_promotion_controller.h" #include "chrome/browser/ui/desktop_ios_promotion/desktop_ios_promotion_footnote_delegate.h" #include "chrome/browser/ui/desktop_ios_promotion/desktop_ios_promotion_util.h" -#include "chrome/browser/ui/views/harmony/chrome_typography.h" +#include "chrome/browser/ui/views/chrome_typography.h" #include "chrome/grit/chromium_strings.h" #include "chrome/grit/generated_resources.h" #include "third_party/skia/include/core/SkColor.h"
diff --git a/chrome/browser/ui/views/device_chooser_content_view.cc b/chrome/browser/ui/views/device_chooser_content_view.cc index ce5ac8b..907d1e13 100644 --- a/chrome/browser/ui/views/device_chooser_content_view.cc +++ b/chrome/browser/ui/views/device_chooser_content_view.cc
@@ -5,7 +5,7 @@ #include "chrome/browser/ui/views/device_chooser_content_view.h" #include "base/numerics/safe_conversions.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" #include "chrome/grit/generated_resources.h" #include "components/strings/grit/components_strings.h" #include "components/vector_icons/vector_icons.h"
diff --git a/chrome/browser/ui/views/download/download_danger_prompt_views.cc b/chrome/browser/ui/views/download/download_danger_prompt_views.cc index 6490196..8187d25 100644 --- a/chrome/browser/ui/views/download/download_danger_prompt_views.cc +++ b/chrome/browser/ui/views/download/download_danger_prompt_views.cc
@@ -7,7 +7,7 @@ #include "base/compiler_specific.h" #include "chrome/browser/download/download_stats.h" #include "chrome/browser/ui/browser_dialogs.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" #include "chrome/grit/chromium_strings.h" #include "chrome/grit/generated_resources.h" #include "components/constrained_window/constrained_window_views.h"
diff --git a/chrome/browser/ui/views/download/download_in_progress_dialog_view.cc b/chrome/browser/ui/views/download/download_in_progress_dialog_view.cc index deb8e9a9..234850b5 100644 --- a/chrome/browser/ui/views/download/download_in_progress_dialog_view.cc +++ b/chrome/browser/ui/views/download/download_in_progress_dialog_view.cc
@@ -5,8 +5,8 @@ #include "chrome/browser/ui/views/download/download_in_progress_dialog_view.h" #include "chrome/browser/ui/browser_dialogs.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" -#include "chrome/browser/ui/views/harmony/chrome_typography.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_typography.h" #include "chrome/grit/chromium_strings.h" #include "chrome/grit/generated_resources.h" #include "components/constrained_window/constrained_window_views.h"
diff --git a/chrome/browser/ui/views/extensions/bookmark_app_confirmation_view.cc b/chrome/browser/ui/views/extensions/bookmark_app_confirmation_view.cc index e4b69a23..2b098c78 100644 --- a/chrome/browser/ui/views/extensions/bookmark_app_confirmation_view.cc +++ b/chrome/browser/ui/views/extensions/bookmark_app_confirmation_view.cc
@@ -13,8 +13,8 @@ #include "base/strings/string_util.h" #include "build/build_config.h" #include "chrome/browser/extensions/extension_util.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" #include "chrome/browser/ui/views/extensions/web_app_info_image_source.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" #include "chrome/common/chrome_features.h" #include "chrome/grit/generated_resources.h" #include "components/constrained_window/constrained_window_views.h"
diff --git a/chrome/browser/ui/views/extensions/chooser_dialog_view.cc b/chrome/browser/ui/views/extensions/chooser_dialog_view.cc index aa0a5d07..a491ad7f 100644 --- a/chrome/browser/ui/views/extensions/chooser_dialog_view.cc +++ b/chrome/browser/ui/views/extensions/chooser_dialog_view.cc
@@ -11,8 +11,8 @@ #include "chrome/browser/extensions/chrome_extension_chooser_dialog.h" #include "chrome/browser/extensions/device_permissions_dialog_controller.h" #include "chrome/browser/ui/browser_dialogs.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" #include "chrome/browser/ui/views/device_chooser_content_view.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" #include "components/constrained_window/constrained_window_views.h" #include "components/web_modal/web_contents_modal_dialog_manager.h" #include "content/public/browser/browser_thread.h"
diff --git a/chrome/browser/ui/views/extensions/extension_install_dialog_view.cc b/chrome/browser/ui/views/extensions/extension_install_dialog_view.cc index 7745e1a..1adb1ff 100644 --- a/chrome/browser/ui/views/extensions/extension_install_dialog_view.cc +++ b/chrome/browser/ui/views/extensions/extension_install_dialog_view.cc
@@ -16,8 +16,8 @@ #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_dialogs.h" #include "chrome/browser/ui/scoped_tabbed_browser_displayer.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" -#include "chrome/browser/ui/views/harmony/chrome_typography.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_typography.h" #include "chrome/common/extensions/extension_constants.h" #include "chrome/grit/generated_resources.h" #include "components/constrained_window/constrained_window_views.h"
diff --git a/chrome/browser/ui/views/extensions/extension_installed_bubble_view.cc b/chrome/browser/ui/views/extensions/extension_installed_bubble_view.cc index db373161..22c9df5 100644 --- a/chrome/browser/ui/views/extensions/extension_installed_bubble_view.cc +++ b/chrome/browser/ui/views/extensions/extension_installed_bubble_view.cc
@@ -23,8 +23,8 @@ #include "chrome/browser/ui/extensions/extension_installed_bubble.h" #include "chrome/browser/ui/singleton_tabs.h" #include "chrome/browser/ui/sync/bubble_sync_promo_delegate.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" #include "chrome/browser/ui/views/frame/app_menu_button.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" #include "chrome/browser/ui/views/sync/bubble_sync_promo_view.h" #include "chrome/browser/ui/views_mode_controller.h" #include "chrome/common/url_constants.h"
diff --git a/chrome/browser/ui/views/extensions/extension_uninstall_dialog_view.cc b/chrome/browser/ui/views/extensions/extension_uninstall_dialog_view.cc index 09e52fb..65b1323 100644 --- a/chrome/browser/ui/views/extensions/extension_uninstall_dialog_view.cc +++ b/chrome/browser/ui/views/extensions/extension_uninstall_dialog_view.cc
@@ -11,9 +11,9 @@ #include "build/build_config.h" #include "chrome/browser/extensions/extension_uninstall_dialog.h" #include "chrome/browser/ui/browser_dialogs.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_typography.h" #include "chrome/browser/ui/views/frame/browser_view.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" -#include "chrome/browser/ui/views/harmony/chrome_typography.h" #include "chrome/browser/ui/views/toolbar/browser_actions_container.h" #include "chrome/browser/ui/views/toolbar/toolbar_view.h" #include "chrome/grit/generated_resources.h"
diff --git a/chrome/browser/ui/views/extensions/media_galleries_dialog_views.cc b/chrome/browser/ui/views/extensions/media_galleries_dialog_views.cc index 60c9957..7e5db80 100644 --- a/chrome/browser/ui/views/extensions/media_galleries_dialog_views.cc +++ b/chrome/browser/ui/views/extensions/media_galleries_dialog_views.cc
@@ -10,8 +10,8 @@ #include "base/strings/utf_string_conversions.h" #include "build/build_config.h" #include "chrome/browser/ui/browser_dialogs.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" #include "chrome/browser/ui/views/extensions/media_gallery_checkbox_view.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" #include "chrome/browser/ui/views_mode_controller.h" #include "chrome/grit/generated_resources.h" #include "chrome/grit/locale_settings.h"
diff --git a/chrome/browser/ui/views/extensions/media_galleries_dialog_views_browsertest.cc b/chrome/browser/ui/views/extensions/media_galleries_dialog_views_browsertest.cc index bf76cf1e..1b6917f4 100644 --- a/chrome/browser/ui/views/extensions/media_galleries_dialog_views_browsertest.cc +++ b/chrome/browser/ui/views/extensions/media_galleries_dialog_views_browsertest.cc
@@ -10,9 +10,9 @@ #include "chrome/browser/media_galleries/media_galleries_dialog_controller_mock.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/test/test_browser_dialog.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" #include "chrome/browser/ui/views/extensions/media_galleries_dialog_views.h" #include "chrome/browser/ui/views/extensions/media_gallery_checkbox_view.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" #include "chrome/test/base/in_process_browser_test.h" #include "components/storage_monitor/storage_info.h" #include "content/public/browser/page_navigator.h"
diff --git a/chrome/browser/ui/views/extensions/media_gallery_checkbox_view.cc b/chrome/browser/ui/views/extensions/media_gallery_checkbox_view.cc index 0294c26..55eac5e4 100644 --- a/chrome/browser/ui/views/extensions/media_gallery_checkbox_view.cc +++ b/chrome/browser/ui/views/extensions/media_gallery_checkbox_view.cc
@@ -5,7 +5,7 @@ #include "chrome/browser/ui/views/extensions/media_gallery_checkbox_view.h" #include "chrome/browser/media_galleries/media_galleries_preferences.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" #include "third_party/skia/include/core/SkColor.h" #include "ui/gfx/geometry/insets.h" #include "ui/gfx/geometry/rect.h"
diff --git a/chrome/browser/ui/views/extensions/pwa_confirmation_view.cc b/chrome/browser/ui/views/extensions/pwa_confirmation_view.cc index 89613148e..d223f5c 100644 --- a/chrome/browser/ui/views/extensions/pwa_confirmation_view.cc +++ b/chrome/browser/ui/views/extensions/pwa_confirmation_view.cc
@@ -11,9 +11,9 @@ #include "base/strings/string16.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_typography.h" #include "chrome/browser/ui/views/extensions/web_app_info_image_source.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" -#include "chrome/browser/ui/views/harmony/chrome_typography.h" #include "chrome/grit/generated_resources.h" #include "components/constrained_window/constrained_window_views.h" #include "components/strings/grit/components_strings.h"
diff --git a/chrome/browser/ui/views/extensions/request_file_system_dialog_view.cc b/chrome/browser/ui/views/extensions/request_file_system_dialog_view.cc index 6b6b53c7..4b4dc45d 100644 --- a/chrome/browser/ui/views/extensions/request_file_system_dialog_view.cc +++ b/chrome/browser/ui/views/extensions/request_file_system_dialog_view.cc
@@ -10,8 +10,8 @@ #include "base/strings/utf_string_conversions.h" #include "base/threading/thread_task_runner_handle.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" -#include "chrome/browser/ui/views/harmony/chrome_typography.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_typography.h" #include "chrome/grit/generated_resources.h" #include "components/constrained_window/constrained_window_views.h" #include "content/public/browser/web_contents.h"
diff --git a/chrome/browser/ui/views/external_protocol_dialog.cc b/chrome/browser/ui/views/external_protocol_dialog.cc index b0310758..09f9f6d 100644 --- a/chrome/browser/ui/views/external_protocol_dialog.cc +++ b/chrome/browser/ui/views/external_protocol_dialog.cc
@@ -12,8 +12,8 @@ #include "chrome/browser/tab_contents/tab_util.h" #include "chrome/browser/ui/browser_dialogs.h" #include "chrome/browser/ui/external_protocol_dialog_delegate.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" -#include "chrome/browser/ui/views/harmony/chrome_typography.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_typography.h" #include "components/constrained_window/constrained_window_views.h" #include "content/public/browser/web_contents.h" #include "ui/base/ui_features.h"
diff --git a/chrome/browser/ui/views/find_bar_view.cc b/chrome/browser/ui/views/find_bar_view.cc index cb0abf04..2954546 100644 --- a/chrome/browser/ui/views/find_bar_view.cc +++ b/chrome/browser/ui/views/find_bar_view.cc
@@ -18,9 +18,9 @@ #include "chrome/browser/ui/find_bar/find_notification_details.h" #include "chrome/browser/ui/find_bar/find_tab_helper.h" #include "chrome/browser/ui/view_ids.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" #include "chrome/browser/ui/views/find_bar_host.h" #include "chrome/browser/ui/views/frame/browser_view.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" #include "chrome/grit/generated_resources.h" #include "components/strings/grit/components_strings.h" #include "components/vector_icons/vector_icons.h"
diff --git a/chrome/browser/ui/views/first_run_dialog.cc b/chrome/browser/ui/views/first_run_dialog.cc index 6f435dd..2f6ba063 100644 --- a/chrome/browser/ui/views/first_run_dialog.cc +++ b/chrome/browser/ui/views/first_run_dialog.cc
@@ -13,7 +13,7 @@ #include "chrome/browser/platform_util.h" #include "chrome/browser/shell_integration.h" #include "chrome/browser/ui/browser_dialogs.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" #include "chrome/common/url_constants.h" #include "chrome/grit/chromium_strings.h" #include "chrome/grit/generated_resources.h"
diff --git a/chrome/browser/ui/views/folder_upload_confirmation_view.cc b/chrome/browser/ui/views/folder_upload_confirmation_view.cc index fb81593..d13b930 100644 --- a/chrome/browser/ui/views/folder_upload_confirmation_view.cc +++ b/chrome/browser/ui/views/folder_upload_confirmation_view.cc
@@ -7,8 +7,8 @@ #include "base/files/file_path.h" #include "base/numerics/safe_conversions.h" #include "chrome/browser/file_select_helper.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" -#include "chrome/browser/ui/views/harmony/chrome_typography.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_typography.h" #include "chrome/grit/generated_resources.h" #include "components/constrained_window/constrained_window_views.h" #include "ui/base/l10n/l10n_util.h"
diff --git a/chrome/browser/ui/views/global_error_bubble_view.cc b/chrome/browser/ui/views/global_error_bubble_view.cc index e401947..eec177c 100644 --- a/chrome/browser/ui/views/global_error_bubble_view.cc +++ b/chrome/browser/ui/views/global_error_bubble_view.cc
@@ -19,9 +19,9 @@ #include "chrome/browser/ui/global_error/global_error.h" #include "chrome/browser/ui/global_error/global_error_service.h" #include "chrome/browser/ui/global_error/global_error_service_factory.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" #include "chrome/browser/ui/views/elevation_icon_setter.h" #include "chrome/browser/ui/views/frame/app_menu_button.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" #include "chrome/browser/ui/views/toolbar/toolbar_view.h" #include "chrome/browser/ui/views_mode_controller.h" #include "ui/base/resource/resource_bundle.h"
diff --git a/chrome/browser/ui/views/global_error_bubble_view_unittest.cc b/chrome/browser/ui/views/global_error_bubble_view_unittest.cc index 2b7839fd..d7af629 100644 --- a/chrome/browser/ui/views/global_error_bubble_view_unittest.cc +++ b/chrome/browser/ui/views/global_error_bubble_view_unittest.cc
@@ -8,7 +8,7 @@ #include <vector> #include "chrome/browser/ui/global_error/global_error.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" #include "chrome/test/views/chrome_test_views_delegate.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h"
diff --git a/chrome/browser/ui/views/hover_button.cc b/chrome/browser/ui/views/hover_button.cc index c7ac2da..e49bfde 100644 --- a/chrome/browser/ui/views/hover_button.cc +++ b/chrome/browser/ui/views/hover_button.cc
@@ -7,8 +7,8 @@ #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" #include "chrome/app/vector_icons/vector_icons.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" -#include "chrome/browser/ui/views/harmony/chrome_typography.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_typography.h" #include "ui/gfx/color_palette.h" #include "ui/gfx/paint_vector_icon.h" #include "ui/views/animation/ink_drop_highlight.h"
diff --git a/chrome/browser/ui/views/hung_renderer_view.cc b/chrome/browser/ui/views/hung_renderer_view.cc index f71d8ab..ad8f4702 100644 --- a/chrome/browser/ui/views/hung_renderer_view.cc +++ b/chrome/browser/ui/views/hung_renderer_view.cc
@@ -21,8 +21,8 @@ #include "chrome/browser/ui/hung_renderer/hung_renderer_core.h" #include "chrome/browser/ui/tab_contents/core_tab_helper.h" #include "chrome/browser/ui/tab_contents/tab_contents_iterator.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" -#include "chrome/browser/ui/views/harmony/chrome_typography.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_typography.h" #include "chrome/common/chrome_constants.h" #include "chrome/common/logging_chrome.h" #include "chrome/grit/generated_resources.h"
diff --git a/chrome/browser/ui/views/ime/ime_warning_bubble_view.cc b/chrome/browser/ui/views/ime/ime_warning_bubble_view.cc index 48327bd..56a2f29 100644 --- a/chrome/browser/ui/views/ime/ime_warning_bubble_view.cc +++ b/chrome/browser/ui/views/ime/ime_warning_bubble_view.cc
@@ -11,11 +11,11 @@ #include "chrome/browser/platform_util.h" #include "chrome/browser/ui/browser_dialogs.h" #include "chrome/browser/ui/browser_list.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_typography.h" #include "chrome/browser/ui/views/frame/app_menu_button.h" #include "chrome/browser/ui/views/frame/browser_view.h" #include "chrome/browser/ui/views/frame/toolbar_button_provider.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" -#include "chrome/browser/ui/views/harmony/chrome_typography.h" #include "chrome/browser/ui/views/toolbar/browser_actions_container.h" #include "chrome/browser/ui/views/toolbar/toolbar_view.h" #include "chrome/grit/generated_resources.h"
diff --git a/chrome/browser/ui/views/importer/import_lock_dialog_view.cc b/chrome/browser/ui/views/importer/import_lock_dialog_view.cc index 30e9bbd1..10aae46 100644 --- a/chrome/browser/ui/views/importer/import_lock_dialog_view.cc +++ b/chrome/browser/ui/views/importer/import_lock_dialog_view.cc
@@ -13,7 +13,7 @@ #include "build/build_config.h" #include "chrome/browser/importer/importer_lock_dialog.h" #include "chrome/browser/ui/browser_dialogs.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" #include "chrome/grit/chromium_strings.h" #include "chrome/grit/generated_resources.h" #include "chrome/grit/locale_settings.h"
diff --git a/chrome/browser/ui/views/infobars/confirm_infobar.cc b/chrome/browser/ui/views/infobars/confirm_infobar.cc index 883e78da..0878db43 100644 --- a/chrome/browser/ui/views/infobars/confirm_infobar.cc +++ b/chrome/browser/ui/views/infobars/confirm_infobar.cc
@@ -10,8 +10,8 @@ #include "base/logging.h" #include "build/build_config.h" #include "chrome/browser/infobars/infobar_service.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" #include "chrome/browser/ui/views/elevation_icon_setter.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" #include "chrome/browser/ui/views_mode_controller.h" #include "ui/base/material_design/material_design_controller.h" #include "ui/base/window_open_disposition.h"
diff --git a/chrome/browser/ui/views/infobars/infobar_view.cc b/chrome/browser/ui/views/infobars/infobar_view.cc index 613fccea..0d82597b 100644 --- a/chrome/browser/ui/views/infobars/infobar_view.cc +++ b/chrome/browser/ui/views/infobars/infobar_view.cc
@@ -10,9 +10,9 @@ #include "base/strings/utf_string_conversions.h" #include "chrome/browser/themes/theme_properties.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_typography.h" #include "chrome/browser/ui/views/frame/browser_view.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" -#include "chrome/browser/ui/views/harmony/chrome_typography.h" #include "chrome/grit/generated_resources.h" #include "components/infobars/core/infobar_delegate.h" #include "components/strings/grit/components_strings.h"
diff --git a/chrome/browser/ui/views/harmony/layout_provider_unittest.cc b/chrome/browser/ui/views/layout_provider_unittest.cc similarity index 94% rename from chrome/browser/ui/views/harmony/layout_provider_unittest.cc rename to chrome/browser/ui/views/layout_provider_unittest.cc index 078de17..ba3974ad 100644 --- a/chrome/browser/ui/views/harmony/layout_provider_unittest.cc +++ b/chrome/browser/ui/views/layout_provider_unittest.cc
@@ -5,9 +5,9 @@ #include "base/strings/utf_string_conversions.h" #include "base/test/scoped_feature_list.h" #include "build/build_config.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" -#include "chrome/browser/ui/views/harmony/chrome_typography.h" -#include "chrome/browser/ui/views/harmony/harmony_typography_provider.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_typography.h" +#include "chrome/browser/ui/views/chrome_typography_provider.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/base/default_style.h" #include "ui/base/resource/resource_bundle.h" @@ -151,8 +151,8 @@ // Harmony spec. constexpr int kHeadline = 20; constexpr int kTitle = kHarmonyTitleSize; // Leading 22. - constexpr int kBody1 = 13; // Leading 20. - constexpr int kBody2 = 12; // Leading 20. + constexpr int kBody1 = 13; // Leading 20. + constexpr int kBody2 = 12; // Leading 20. constexpr int kButton = 12; #if defined(OS_WIN) @@ -182,7 +182,7 @@ #if defined(OS_MACOSX) EXPECT_EQ(25, headline_font.GetHeight()); #elif defined(OS_WIN) - EXPECT_EQ(HarmonyTypographyProvider::GetPlatformFontHeight(CONTEXT_HEADLINE), + EXPECT_EQ(ChromeTypographyProvider::GetPlatformFontHeight(CONTEXT_HEADLINE), headline_font.GetHeight()); #else EXPECT_EQ(24, headline_font.GetHeight()); @@ -206,7 +206,7 @@ EXPECT_EQ(16, body1_font.GetHeight()); // Add 4. #elif defined(OS_WIN) EXPECT_EQ( - HarmonyTypographyProvider::GetPlatformFontHeight(CONTEXT_BODY_TEXT_LARGE), + ChromeTypographyProvider::GetPlatformFontHeight(CONTEXT_BODY_TEXT_LARGE), body1_font.GetHeight()); #else // Linux. EXPECT_EQ(17, body1_font.GetHeight()); // Add 3. @@ -214,10 +214,10 @@ EXPECT_EQ(kBody2, body2_font.GetFontSize()); - // Body2 font leading should be 20. +// Body2 font leading should be 20. #if defined(OS_WIN) EXPECT_EQ( - HarmonyTypographyProvider::GetPlatformFontHeight(CONTEXT_BODY_TEXT_SMALL), + ChromeTypographyProvider::GetPlatformFontHeight(CONTEXT_BODY_TEXT_SMALL), body2_font.GetHeight()); #else EXPECT_EQ(15, body2_font.GetHeight()); // Other platforms: Add 5. @@ -225,10 +225,10 @@ EXPECT_EQ(kButton, button_font.GetFontSize()); - // Button leading not specified (shouldn't be needed: no multiline buttons). +// Button leading not specified (shouldn't be needed: no multiline buttons). #if defined(OS_WIN) EXPECT_EQ( - HarmonyTypographyProvider::GetPlatformFontHeight(CONTEXT_BODY_TEXT_SMALL), + ChromeTypographyProvider::GetPlatformFontHeight(CONTEXT_BODY_TEXT_SMALL), button_font.GetHeight()); #else EXPECT_EQ(15, button_font.GetHeight()); @@ -343,7 +343,7 @@ // TODO(tapted): Pass in contexts to StyledLabel instead. Currently they are // stuck on style::CONTEXT_LABEL. That only matches the default line height in - // HarmonyTypographyProvider::GetLineHeight(), which is body text. + // ChromeTypographyProvider::GetLineHeight(), which is body text. EXPECT_EQ(kBodyLineHeight, views::style::GetLineHeight(views::style::CONTEXT_LABEL, kStyle)); views::StyledLabel styled_label(base::ASCIIToUTF16("test"), nullptr);
diff --git a/chrome/browser/ui/views/location_bar/keyword_hint_view.cc b/chrome/browser/ui/views/location_bar/keyword_hint_view.cc index 269fdeb..b88adbac 100644 --- a/chrome/browser/ui/views/location_bar/keyword_hint_view.cc +++ b/chrome/browser/ui/views/location_bar/keyword_hint_view.cc
@@ -14,7 +14,7 @@ #include "chrome/browser/search_engines/template_url_service_factory.h" #include "chrome/browser/ui/layout_constants.h" #include "chrome/browser/ui/omnibox/omnibox_theme.h" -#include "chrome/browser/ui/views/harmony/chrome_typography.h" +#include "chrome/browser/ui/views/chrome_typography.h" #include "chrome/browser/ui/views/location_bar/background_with_1_px_border.h" #include "chrome/browser/ui/views/location_bar/location_bar_view.h" #include "chrome/grit/generated_resources.h"
diff --git a/chrome/browser/ui/views/location_bar/location_bar_view.cc b/chrome/browser/ui/views/location_bar/location_bar_view.cc index a974517..ec6eafd 100644 --- a/chrome/browser/ui/views/location_bar/location_bar_view.cc +++ b/chrome/browser/ui/views/location_bar/location_bar_view.cc
@@ -43,10 +43,10 @@ #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/browser/ui/views/autofill/local_card_migration_icon_view.h" #include "chrome/browser/ui/views/autofill/save_card_icon_view.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" #include "chrome/browser/ui/views/chrome_platform_style.h" +#include "chrome/browser/ui/views/chrome_typography.h" #include "chrome/browser/ui/views/frame/browser_view.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" -#include "chrome/browser/ui/views/harmony/chrome_typography.h" #include "chrome/browser/ui/views/location_bar/background_with_1_px_border.h" #include "chrome/browser/ui/views/location_bar/content_setting_image_view.h" #include "chrome/browser/ui/views/location_bar/keyword_hint_view.h"
diff --git a/chrome/browser/ui/views/location_bar/zoom_bubble_view.cc b/chrome/browser/ui/views/location_bar/zoom_bubble_view.cc index 6f92c7e6..3565e22 100644 --- a/chrome/browser/ui/views/location_bar/zoom_bubble_view.cc +++ b/chrome/browser/ui/views/location_bar/zoom_bubble_view.cc
@@ -19,9 +19,9 @@ #include "chrome/browser/ui/browser_finder.h" #include "chrome/browser/ui/browser_tabstrip.h" #include "chrome/browser/ui/browser_window.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" #include "chrome/browser/ui/views/frame/browser_view.h" #include "chrome/browser/ui/views/frame/toolbar_button_provider.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" #include "chrome/browser/ui/views/page_action/page_action_icon_container_view.h" #include "chrome/browser/ui/views/page_action/zoom_view.h" #include "chrome/browser/ui/views_mode_controller.h"
diff --git a/chrome/browser/ui/views/login_view.cc b/chrome/browser/ui/views/login_view.cc index 901494d..fe7d447 100644 --- a/chrome/browser/ui/views/login_view.cc +++ b/chrome/browser/ui/views/login_view.cc
@@ -4,9 +4,9 @@ #include "chrome/browser/ui/views/login_view.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" -#include "chrome/browser/ui/views/harmony/chrome_typography.h" -#include "chrome/browser/ui/views/harmony/textfield_layout.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_typography.h" +#include "chrome/browser/ui/views/textfield_layout.h" #include "components/strings/grit/components_strings.h" #include "ui/base/l10n/l10n_util.h" #include "ui/views/border.h"
diff --git a/chrome/browser/ui/views/harmony/material_refresh_layout_provider.cc b/chrome/browser/ui/views/material_refresh_layout_provider.cc similarity index 96% rename from chrome/browser/ui/views/harmony/material_refresh_layout_provider.cc rename to chrome/browser/ui/views/material_refresh_layout_provider.cc index 61dff04..9e51fe7 100644 --- a/chrome/browser/ui/views/harmony/material_refresh_layout_provider.cc +++ b/chrome/browser/ui/views/material_refresh_layout_provider.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 "chrome/browser/ui/views/harmony/material_refresh_layout_provider.h" +#include "chrome/browser/ui/views/material_refresh_layout_provider.h" #include "ui/base/material_design/material_design_controller.h" #include "ui/views/layout/layout_provider.h"
diff --git a/chrome/browser/ui/views/harmony/material_refresh_layout_provider.h b/chrome/browser/ui/views/material_refresh_layout_provider.h similarity index 72% rename from chrome/browser/ui/views/harmony/material_refresh_layout_provider.h rename to chrome/browser/ui/views/material_refresh_layout_provider.h index de54a7f..f9819e54 100644 --- a/chrome/browser/ui/views/harmony/material_refresh_layout_provider.h +++ b/chrome/browser/ui/views/material_refresh_layout_provider.h
@@ -2,18 +2,18 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_UI_VIEWS_HARMONY_MATERIAL_REFRESH_LAYOUT_PROVIDER_H_ -#define CHROME_BROWSER_UI_VIEWS_HARMONY_MATERIAL_REFRESH_LAYOUT_PROVIDER_H_ +#ifndef CHROME_BROWSER_UI_VIEWS_MATERIAL_REFRESH_LAYOUT_PROVIDER_H_ +#define CHROME_BROWSER_UI_VIEWS_MATERIAL_REFRESH_LAYOUT_PROVIDER_H_ #include "base/macros.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" class MaterialRefreshLayoutProvider : public ChromeLayoutProvider { public: MaterialRefreshLayoutProvider() = default; ~MaterialRefreshLayoutProvider() override = default; - // HarmonyLayoutProvider: + // ChromeLayoutProvider: int GetDistanceMetric(int metric) const override; gfx::Insets GetInsetsMetric(int metric) const override; int GetCornerRadiusMetric(views::EmphasisMetric emphasis_metric, @@ -24,4 +24,4 @@ SkColor color) const override; }; -#endif // CHROME_BROWSER_UI_VIEWS_HARMONY_MATERIAL_REFRESH_LAYOUT_PROVIDER_H_ +#endif // CHROME_BROWSER_UI_VIEWS_MATERIAL_REFRESH_LAYOUT_PROVIDER_H_
diff --git a/chrome/browser/ui/views/media_router/cast_dialog_sink_button_unittest.cc b/chrome/browser/ui/views/media_router/cast_dialog_sink_button_unittest.cc index a6a38a7..9f2d9fe 100644 --- a/chrome/browser/ui/views/media_router/cast_dialog_sink_button_unittest.cc +++ b/chrome/browser/ui/views/media_router/cast_dialog_sink_button_unittest.cc
@@ -5,7 +5,7 @@ #include "chrome/browser/ui/views/media_router/cast_dialog_sink_button.h" #include "chrome/browser/ui/media_router/ui_media_sink.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" #include "chrome/grit/generated_resources.h" #include "chrome/test/views/chrome_views_test_base.h" #include "testing/gmock/include/gmock/gmock.h"
diff --git a/chrome/browser/ui/views/media_router/cast_dialog_view.cc b/chrome/browser/ui/views/media_router/cast_dialog_view.cc index c1b343c2..13f6020 100644 --- a/chrome/browser/ui/views/media_router/cast_dialog_view.cc +++ b/chrome/browser/ui/views/media_router/cast_dialog_view.cc
@@ -14,9 +14,9 @@ #include "chrome/browser/ui/media_router/media_cast_mode.h" #include "chrome/browser/ui/media_router/ui_media_sink.h" #include "chrome/browser/ui/toolbar/component_toolbar_actions_factory.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" #include "chrome/browser/ui/views/frame/browser_view.h" #include "chrome/browser/ui/views/frame/top_container_view.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" #include "chrome/browser/ui/views/media_router/cast_dialog_no_sinks_view.h" #include "chrome/browser/ui/views/media_router/cast_dialog_sink_button.h" #include "chrome/browser/ui/views/toolbar/browser_actions_container.h"
diff --git a/chrome/browser/ui/views/media_router/cast_dialog_view_unittest.cc b/chrome/browser/ui/views/media_router/cast_dialog_view_unittest.cc index 8fbe792..15d6bf1 100644 --- a/chrome/browser/ui/views/media_router/cast_dialog_view_unittest.cc +++ b/chrome/browser/ui/views/media_router/cast_dialog_view_unittest.cc
@@ -15,7 +15,7 @@ #include "build/build_config.h" #include "chrome/browser/ui/media_router/cast_dialog_controller.h" #include "chrome/browser/ui/media_router/cast_dialog_model.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" #include "chrome/browser/ui/views/media_router/cast_dialog_sink_button.h" #include "chrome/grit/generated_resources.h" #include "chrome/test/views/chrome_views_test_base.h"
diff --git a/chrome/browser/ui/views/media_router/cloud_services_dialog_view.cc b/chrome/browser/ui/views/media_router/cloud_services_dialog_view.cc index acb4bf68..4bb6bf91 100644 --- a/chrome/browser/ui/views/media_router/cloud_services_dialog_view.cc +++ b/chrome/browser/ui/views/media_router/cloud_services_dialog_view.cc
@@ -8,8 +8,8 @@ #include "chrome/browser/ui/browser_tabstrip.h" #include "chrome/browser/ui/media_router/cloud_services_dialog.h" #include "chrome/browser/ui/toolbar/component_toolbar_actions_factory.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" #include "chrome/browser/ui/views/frame/browser_view.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" #include "chrome/browser/ui/views/toolbar/browser_actions_container.h" #include "chrome/browser/ui/views/toolbar/toolbar_view.h" #include "chrome/common/pref_names.h"
diff --git a/chrome/browser/ui/views/media_router/media_remoting_dialog_view.cc b/chrome/browser/ui/views/media_router/media_remoting_dialog_view.cc index 678cb9a6..0b9eee4 100644 --- a/chrome/browser/ui/views/media_router/media_remoting_dialog_view.cc +++ b/chrome/browser/ui/views/media_router/media_remoting_dialog_view.cc
@@ -6,7 +6,7 @@ #include "chrome/browser/ui/browser_finder.h" #include "chrome/browser/ui/toolbar/component_toolbar_actions_factory.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" #include "chrome/browser/ui/views/toolbar/toolbar_view.h" #include "chrome/common/pref_names.h" #include "chrome/grit/generated_resources.h"
diff --git a/chrome/browser/ui/views/omnibox/omnibox_result_view.cc b/chrome/browser/ui/views/omnibox/omnibox_result_view.cc index 5ab2343..5599228 100644 --- a/chrome/browser/ui/views/omnibox/omnibox_result_view.cc +++ b/chrome/browser/ui/views/omnibox/omnibox_result_view.cc
@@ -176,10 +176,10 @@ suggestion_view_->description()->SetText(match_.description, match_.description_class); - // Normally, OmniboxTextView caches its appearance, but in high contrast - // selected-ness changes the text colors, so the styling of the text part of - // the results needs to be recomputed. - if (high_contrast) { + // Normally, OmniboxTextView caches its appearance, but in high contrast and + // on Windows in the pre-Refresh UI, selected-ness changes the text colors, + // so the styling of the text part of the results needs to be recomputed. + if (high_contrast || !ui::MaterialDesignController::IsRefreshUi()) { suggestion_view_->content()->ReapplyStyling(); suggestion_view_->description()->ReapplyStyling(); }
diff --git a/chrome/browser/ui/views/omnibox/omnibox_text_view.cc b/chrome/browser/ui/views/omnibox/omnibox_text_view.cc index 5d87db9..a1fea8b9 100644 --- a/chrome/browser/ui/views/omnibox/omnibox_text_view.cc +++ b/chrome/browser/ui/views/omnibox/omnibox_text_view.cc
@@ -14,7 +14,7 @@ #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" #include "chrome/browser/ui/omnibox/omnibox_theme.h" -#include "chrome/browser/ui/views/harmony/chrome_typography.h" +#include "chrome/browser/ui/views/chrome_typography.h" #include "components/omnibox/browser/omnibox_field_trial.h" #include "ui/base/material_design/material_design_controller.h" #include "ui/base/resource/resource_bundle.h"
diff --git a/chrome/browser/ui/views/omnibox/omnibox_view_views.cc b/chrome/browser/ui/views/omnibox/omnibox_view_views.cc index e4d50e9..776e268e 100644 --- a/chrome/browser/ui/views/omnibox/omnibox_view_views.cc +++ b/chrome/browser/ui/views/omnibox/omnibox_view_views.cc
@@ -20,7 +20,7 @@ #include "chrome/browser/ui/omnibox/clipboard_utils.h" #include "chrome/browser/ui/omnibox/omnibox_theme.h" #include "chrome/browser/ui/view_ids.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" #include "chrome/browser/ui/views/location_bar/location_bar_view.h" #include "chrome/browser/ui/views/omnibox/omnibox_popup_contents_view.h" #include "chrome/grit/generated_resources.h"
diff --git a/chrome/browser/ui/views/outdated_upgrade_bubble_view.cc b/chrome/browser/ui/views/outdated_upgrade_bubble_view.cc index 374e087..f5d3be5b 100644 --- a/chrome/browser/ui/views/outdated_upgrade_bubble_view.cc +++ b/chrome/browser/ui/views/outdated_upgrade_bubble_view.cc
@@ -10,7 +10,7 @@ #include "build/build_config.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/ui/browser_dialogs.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" #include "chrome/browser/upgrade_detector/upgrade_detector.h" #include "chrome/common/pref_names.h" #include "chrome/grit/chromium_strings.h"
diff --git a/chrome/browser/ui/views/page_info/chosen_object_view.cc b/chrome/browser/ui/views/page_info/chosen_object_view.cc index 8eda458..c514bba 100644 --- a/chrome/browser/ui/views/page_info/chosen_object_view.cc +++ b/chrome/browser/ui/views/page_info/chosen_object_view.cc
@@ -4,8 +4,8 @@ #include "chrome/browser/ui/views/page_info/chosen_object_view.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" -#include "chrome/browser/ui/views/harmony/chrome_typography.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_typography.h" #include "chrome/browser/ui/views/page_info/chosen_object_view_observer.h" #include "chrome/browser/ui/views/page_info/page_info_bubble_view.h" #include "components/vector_icons/vector_icons.h"
diff --git a/chrome/browser/ui/views/page_info/page_info_bubble_view.cc b/chrome/browser/ui/views/page_info/page_info_bubble_view.cc index 55ee18e6..9a7f310 100644 --- a/chrome/browser/ui/views/page_info/page_info_bubble_view.cc +++ b/chrome/browser/ui/views/page_info/page_info_bubble_view.cc
@@ -27,9 +27,9 @@ #include "chrome/browser/ui/view_ids.h" #include "chrome/browser/ui/views/accessibility/non_accessible_image_view.h" #include "chrome/browser/ui/views/bubble_anchor_util_views.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_typography.h" #include "chrome/browser/ui/views/collected_cookies_views.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" -#include "chrome/browser/ui/views/harmony/chrome_typography.h" #include "chrome/browser/ui/views/hover_button.h" #include "chrome/browser/ui/views/page_info/chosen_object_view.h" #include "chrome/browser/ui/views/page_info/permission_selector_row.h"
diff --git a/chrome/browser/ui/views/page_info/page_info_bubble_view_unittest.cc b/chrome/browser/ui/views/page_info/page_info_bubble_view_unittest.cc index d94af26..6ebada6 100644 --- a/chrome/browser/ui/views/page_info/page_info_bubble_view_unittest.cc +++ b/chrome/browser/ui/views/page_info/page_info_bubble_view_unittest.cc
@@ -9,7 +9,7 @@ #include "build/build_config.h" #include "chrome/browser/content_settings/host_content_settings_map_factory.h" #include "chrome/browser/ui/exclusive_access/exclusive_access_manager.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" #include "chrome/browser/ui/views/hover_button.h" #include "chrome/browser/ui/views/page_info/chosen_object_view.h" #include "chrome/browser/ui/views/page_info/permission_selector_row.h"
diff --git a/chrome/browser/ui/views/page_info/permission_selector_row.cc b/chrome/browser/ui/views/page_info/permission_selector_row.cc index d0db13c..15f4c13 100644 --- a/chrome/browser/ui/views/page_info/permission_selector_row.cc +++ b/chrome/browser/ui/views/page_info/permission_selector_row.cc
@@ -10,8 +10,8 @@ #include "chrome/browser/ui/page_info/page_info_ui.h" #include "chrome/browser/ui/page_info/permission_menu_model.h" #include "chrome/browser/ui/views/accessibility/non_accessible_image_view.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" -#include "chrome/browser/ui/views/harmony/chrome_typography.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_typography.h" #include "chrome/browser/ui/views/page_info/page_info_bubble_view.h" #include "components/strings/grit/components_strings.h" #include "ui/accessibility/ax_node_data.h"
diff --git a/chrome/browser/ui/views/passwords/account_chooser_dialog_view.cc b/chrome/browser/ui/views/passwords/account_chooser_dialog_view.cc index 5f054f1..a4b5466c 100644 --- a/chrome/browser/ui/views/passwords/account_chooser_dialog_view.cc +++ b/chrome/browser/ui/views/passwords/account_chooser_dialog_view.cc
@@ -12,7 +12,7 @@ #include "chrome/browser/ui/browser_dialogs.h" #include "chrome/browser/ui/passwords/manage_passwords_view_utils.h" #include "chrome/browser/ui/passwords/password_dialog_controller.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" #include "chrome/browser/ui/views/passwords/credentials_item_view.h" #include "chrome/grit/generated_resources.h" #include "components/autofill/core/common/password_form.h"
diff --git a/chrome/browser/ui/views/passwords/auto_signin_first_run_dialog_view.cc b/chrome/browser/ui/views/passwords/auto_signin_first_run_dialog_view.cc index f6f402e8..0e76d0f 100644 --- a/chrome/browser/ui/views/passwords/auto_signin_first_run_dialog_view.cc +++ b/chrome/browser/ui/views/passwords/auto_signin_first_run_dialog_view.cc
@@ -7,8 +7,8 @@ #include "build/build_config.h" #include "chrome/browser/ui/browser_dialogs.h" #include "chrome/browser/ui/passwords/password_dialog_controller.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" -#include "chrome/browser/ui/views/harmony/chrome_typography.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_typography.h" #include "chrome/grit/generated_resources.h" #include "components/constrained_window/constrained_window_views.h" #include "ui/base/l10n/l10n_util.h"
diff --git a/chrome/browser/ui/views/passwords/credentials_item_view.cc b/chrome/browser/ui/views/passwords/credentials_item_view.cc index ff3f9c1..d9a04dc 100644 --- a/chrome/browser/ui/views/passwords/credentials_item_view.cc +++ b/chrome/browser/ui/views/passwords/credentials_item_view.cc
@@ -7,8 +7,8 @@ #include "base/macros.h" #include "base/strings/utf_string_conversions.h" #include "chrome/browser/ui/passwords/manage_passwords_view_utils.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" -#include "chrome/browser/ui/views/harmony/chrome_typography.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_typography.h" #include "chrome/grit/theme_resources.h" #include "components/autofill/core/common/password_form.h" #include "ui/base/resource/resource_bundle.h"
diff --git a/chrome/browser/ui/views/passwords/password_auto_sign_in_view.cc b/chrome/browser/ui/views/passwords/password_auto_sign_in_view.cc index 76fe5b9..686c4ec 100644 --- a/chrome/browser/ui/views/passwords/password_auto_sign_in_view.cc +++ b/chrome/browser/ui/views/passwords/password_auto_sign_in_view.cc
@@ -8,7 +8,7 @@ #include "chrome/browser/ui/browser_finder.h" #include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/passwords/password_dialog_prompts.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" #include "chrome/browser/ui/views/passwords/credentials_item_view.h" #include "chrome/grit/generated_resources.h" #include "components/strings/grit/components_strings.h"
diff --git a/chrome/browser/ui/views/passwords/password_generation_popup_view_views.cc b/chrome/browser/ui/views/passwords/password_generation_popup_view_views.cc index 5ebacc1..711b005e 100644 --- a/chrome/browser/ui/views/passwords/password_generation_popup_view_views.cc +++ b/chrome/browser/ui/views/passwords/password_generation_popup_view_views.cc
@@ -7,8 +7,8 @@ #include "base/macros.h" #include "base/strings/string16.h" #include "chrome/browser/ui/passwords/password_generation_popup_controller.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" -#include "chrome/browser/ui/views/harmony/chrome_typography.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_typography.h" #include "ui/accessibility/ax_node_data.h" #include "ui/base/material_design/material_design_controller.h" #include "ui/base/resource/resource_bundle.h"
diff --git a/chrome/browser/ui/views/passwords/password_items_view.cc b/chrome/browser/ui/views/passwords/password_items_view.cc index 3498c73..68c13b6a 100644 --- a/chrome/browser/ui/views/passwords/password_items_view.cc +++ b/chrome/browser/ui/views/passwords/password_items_view.cc
@@ -11,8 +11,8 @@ #include "chrome/app/vector_icons/vector_icons.h" #include "chrome/browser/ui/passwords/manage_passwords_bubble_model.h" #include "chrome/browser/ui/passwords/manage_passwords_view_utils.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" -#include "chrome/browser/ui/views/harmony/chrome_typography.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_typography.h" #include "chrome/grit/generated_resources.h" #include "components/password_manager/core/common/password_manager_ui.h" #include "ui/base/l10n/l10n_util.h"
diff --git a/chrome/browser/ui/views/passwords/password_pending_view.cc b/chrome/browser/ui/views/passwords/password_pending_view.cc index 32c10d7..f1fdefb 100644 --- a/chrome/browser/ui/views/passwords/password_pending_view.cc +++ b/chrome/browser/ui/views/passwords/password_pending_view.cc
@@ -11,8 +11,8 @@ #include "base/strings/utf_string_conversions.h" #include "build/build_config.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" -#include "chrome/browser/ui/views/harmony/chrome_typography.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_typography.h" #include "chrome/browser/ui/views/passwords/password_items_view.h" #include "chrome/browser/ui/views/passwords/password_sign_in_promo_view.h" #include "chrome/grit/generated_resources.h"
diff --git a/chrome/browser/ui/views/passwords/password_save_confirmation_view.cc b/chrome/browser/ui/views/passwords/password_save_confirmation_view.cc index e359b4d..1ed8aaf 100644 --- a/chrome/browser/ui/views/passwords/password_save_confirmation_view.cc +++ b/chrome/browser/ui/views/passwords/password_save_confirmation_view.cc
@@ -4,8 +4,8 @@ #include "chrome/browser/ui/views/passwords/password_save_confirmation_view.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" -#include "chrome/browser/ui/views/harmony/chrome_typography.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_typography.h" #include "chrome/grit/generated_resources.h" #include "components/strings/grit/components_strings.h" #include "ui/base/l10n/l10n_util.h"
diff --git a/chrome/browser/ui/views/passwords/password_sign_in_promo_view.cc b/chrome/browser/ui/views/passwords/password_sign_in_promo_view.cc index b2412d4..90946b7 100644 --- a/chrome/browser/ui/views/passwords/password_sign_in_promo_view.cc +++ b/chrome/browser/ui/views/passwords/password_sign_in_promo_view.cc
@@ -10,8 +10,8 @@ #include "build/buildflag.h" #include "chrome/browser/signin/account_consistency_mode_manager.h" #include "chrome/browser/ui/passwords/manage_passwords_bubble_model.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" -#include "chrome/browser/ui/views/harmony/chrome_typography.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_typography.h" #include "chrome/grit/generated_resources.h" #include "components/signin/core/browser/account_info.h" #include "components/signin/core/browser/signin_buildflags.h"
diff --git a/chrome/browser/ui/views/payments/credit_card_editor_view_controller.cc b/chrome/browser/ui/views/payments/credit_card_editor_view_controller.cc index 6de40db..1927fee 100644 --- a/chrome/browser/ui/views/payments/credit_card_editor_view_controller.cc +++ b/chrome/browser/ui/views/payments/credit_card_editor_view_controller.cc
@@ -18,7 +18,7 @@ #include "chrome/browser/ui/autofill/autofill_dialog_models.h" #include "chrome/browser/ui/scoped_tabbed_browser_displayer.h" #include "chrome/browser/ui/singleton_tabs.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" #include "chrome/browser/ui/views/payments/payment_request_dialog_view.h" #include "chrome/browser/ui/views/payments/payment_request_dialog_view_ids.h" #include "chrome/browser/ui/views/payments/payment_request_views_util.h"
diff --git a/chrome/browser/ui/views/payments/editor_view_controller.cc b/chrome/browser/ui/views/payments/editor_view_controller.cc index fc95487..68591b7f 100644 --- a/chrome/browser/ui/views/payments/editor_view_controller.cc +++ b/chrome/browser/ui/views/payments/editor_view_controller.cc
@@ -10,7 +10,7 @@ #include <utility> #include "base/strings/utf_string_conversions.h" -#include "chrome/browser/ui/views/harmony/chrome_typography.h" +#include "chrome/browser/ui/views/chrome_typography.h" #include "chrome/browser/ui/views/payments/payment_request_dialog_view.h" #include "chrome/browser/ui/views/payments/payment_request_dialog_view_ids.h" #include "chrome/browser/ui/views/payments/payment_request_views_util.h"
diff --git a/chrome/browser/ui/views/payments/payment_method_view_controller.cc b/chrome/browser/ui/views/payments/payment_method_view_controller.cc index 450b38f3..8aaec493 100644 --- a/chrome/browser/ui/views/payments/payment_method_view_controller.cc +++ b/chrome/browser/ui/views/payments/payment_method_view_controller.cc
@@ -12,7 +12,7 @@ #include "base/bind_helpers.h" #include "base/callback_forward.h" #include "chrome/browser/browser_process.h" -#include "chrome/browser/ui/views/harmony/chrome_typography.h" +#include "chrome/browser/ui/views/chrome_typography.h" #include "chrome/browser/ui/views/payments/payment_request_dialog_view.h" #include "chrome/browser/ui/views/payments/payment_request_dialog_view_ids.h" #include "chrome/browser/ui/views/payments/payment_request_row_view.h"
diff --git a/chrome/browser/ui/views/payments/payment_request_views_util.cc b/chrome/browser/ui/views/payments/payment_request_views_util.cc index ed4fa70..06d6ced4 100644 --- a/chrome/browser/ui/views/payments/payment_request_views_util.cc +++ b/chrome/browser/ui/views/payments/payment_request_views_util.cc
@@ -8,7 +8,7 @@ #include "base/macros.h" #include "base/strings/utf_string_conversions.h" -#include "chrome/browser/ui/views/harmony/chrome_typography.h" +#include "chrome/browser/ui/views/chrome_typography.h" #include "chrome/browser/ui/views/payments/payment_request_dialog_view_ids.h" #include "chrome/browser/ui/views/payments/payment_request_sheet_controller.h" #include "chrome/grit/chromium_strings.h"
diff --git a/chrome/browser/ui/views/payments/payment_sheet_view_controller.cc b/chrome/browser/ui/views/payments/payment_sheet_view_controller.cc index 63f572a..901ecb99 100644 --- a/chrome/browser/ui/views/payments/payment_sheet_view_controller.cc +++ b/chrome/browser/ui/views/payments/payment_sheet_view_controller.cc
@@ -20,7 +20,7 @@ #include "chrome/browser/browser_process.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/chrome_pages.h" -#include "chrome/browser/ui/views/harmony/chrome_typography.h" +#include "chrome/browser/ui/views/chrome_typography.h" #include "chrome/browser/ui/views/payments/payment_request_dialog_view.h" #include "chrome/browser/ui/views/payments/payment_request_dialog_view_ids.h" #include "chrome/browser/ui/views/payments/payment_request_row_view.h"
diff --git a/chrome/browser/ui/views/permission_bubble/permission_prompt_impl.cc b/chrome/browser/ui/views/permission_bubble/permission_prompt_impl.cc index 7ed680f..55a49cb 100644 --- a/chrome/browser/ui/views/permission_bubble/permission_prompt_impl.cc +++ b/chrome/browser/ui/views/permission_bubble/permission_prompt_impl.cc
@@ -16,7 +16,7 @@ #include "chrome/browser/ui/browser_dialogs.h" #include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/views/bubble_anchor_util_views.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" #include "chrome/browser/ui/views/page_info/permission_selector_row.h" #include "chrome/browser/ui/views/page_info/permission_selector_row_observer.h" #include "chrome/grit/generated_resources.h"
diff --git a/chrome/browser/ui/views/platform_keys_certificate_selector_chromeos.cc b/chrome/browser/ui/views/platform_keys_certificate_selector_chromeos.cc index 1d105e0..d08e097 100644 --- a/chrome/browser/ui/views/platform_keys_certificate_selector_chromeos.cc +++ b/chrome/browser/ui/views/platform_keys_certificate_selector_chromeos.cc
@@ -13,7 +13,7 @@ #include "base/strings/string16.h" #include "base/strings/utf_string_conversions.h" #include "chrome/browser/ui/browser_dialogs.h" -#include "chrome/browser/ui/views/harmony/chrome_typography.h" +#include "chrome/browser/ui/views/chrome_typography.h" #include "chrome/grit/generated_resources.h" #include "net/ssl/client_cert_identity.h" #include "net/ssl/ssl_private_key.h"
diff --git a/chrome/browser/ui/views/policy/enterprise_startup_dialog_view.cc b/chrome/browser/ui/views/policy/enterprise_startup_dialog_view.cc index 6e20a16..35ba83c 100644 --- a/chrome/browser/ui/views/policy/enterprise_startup_dialog_view.cc +++ b/chrome/browser/ui/views/policy/enterprise_startup_dialog_view.cc
@@ -12,7 +12,7 @@ #include "base/strings/utf_string_conversions.h" #include "build/build_config.h" #include "chrome/app/vector_icons/vector_icons.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" #include "chrome/grit/chromium_strings.h" #include "chrome/grit/theme_resources.h" #include "components/constrained_window/constrained_window_views.h"
diff --git a/chrome/browser/ui/views/profiles/dice_accounts_menu.cc b/chrome/browser/ui/views/profiles/dice_accounts_menu.cc index db3f00a0..3f4edad 100644 --- a/chrome/browser/ui/views/profiles/dice_accounts_menu.cc +++ b/chrome/browser/ui/views/profiles/dice_accounts_menu.cc
@@ -8,7 +8,7 @@ #include "build/build_config.h" #include "chrome/app/vector_icons/vector_icons.h" #include "chrome/browser/profiles/profile_avatar_icon_util.h" -#include "chrome/browser/ui/views/harmony/chrome_typography.h" +#include "chrome/browser/ui/views/chrome_typography.h" #include "chrome/grit/generated_resources.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/resource/resource_bundle.h"
diff --git a/chrome/browser/ui/views/profiles/forced_reauthentication_dialog_view.cc b/chrome/browser/ui/views/profiles/forced_reauthentication_dialog_view.cc index de75d15..5db069e5 100644 --- a/chrome/browser/ui/views/profiles/forced_reauthentication_dialog_view.cc +++ b/chrome/browser/ui/views/profiles/forced_reauthentication_dialog_view.cc
@@ -18,9 +18,9 @@ #include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/sync/profile_signin_confirmation_helper.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_typography.h" #include "chrome/browser/ui/views/frame/browser_view.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" -#include "chrome/browser/ui/views/harmony/chrome_typography.h" #include "chrome/grit/chromium_strings.h" #include "chrome/grit/generated_resources.h" #include "components/constrained_window/constrained_window_views.h"
diff --git a/chrome/browser/ui/views/profiles/profile_chooser_view.cc b/chrome/browser/ui/views/profiles/profile_chooser_view.cc index 228e99b..c1341d0 100644 --- a/chrome/browser/ui/views/profiles/profile_chooser_view.cc +++ b/chrome/browser/ui/views/profiles/profile_chooser_view.cc
@@ -44,8 +44,8 @@ #include "chrome/browser/ui/sync/sync_promo_ui.h" #include "chrome/browser/ui/user_manager.h" #include "chrome/browser/ui/views/accessibility/non_accessible_image_view.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" -#include "chrome/browser/ui/views/harmony/chrome_typography.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_typography.h" #include "chrome/browser/ui/views/hover_button.h" #include "chrome/browser/ui/views/profiles/badged_profile_photo.h" #include "chrome/browser/ui/views/profiles/signin_view_controller_delegate_views.h"
diff --git a/chrome/browser/ui/views/relaunch_notification/relaunch_recommended_bubble_view.cc b/chrome/browser/ui/views/relaunch_notification/relaunch_recommended_bubble_view.cc index 16ab625..a4832a8a 100644 --- a/chrome/browser/ui/views/relaunch_notification/relaunch_recommended_bubble_view.cc +++ b/chrome/browser/ui/views/relaunch_notification/relaunch_recommended_bubble_view.cc
@@ -13,8 +13,8 @@ #include "base/time/time.h" #include "build/build_config.h" #include "chrome/browser/ui/browser_dialogs.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" #include "chrome/browser/ui/views/frame/browser_view.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" #include "chrome/browser/ui/views/toolbar/browser_app_menu_button.h" #include "chrome/browser/ui/views/toolbar/toolbar_view.h" #include "chrome/grit/chromium_strings.h" @@ -223,6 +223,9 @@ } void RelaunchRecommendedBubbleView::OnTitleRefresh() { - GetBubbleFrameView()->UpdateWindowTitle(); + GetWidget()->UpdateWindowTitle(); + // This might update the length of the window title (for N days). Resize the + // bubble to match the new preferred size. + SizeToContents(); ScheduleNextTitleRefresh(); }
diff --git a/chrome/browser/ui/views/relaunch_notification/relaunch_required_dialog_view.cc b/chrome/browser/ui/views/relaunch_notification/relaunch_required_dialog_view.cc index 535999d..aea3c1d 100644 --- a/chrome/browser/ui/views/relaunch_notification/relaunch_required_dialog_view.cc +++ b/chrome/browser/ui/views/relaunch_notification/relaunch_required_dialog_view.cc
@@ -11,7 +11,7 @@ #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_dialogs.h" #include "chrome/browser/ui/browser_window.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" #include "chrome/grit/chromium_strings.h" #include "chrome/grit/generated_resources.h" #include "components/constrained_window/constrained_window_views.h" @@ -23,13 +23,12 @@ #include "ui/gfx/geometry/rect.h" #include "ui/gfx/paint_vector_icon.h" #include "ui/gfx/text_constants.h" -#include "ui/views/bubble/bubble_frame_view.h" +#include "ui/views/border.h" #include "ui/views/controls/label.h" #include "ui/views/layout/layout_provider.h" #include "ui/views/style/typography.h" #include "ui/views/view.h" #include "ui/views/widget/widget.h" -#include "ui/views/window/non_client_view.h" // static views::Widget* RelaunchRequiredDialogView::Show( @@ -271,14 +270,8 @@ } void RelaunchRequiredDialogView::OnTitleRefresh() { - GetBubbleFrameView()->UpdateWindowTitle(); + GetWidget()->UpdateWindowTitle(); + if (!last_refresh_) ScheduleNextTitleRefresh(); } - -views::BubbleFrameView* RelaunchRequiredDialogView::GetBubbleFrameView() { - const views::NonClientView* view = - GetWidget() ? GetWidget()->non_client_view() : nullptr; - return view ? static_cast<views::BubbleFrameView*>(view->frame_view()) - : nullptr; -}
diff --git a/chrome/browser/ui/views/relaunch_notification/relaunch_required_dialog_view.h b/chrome/browser/ui/views/relaunch_notification/relaunch_required_dialog_view.h index df6a7287..27487cf 100644 --- a/chrome/browser/ui/views/relaunch_notification/relaunch_required_dialog_view.h +++ b/chrome/browser/ui/views/relaunch_notification/relaunch_required_dialog_view.h
@@ -13,7 +13,6 @@ class Browser; namespace views { -class BubbleFrameView; class Label; class Widget; } // namespace views @@ -76,10 +75,6 @@ // Invoked when the timer fires to refresh the title text. void OnTitleRefresh(); - // Returns the containing widget's NonClientView's FrameView as a - // BubbleFrameView. - views::BubbleFrameView* GetBubbleFrameView(); - // The time at which Chrome will be forcefully relaunched. base::TimeTicks relaunch_deadline_;
diff --git a/chrome/browser/ui/views/sad_tab_view.cc b/chrome/browser/ui/views/sad_tab_view.cc index e7c7d90..c8b4230 100644 --- a/chrome/browser/ui/views/sad_tab_view.cc +++ b/chrome/browser/ui/views/sad_tab_view.cc
@@ -11,10 +11,10 @@ #include "build/build_config.h" #include "chrome/app/vector_icons/vector_icons.h" #include "chrome/browser/ui/browser_finder.h" +#include "chrome/browser/ui/views/bulleted_label_list_view.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_typography.h" #include "chrome/browser/ui/views/frame/browser_view.h" -#include "chrome/browser/ui/views/harmony/bulleted_label_list_view.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" -#include "chrome/browser/ui/views/harmony/chrome_typography.h" #include "chrome/browser/ui/views_mode_controller.h" #include "content/public/browser/web_contents.h" #include "ui/accessibility/ax_enums.mojom.h"
diff --git a/chrome/browser/ui/views/safe_browsing/password_reuse_modal_warning_dialog.cc b/chrome/browser/ui/views/safe_browsing/password_reuse_modal_warning_dialog.cc index 00cf695..03abec89 100644 --- a/chrome/browser/ui/views/safe_browsing/password_reuse_modal_warning_dialog.cc +++ b/chrome/browser/ui/views/safe_browsing/password_reuse_modal_warning_dialog.cc
@@ -8,8 +8,8 @@ #include "base/strings/utf_string_conversions.h" #include "build/build_config.h" #include "chrome/app/vector_icons/vector_icons.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" -#include "chrome/browser/ui/views/harmony/chrome_typography.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_typography.h" #include "components/constrained_window/constrained_window_views.h" #include "components/strings/grit/components_strings.h" #include "components/vector_icons/vector_icons.h"
diff --git a/chrome/browser/ui/views/session_crashed_bubble_view.cc b/chrome/browser/ui/views/session_crashed_bubble_view.cc index c4abc5f..6c9ffe2 100644 --- a/chrome/browser/ui/views/session_crashed_bubble_view.cc +++ b/chrome/browser/ui/views/session_crashed_bubble_view.cc
@@ -23,11 +23,11 @@ #include "chrome/browser/ui/browser_list_observer.h" #include "chrome/browser/ui/bubble_anchor_util.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_typography.h" #include "chrome/browser/ui/views/frame/app_menu_button.h" #include "chrome/browser/ui/views/frame/browser_view.h" #include "chrome/browser/ui/views/frame/toolbar_button_provider.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" -#include "chrome/browser/ui/views/harmony/chrome_typography.h" #include "chrome/browser/ui/views/toolbar/toolbar_view.h" #include "chrome/browser/ui/views_mode_controller.h" #include "chrome/grit/chromium_strings.h"
diff --git a/chrome/browser/ui/views/settings_reset_prompt_dialog.cc b/chrome/browser/ui/views/settings_reset_prompt_dialog.cc index fd93370c..36b2dd5f 100644 --- a/chrome/browser/ui/views/settings_reset_prompt_dialog.cc +++ b/chrome/browser/ui/views/settings_reset_prompt_dialog.cc
@@ -7,9 +7,9 @@ #include "chrome/browser/safe_browsing/settings_reset_prompt/settings_reset_prompt_controller.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_dialogs.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_typography.h" #include "chrome/browser/ui/views/frame/browser_view.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" -#include "chrome/browser/ui/views/harmony/chrome_typography.h" #include "components/constrained_window/constrained_window_views.h" #include "ui/gfx/font.h" #include "ui/gfx/geometry/insets.h"
diff --git a/chrome/browser/ui/views/subtle_notification_view.cc b/chrome/browser/ui/views/subtle_notification_view.cc index b3f030b..922edba60 100644 --- a/chrome/browser/ui/views/subtle_notification_view.cc +++ b/chrome/browser/ui/views/subtle_notification_view.cc
@@ -8,7 +8,7 @@ #include "base/strings/string_split.h" #include "base/strings/utf_string_conversions.h" -#include "chrome/browser/ui/views/harmony/chrome_typography.h" +#include "chrome/browser/ui/views/chrome_typography.h" #include "third_party/skia/include/core/SkColor.h" #include "ui/accessibility/ax_node_data.h" #include "ui/base/resource/resource_bundle.h"
diff --git a/chrome/browser/ui/views/sync/bubble_sync_promo_view.cc b/chrome/browser/ui/views/sync/bubble_sync_promo_view.cc index a1c8585..eb9ea74 100644 --- a/chrome/browser/ui/views/sync/bubble_sync_promo_view.cc +++ b/chrome/browser/ui/views/sync/bubble_sync_promo_view.cc
@@ -8,7 +8,7 @@ #include "base/strings/string16.h" #include "chrome/browser/ui/sync/bubble_sync_promo_delegate.h" -#include "chrome/browser/ui/views/harmony/chrome_typography.h" +#include "chrome/browser/ui/views/chrome_typography.h" #include "components/signin/core/browser/account_info.h" #include "third_party/skia/include/core/SkColor.h" #include "ui/base/l10n/l10n_util.h"
diff --git a/chrome/browser/ui/views/sync/dice_bubble_sync_promo_view.cc b/chrome/browser/ui/views/sync/dice_bubble_sync_promo_view.cc index a9a877b5..c1e8a5463 100644 --- a/chrome/browser/ui/views/sync/dice_bubble_sync_promo_view.cc +++ b/chrome/browser/ui/views/sync/dice_bubble_sync_promo_view.cc
@@ -12,8 +12,8 @@ #include "chrome/browser/signin/account_consistency_mode_manager.h" #include "chrome/browser/signin/account_tracker_service_factory.h" #include "chrome/browser/signin/signin_ui_util.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" -#include "chrome/browser/ui/views/harmony/chrome_typography.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_typography.h" #include "chrome/browser/ui/views/sync/dice_signin_button_view.h" #include "components/signin/core/browser/account_tracker_service.h" #include "ui/base/l10n/l10n_util.h"
diff --git a/chrome/browser/ui/views/sync/one_click_signin_dialog_view.cc b/chrome/browser/ui/views/sync/one_click_signin_dialog_view.cc index 6069e44..8cdc3eae 100644 --- a/chrome/browser/ui/views/sync/one_click_signin_dialog_view.cc +++ b/chrome/browser/ui/views/sync/one_click_signin_dialog_view.cc
@@ -10,7 +10,7 @@ #include "base/logging.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_dialogs.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" #include "chrome/common/url_constants.h" #include "chrome/grit/chromium_strings.h" #include "chrome/grit/generated_resources.h"
diff --git a/chrome/browser/ui/views/sync/profile_signin_confirmation_dialog_views.cc b/chrome/browser/ui/views/sync/profile_signin_confirmation_dialog_views.cc index d4b67b9e..fca29e0f 100644 --- a/chrome/browser/ui/views/sync/profile_signin_confirmation_dialog_views.cc +++ b/chrome/browser/ui/views/sync/profile_signin_confirmation_dialog_views.cc
@@ -14,8 +14,8 @@ #include "chrome/browser/ui/browser_navigator.h" #include "chrome/browser/ui/browser_navigator_params.h" #include "chrome/browser/ui/browser_window.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" -#include "chrome/browser/ui/views/harmony/chrome_typography.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_typography.h" #include "chrome/grit/chromium_strings.h" #include "chrome/grit/generated_resources.h" #include "components/constrained_window/constrained_window_views.h"
diff --git a/chrome/browser/ui/views/tab_modal_confirm_dialog_views.cc b/chrome/browser/ui/views/tab_modal_confirm_dialog_views.cc index 4d0ee72..5ddf322 100644 --- a/chrome/browser/ui/views/tab_modal_confirm_dialog_views.cc +++ b/chrome/browser/ui/views/tab_modal_confirm_dialog_views.cc
@@ -9,7 +9,7 @@ #include "chrome/browser/ui/browser_dialogs.h" #include "chrome/browser/ui/browser_list.h" #include "chrome/browser/ui/browser_window.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" #include "chrome/browser/ui/views_mode_controller.h" #include "chrome/common/chrome_switches.h" #include "components/constrained_window/constrained_window_views.h"
diff --git a/chrome/browser/ui/views/tabs/new_tab_button.cc b/chrome/browser/ui/views/tabs/new_tab_button.cc index ebb5680d1..da441d2 100644 --- a/chrome/browser/ui/views/tabs/new_tab_button.cc +++ b/chrome/browser/ui/views/tabs/new_tab_button.cc
@@ -9,8 +9,8 @@ #include "chrome/browser/themes/theme_properties.h" #include "chrome/browser/ui/browser_list.h" #include "chrome/browser/ui/layout_constants.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" #include "chrome/browser/ui/views/feature_promos/new_tab_promo_bubble_view.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" #include "chrome/browser/ui/views/tabs/browser_tab_strip_controller.h" #include "chrome/browser/ui/views/tabs/tab_strip.h" #include "chrome/grit/theme_resources.h"
diff --git a/chrome/browser/ui/views/tabs/tab.cc b/chrome/browser/ui/views/tabs/tab.cc index d1bebe67..c27b910 100644 --- a/chrome/browser/ui/views/tabs/tab.cc +++ b/chrome/browser/ui/views/tabs/tab.cc
@@ -26,8 +26,8 @@ #include "chrome/browser/ui/tab_contents/core_tab_helper.h" #include "chrome/browser/ui/tabs/tab_utils.h" #include "chrome/browser/ui/view_ids.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" #include "chrome/browser/ui/views/frame/browser_view.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" #include "chrome/browser/ui/views/tabs/alert_indicator_button.h" #include "chrome/browser/ui/views/tabs/browser_tab_strip_controller.h" #include "chrome/browser/ui/views/tabs/tab_close_button.h"
diff --git a/chrome/browser/ui/views/task_manager_view.cc b/chrome/browser/ui/views/task_manager_view.cc index b285f6a..9096110d 100644 --- a/chrome/browser/ui/views/task_manager_view.cc +++ b/chrome/browser/ui/views/task_manager_view.cc
@@ -17,7 +17,7 @@ #include "chrome/browser/ui/browser_navigator_params.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/browser/ui/task_manager/task_manager_columns.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" #include "chrome/common/pref_names.h" #include "chrome/common/url_constants.h" #include "chrome/grit/chromium_strings.h"
diff --git a/chrome/browser/ui/views/harmony/textfield_layout.cc b/chrome/browser/ui/views/textfield_layout.cc similarity index 96% rename from chrome/browser/ui/views/harmony/textfield_layout.cc rename to chrome/browser/ui/views/textfield_layout.cc index 9c44c417..b2280201 100644 --- a/chrome/browser/ui/views/harmony/textfield_layout.cc +++ b/chrome/browser/ui/views/textfield_layout.cc
@@ -2,9 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/ui/views/harmony/textfield_layout.h" +#include "chrome/browser/ui/views/textfield_layout.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" #include "ui/views/controls/combobox/combobox.h" #include "ui/views/controls/label.h" #include "ui/views/controls/textfield/textfield.h"
diff --git a/chrome/browser/ui/views/harmony/textfield_layout.h b/chrome/browser/ui/views/textfield_layout.h similarity index 88% rename from chrome/browser/ui/views/harmony/textfield_layout.h rename to chrome/browser/ui/views/textfield_layout.h index cb250277..e6ea7a4 100644 --- a/chrome/browser/ui/views/harmony/textfield_layout.h +++ b/chrome/browser/ui/views/textfield_layout.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_UI_VIEWS_HARMONY_TEXTFIELD_LAYOUT_H_ -#define CHROME_BROWSER_UI_VIEWS_HARMONY_TEXTFIELD_LAYOUT_H_ +#ifndef CHROME_BROWSER_UI_VIEWS_TEXTFIELD_LAYOUT_H_ +#define CHROME_BROWSER_UI_VIEWS_TEXTFIELD_LAYOUT_H_ #include "base/strings/string16.h" @@ -41,4 +41,4 @@ std::unique_ptr<ui::ComboboxModel> model, int column_set_id); -#endif // CHROME_BROWSER_UI_VIEWS_HARMONY_TEXTFIELD_LAYOUT_H_ +#endif // CHROME_BROWSER_UI_VIEWS_TEXTFIELD_LAYOUT_H_
diff --git a/chrome/browser/ui/views/toolbar/browser_app_menu_button.cc b/chrome/browser/ui/views/toolbar/browser_app_menu_button.cc index 474f725..a8b12657 100644 --- a/chrome/browser/ui/views/toolbar/browser_app_menu_button.cc +++ b/chrome/browser/ui/views/toolbar/browser_app_menu_button.cc
@@ -20,8 +20,8 @@ #include "chrome/browser/ui/layout_constants.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/browser/ui/toolbar/app_menu_model.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" #include "chrome/browser/ui/views/extensions/browser_action_drag_data.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" #include "chrome/browser/ui/views/toolbar/app_menu.h" #include "chrome/browser/ui/views/toolbar/toolbar_button.h" #include "chrome/browser/ui/views/toolbar/toolbar_ink_drop_util.h"
diff --git a/chrome/browser/ui/views/toolbar/home_button.cc b/chrome/browser/ui/views/toolbar/home_button.cc index 555bd92..ed74f9c 100644 --- a/chrome/browser/ui/views/toolbar/home_button.cc +++ b/chrome/browser/ui/views/toolbar/home_button.cc
@@ -10,7 +10,7 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_dialogs.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" #include "chrome/common/pref_names.h" #include "chrome/grit/generated_resources.h" #include "components/prefs/pref_service.h"
diff --git a/chrome/browser/ui/views/toolbar/toolbar_action_view.cc b/chrome/browser/ui/views/toolbar/toolbar_action_view.cc index d310e70a..ec1e1f0 100644 --- a/chrome/browser/ui/views/toolbar/toolbar_action_view.cc +++ b/chrome/browser/ui/views/toolbar/toolbar_action_view.cc
@@ -15,7 +15,7 @@ #include "chrome/browser/ui/toolbar/toolbar_action_view_controller.h" #include "chrome/browser/ui/toolbar/toolbar_actions_bar.h" #include "chrome/browser/ui/view_ids.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" #include "chrome/browser/ui/views/toolbar/toolbar_ink_drop_util.h" #include "content/public/browser/notification_source.h" #include "ui/accessibility/ax_node_data.h"
diff --git a/chrome/browser/ui/views/toolbar/toolbar_actions_bar_bubble_views.cc b/chrome/browser/ui/views/toolbar/toolbar_actions_bar_bubble_views.cc index 3e6b6be8..dba58bd 100644 --- a/chrome/browser/ui/views/toolbar/toolbar_actions_bar_bubble_views.cc +++ b/chrome/browser/ui/views/toolbar/toolbar_actions_bar_bubble_views.cc
@@ -5,7 +5,7 @@ #include "chrome/browser/ui/views/toolbar/toolbar_actions_bar_bubble_views.h" #include "chrome/browser/ui/browser_dialogs.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" #include "chrome/grit/locale_settings.h" #include "components/vector_icons/vector_icons.h" #include "ui/base/resource/resource_bundle.h"
diff --git a/chrome/browser/ui/views/toolbar/toolbar_button.cc b/chrome/browser/ui/views/toolbar/toolbar_button.cc index f3d2418..87a384c6 100644 --- a/chrome/browser/ui/views/toolbar/toolbar_button.cc +++ b/chrome/browser/ui/views/toolbar/toolbar_button.cc
@@ -13,8 +13,8 @@ #include "chrome/browser/themes/theme_service_factory.h" #include "chrome/browser/ui/layout_constants.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" -#include "chrome/browser/ui/views/harmony/chrome_typography.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_typography.h" #include "chrome/browser/ui/views/toolbar/toolbar_ink_drop_util.h" #include "ui/accessibility/ax_node_data.h" #include "ui/base/material_design/material_design_controller.h"
diff --git a/chrome/browser/ui/views/translate/translate_bubble_view.cc b/chrome/browser/ui/views/translate/translate_bubble_view.cc index c36600b..4052cba 100644 --- a/chrome/browser/ui/views/translate/translate_bubble_view.cc +++ b/chrome/browser/ui/views/translate/translate_bubble_view.cc
@@ -25,7 +25,7 @@ #include "chrome/browser/ui/chrome_pages.h" #include "chrome/browser/ui/translate/translate_bubble_model_impl.h" #include "chrome/browser/ui/translate/translate_bubble_view_state_transition.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" #include "chrome/browser/ui/views_mode_controller.h" #include "chrome/common/url_constants.h" #include "chrome/grit/generated_resources.h"
diff --git a/chrome/browser/ui/views/try_chrome_dialog_win/try_chrome_dialog.cc b/chrome/browser/ui/views/try_chrome_dialog_win/try_chrome_dialog.cc index 845f196a..bd0210ce 100644 --- a/chrome/browser/ui/views/try_chrome_dialog_win/try_chrome_dialog.cc +++ b/chrome/browser/ui/views/try_chrome_dialog_win/try_chrome_dialog.cc
@@ -15,7 +15,7 @@ #include "base/time/time.h" #include "cc/paint/paint_flags.h" #include "chrome/app/vector_icons/vector_icons.h" -#include "chrome/browser/ui/views/harmony/chrome_typography.h" +#include "chrome/browser/ui/views/chrome_typography.h" #include "chrome/browser/ui/views/try_chrome_dialog_win/arrow_border.h" #include "chrome/browser/ui/views/try_chrome_dialog_win/button_layout.h" #include "chrome/browser/win/taskbar_icon_finder.h"
diff --git a/chrome/browser/ui/views/uninstall_view.cc b/chrome/browser/ui/views/uninstall_view.cc index c06458c8..489cd90 100644 --- a/chrome/browser/ui/views/uninstall_view.cc +++ b/chrome/browser/ui/views/uninstall_view.cc
@@ -9,7 +9,7 @@ #include "base/run_loop.h" #include "chrome/browser/shell_integration.h" #include "chrome/browser/ui/uninstall_browser_prompt.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" #include "chrome/common/chrome_result_codes.h" #include "chrome/grit/chromium_strings.h" #include "chrome/installer/util/shell_util.h"
diff --git a/chrome/browser/ui/views/update_recommended_message_box.cc b/chrome/browser/ui/views/update_recommended_message_box.cc index 3561365..ec4983e3 100644 --- a/chrome/browser/ui/views/update_recommended_message_box.cc +++ b/chrome/browser/ui/views/update_recommended_message_box.cc
@@ -7,7 +7,7 @@ #include "build/build_config.h" #include "chrome/browser/lifetime/application_lifetime.h" #include "chrome/browser/ui/browser_dialogs.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" #include "chrome/grit/chromium_strings.h" #include "components/constrained_window/constrained_window_views.h" #include "components/strings/grit/components_strings.h"
diff --git a/chrome/browser/ui/views/webauthn/authenticator_request_dialog_view.cc b/chrome/browser/ui/views/webauthn/authenticator_request_dialog_view.cc index 2680355..6facf5e 100644 --- a/chrome/browser/ui/views/webauthn/authenticator_request_dialog_view.cc +++ b/chrome/browser/ui/views/webauthn/authenticator_request_dialog_view.cc
@@ -6,8 +6,8 @@ #include "base/logging.h" #include "base/strings/string16.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" -#include "chrome/browser/ui/views/harmony/chrome_typography.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_typography.h" #include "chrome/browser/ui/views/webauthn/authenticator_request_sheet_view.h" #include "chrome/browser/ui/views/webauthn/sheet_view_factory.h" #include "chrome/browser/ui/webauthn/authenticator_request_sheet_model.h"
diff --git a/chrome/browser/ui/views/webauthn/authenticator_request_sheet_view.cc b/chrome/browser/ui/views/webauthn/authenticator_request_sheet_view.cc index 32edc622..34c2541 100644 --- a/chrome/browser/ui/views/webauthn/authenticator_request_sheet_view.cc +++ b/chrome/browser/ui/views/webauthn/authenticator_request_sheet_view.cc
@@ -4,8 +4,8 @@ #include "chrome/browser/ui/views/webauthn/authenticator_request_sheet_view.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" -#include "chrome/browser/ui/views/harmony/chrome_typography.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_typography.h" #include "chrome/browser/ui/webauthn/authenticator_request_sheet_model.h" #include "chrome/browser/webauthn/authenticator_request_dialog_model.h" #include "components/strings/grit/components_strings.h"
diff --git a/chrome/browser/ui/views/webauthn/transport_list_view.cc b/chrome/browser/ui/views/webauthn/transport_list_view.cc index 6a6f926a..2de7ad0 100644 --- a/chrome/browser/ui/views/webauthn/transport_list_view.cc +++ b/chrome/browser/ui/views/webauthn/transport_list_view.cc
@@ -7,8 +7,8 @@ #include "base/logging.h" #include "base/strings/string16.h" #include "chrome/app/vector_icons/vector_icons.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" -#include "chrome/browser/ui/views/harmony/chrome_typography.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_typography.h" #include "chrome/browser/ui/views/hover_button.h" #include "chrome/grit/generated_resources.h" #include "components/vector_icons/vector_icons.h"
diff --git a/chrome/browser/ui/views/webshare/webshare_target_picker_view.cc b/chrome/browser/ui/views/webshare/webshare_target_picker_view.cc index 62144ff..e89c8e4 100644 --- a/chrome/browser/ui/views/webshare/webshare_target_picker_view.cc +++ b/chrome/browser/ui/views/webshare/webshare_target_picker_view.cc
@@ -8,7 +8,7 @@ #include "base/strings/utf_string_conversions.h" #include "chrome/browser/ui/browser_dialogs.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" #include "chrome/grit/generated_resources.h" #include "components/constrained_window/constrained_window_views.h" #include "ui/base/l10n/l10n_util.h"
diff --git a/chrome/browser/ui/webui/chromeos/login/encryption_migration_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/encryption_migration_screen_handler.cc index f217e67..f7de717 100644 --- a/chrome/browser/ui/webui/chromeos/login/encryption_migration_screen_handler.cc +++ b/chrome/browser/ui/webui/chromeos/login/encryption_migration_screen_handler.cc
@@ -642,23 +642,30 @@ user_manager::UserManager::Get()->SaveUserOAuthStatus( user_context_.GetAccountId(), user_manager::User::OAUTH2_TOKEN_STATUS_INVALID); - cryptohome::AsyncMethodCaller::GetInstance()->AsyncRemove( - cryptohome::Identification(user_context_.GetAccountId()), - base::Bind(&EncryptionMigrationScreenHandler::OnRemoveCryptohome, - weak_ptr_factory_.GetWeakPtr())); + + const cryptohome::Identification cryptohome_id(user_context_.GetAccountId()); + + cryptohome::AccountIdentifier account_id_proto; + account_id_proto.set_account_id(cryptohome_id.id()); + + DBusThreadManager::Get()->GetCryptohomeClient()->RemoveEx( + account_id_proto, + base::BindOnce(&EncryptionMigrationScreenHandler::OnRemoveCryptohome, + weak_ptr_factory_.GetWeakPtr())); } void EncryptionMigrationScreenHandler::OnRemoveCryptohome( - bool success, - cryptohome::MountError return_code) { - LOG_IF(ERROR, !success) << "Removing cryptohome failed. return code: " - << return_code; - if (success) + base::Optional<cryptohome::BaseReply> reply) { + cryptohome::MountError error = BaseReplyToMountError(reply); + if (error == cryptohome::MOUNT_ERROR_NONE) { RecordRemoveCryptohomeResultSuccess(IsResumingIncompleteMigration(), IsArcKiosk()); - else + } else { + LOG(ERROR) << "Removing cryptohome failed. return code: " + << reply.value().error(); RecordRemoveCryptohomeResultFailure(IsResumingIncompleteMigration(), IsArcKiosk()); + } UpdateUIState(UIState::MIGRATION_FAILED); }
diff --git a/chrome/browser/ui/webui/chromeos/login/encryption_migration_screen_handler.h b/chrome/browser/ui/webui/chromeos/login/encryption_migration_screen_handler.h index f13f58d..74affe81 100644 --- a/chrome/browser/ui/webui/chromeos/login/encryption_migration_screen_handler.h +++ b/chrome/browser/ui/webui/chromeos/login/encryption_migration_screen_handler.h
@@ -108,7 +108,7 @@ void OnMountExistingVault(base::Optional<cryptohome::BaseReply> reply); // Removes cryptohome and shows the error screen after the removal finishes. void RemoveCryptohome(); - void OnRemoveCryptohome(bool success, cryptohome::MountError return_code); + void OnRemoveCryptohome(base::Optional<cryptohome::BaseReply> reply); // Creates authorization request for MountEx method using |user_context_|. cryptohome::AuthorizationRequest CreateAuthorizationRequest();
diff --git a/chrome/browser/ui/webui/chromeos/login/encryption_migration_screen_handler_unittest.cc b/chrome/browser/ui/webui/chromeos/login/encryption_migration_screen_handler_unittest.cc index 2e0ac71..537629d 100644 --- a/chrome/browser/ui/webui/chromeos/login/encryption_migration_screen_handler_unittest.cc +++ b/chrome/browser/ui/webui/chromeos/login/encryption_migration_screen_handler_unittest.cc
@@ -299,10 +299,6 @@ scoped_task_environment_.RunUntilIdle(); - EXPECT_CALL( - *mock_async_method_caller_, - AsyncRemove(cryptohome::Identification(user_context_.GetAccountId()), - _ /* callback */)); encryption_migration_screen_handler_->testing_tick_clock()->Advance( base::TimeDelta::FromMinutes(1)); fake_cryptohome_client_->NotifyDircryptoMigrationProgress(
diff --git a/chrome/browser/ui/webui/interventions_internals/interventions_internals_page_handler.cc b/chrome/browser/ui/webui/interventions_internals/interventions_internals_page_handler.cc index 7acc8d0..ae7afce 100644 --- a/chrome/browser/ui/webui/interventions_internals/interventions_internals_page_handler.cc +++ b/chrome/browser/ui/webui/interventions_internals/interventions_internals_page_handler.cc
@@ -12,12 +12,13 @@ #include "base/metrics/field_trial_params.h" #include "base/time/time.h" #include "build/build_config.h" +#include "chrome/browser/browser_process.h" #include "chrome/browser/flag_descriptions.h" -#include "chrome/browser/net/nqe/ui_network_quality_estimator_service.h" #include "chrome/common/chrome_switches.h" #include "components/previews/core/previews_experiments.h" #include "components/previews/core/previews_switches.h" #include "net/nqe/network_quality_estimator_params.h" +#include "services/network/public/cpp/network_quality_tracker.h" #include "services/network/public/cpp/network_switches.h" namespace { @@ -99,11 +100,9 @@ InterventionsInternalsPageHandler::InterventionsInternalsPageHandler( mojom::InterventionsInternalsPageHandlerRequest request, - previews::PreviewsUIService* previews_ui_service, - UINetworkQualityEstimatorService* ui_nqe_service) + previews::PreviewsUIService* previews_ui_service) : binding_(this, std::move(request)), previews_ui_service_(previews_ui_service), - ui_nqe_service_(ui_nqe_service), current_estimated_ect_(net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN) { logger_ = previews_ui_service_->previews_logger(); DCHECK(logger_); @@ -112,7 +111,8 @@ InterventionsInternalsPageHandler::~InterventionsInternalsPageHandler() { DCHECK(logger_); logger_->RemoveObserver(this); - ui_nqe_service_->RemoveEffectiveConnectionTypeObserver(this); + g_browser_process->network_quality_tracker() + ->RemoveEffectiveConnectionTypeObserver(this); } void InterventionsInternalsPageHandler::SetClientPage( @@ -120,7 +120,8 @@ page_ = std::move(page); DCHECK(page_); logger_->AddAndNotifyObserver(this); - ui_nqe_service_->AddEffectiveConnectionTypeObserver(this); + g_browser_process->network_quality_tracker() + ->AddEffectiveConnectionTypeObserver(this); } void InterventionsInternalsPageHandler::OnEffectiveConnectionTypeChanged(
diff --git a/chrome/browser/ui/webui/interventions_internals/interventions_internals_page_handler.h b/chrome/browser/ui/webui/interventions_internals/interventions_internals_page_handler.h index 55c20dcd..49a50b6 100644 --- a/chrome/browser/ui/webui/interventions_internals/interventions_internals_page_handler.h +++ b/chrome/browser/ui/webui/interventions_internals/interventions_internals_page_handler.h
@@ -15,19 +15,16 @@ #include "components/previews/core/previews_logger_observer.h" #include "mojo/public/cpp/bindings/binding.h" #include "net/nqe/effective_connection_type.h" -#include "net/nqe/effective_connection_type_observer.h" - -class UINetworkQualityEstimatorService; +#include "services/network/public/cpp/network_quality_tracker.h" class InterventionsInternalsPageHandler : public previews::PreviewsLoggerObserver, - public net::EffectiveConnectionTypeObserver, + public network::NetworkQualityTracker::EffectiveConnectionTypeObserver, public mojom::InterventionsInternalsPageHandler { public: InterventionsInternalsPageHandler( mojom::InterventionsInternalsPageHandlerRequest request, - previews::PreviewsUIService* previews_ui_service, - UINetworkQualityEstimatorService* ui_nqe_service); + previews::PreviewsUIService* previews_ui_service); ~InterventionsInternalsPageHandler() override; // mojom::InterventionsInternalsPageHandler: @@ -47,7 +44,7 @@ void OnLastObserverRemove() override; private: - // net::EffectiveConnectionTypeObserver: + // network::NetworkQualityTracker::EffectiveConnectionTypeObserver: void OnEffectiveConnectionTypeChanged( net::EffectiveConnectionType type) override; @@ -61,10 +58,6 @@ // guaranteed to outlive |this|. previews::PreviewsUIService* previews_ui_service_; - // A pointer to the UINetworkQualityEsitmatorService, guaranteed to outlive - // |this|. - UINetworkQualityEstimatorService* ui_nqe_service_; - // The current estimated effective connection type. net::EffectiveConnectionType current_estimated_ect_;
diff --git a/chrome/browser/ui/webui/interventions_internals/interventions_internals_page_handler_unittest.cc b/chrome/browser/ui/webui/interventions_internals/interventions_internals_page_handler_unittest.cc index a1312af..46c92a66 100644 --- a/chrome/browser/ui/webui/interventions_internals/interventions_internals_page_handler_unittest.cc +++ b/chrome/browser/ui/webui/interventions_internals/interventions_internals_page_handler_unittest.cc
@@ -22,7 +22,6 @@ #include "base/time/default_clock.h" #include "build/build_config.h" #include "chrome/browser/flag_descriptions.h" -#include "chrome/browser/net/nqe/ui_network_quality_estimator_service.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/webui/interventions_internals/interventions_internals.mojom.h" #include "chrome/common/chrome_constants.h" @@ -191,27 +190,6 @@ bool remove_is_called_; }; -// Mock class to test interaction between PageHandler and the -// UINetworkQualityEstimatorService. -class TestUINetworkQualityEstimatorService - : public UINetworkQualityEstimatorService { - public: - explicit TestUINetworkQualityEstimatorService(Profile* profile) - : UINetworkQualityEstimatorService(profile), remove_is_called_(false) {} - - // UINetworkQualityEstimatorService: - void RemoveEffectiveConnectionTypeObserver( - net::EffectiveConnectionTypeObserver* observer) override { - remove_is_called_ = true; - } - - bool RemovedObserverIsCalled() const { return remove_is_called_; } - - private: - // Check if the observer removed itself from the observer list. - bool remove_is_called_; -}; - // A dummy class to setup PreviewsUIService. class TestPreviewsDeciderImpl : public previews::PreviewsDeciderImpl { public: @@ -276,16 +254,11 @@ std::make_unique<TestPreviewsUIService>(&io_data, std::move(logger)); ASSERT_TRUE(profile_manager_.SetUp()); - TestingProfile* test_profile = - profile_manager_.CreateTestingProfile(chrome::kInitialProfile); - ui_nqe_service_ = - std::make_unique<TestUINetworkQualityEstimatorService>(test_profile); mojom::InterventionsInternalsPageHandlerPtr page_handler_ptr; handler_request_ = mojo::MakeRequest(&page_handler_ptr); page_handler_ = std::make_unique<InterventionsInternalsPageHandler>( - std::move(handler_request_), previews_ui_service_.get(), - ui_nqe_service_.get()); + std::move(handler_request_), previews_ui_service_.get()); mojom::InterventionsInternalsPagePtr page_ptr; page_request_ = mojo::MakeRequest(&page_ptr); @@ -306,7 +279,6 @@ TestPreviewsLogger* logger_; std::unique_ptr<TestPreviewsUIService> previews_ui_service_; - std::unique_ptr<TestUINetworkQualityEstimatorService> ui_nqe_service_; // InterventionsInternalPageHandler's variables. mojom::InterventionsInternalsPageHandlerRequest handler_request_; @@ -650,6 +622,13 @@ base::RunLoop().RunUntilIdle(); mojom::MessageLogPtr* actual = page_->message(); + // Discard any messages generated by network quality tracker. + while ((*actual)->type == "ECT Changed") { + page_handler_->OnNewMessageLogAdded(message); + base::RunLoop().RunUntilIdle(); + + actual = page_->message(); + } EXPECT_EQ(message.event_type, (*actual)->type); EXPECT_EQ(message.event_description, (*actual)->description); EXPECT_EQ(message.url, (*actual)->url); @@ -661,10 +640,8 @@ TEST_F(InterventionsInternalsPageHandlerTest, ObserverIsRemovedWhenDestroyed) { EXPECT_FALSE(logger_->RemovedObserverIsCalled()); - EXPECT_FALSE(ui_nqe_service_->RemovedObserverIsCalled()); page_handler_.reset(); EXPECT_TRUE(logger_->RemovedObserverIsCalled()); - EXPECT_TRUE(ui_nqe_service_->RemovedObserverIsCalled()); } TEST_F(InterventionsInternalsPageHandlerTest, OnNewBlacklistedHostPostToPage) {
diff --git a/chrome/browser/ui/webui/interventions_internals/interventions_internals_ui.cc b/chrome/browser/ui/webui/interventions_internals/interventions_internals_ui.cc index 434ebf8..70172891 100644 --- a/chrome/browser/ui/webui/interventions_internals/interventions_internals_ui.cc +++ b/chrome/browser/ui/webui/interventions_internals/interventions_internals_ui.cc
@@ -8,8 +8,6 @@ #include <utility> #include <vector> -#include "chrome/browser/net/nqe/ui_network_quality_estimator_service.h" -#include "chrome/browser/net/nqe/ui_network_quality_estimator_service_factory.h" #include "chrome/browser/previews/previews_service.h" #include "chrome/browser/previews/previews_service_factory.h" #include "chrome/browser/profiles/profile.h" @@ -58,8 +56,6 @@ } content::WebUIDataSource::Add(profile, GetSource()); previews_ui_service_ = previews_service->previews_ui_service(); - ui_nqe_service_ = - UINetworkQualityEstimatorServiceFactory::GetForProfile(profile); AddHandlerToRegistry(base::BindRepeating( &InterventionsInternalsUI::BindInterventionsInternalsPageHandler, base::Unretained(this))); @@ -70,7 +66,6 @@ void InterventionsInternalsUI::BindInterventionsInternalsPageHandler( mojom::InterventionsInternalsPageHandlerRequest request) { DCHECK(previews_ui_service_); - DCHECK(ui_nqe_service_); page_handler_.reset(new InterventionsInternalsPageHandler( - std::move(request), previews_ui_service_, ui_nqe_service_)); + std::move(request), previews_ui_service_)); }
diff --git a/chrome/browser/ui/webui/interventions_internals/interventions_internals_ui.h b/chrome/browser/ui/webui/interventions_internals/interventions_internals_ui.h index 28a0150d..b284a9d 100644 --- a/chrome/browser/ui/webui/interventions_internals/interventions_internals_ui.h +++ b/chrome/browser/ui/webui/interventions_internals/interventions_internals_ui.h
@@ -14,8 +14,6 @@ class PreviewsUIService; } // namespace previews -class UINetworkQualityEstimatorService; - // The WebUI for chrome://interventions-internals. class InterventionsInternalsUI : public ui::MojoWebUIController { public: @@ -29,10 +27,6 @@ // The PreviewsUIService associated with this UI. previews::PreviewsUIService* previews_ui_service_; - // The network quality estimator service for getting the estimate effective - // conntection type. - UINetworkQualityEstimatorService* ui_nqe_service_; - std::unique_ptr<InterventionsInternalsPageHandler> page_handler_; DISALLOW_COPY_AND_ASSIGN(InterventionsInternalsUI);
diff --git a/chrome/browser/ui/window_sizer/window_sizer_ash_uitest.cc b/chrome/browser/ui/window_sizer/window_sizer_ash_uitest.cc index ce3a394f..f75a9a5f 100644 --- a/chrome/browser/ui/window_sizer/window_sizer_ash_uitest.cc +++ b/chrome/browser/ui/window_sizer/window_sizer_ash_uitest.cc
@@ -71,8 +71,8 @@ ChromeLauncherController::instance()->FlushForTesting(); // Move the cursor up to the "New window" menu option - assumes menu content. - generator.MoveMouseBy(0, -5 * views::MenuConfig::instance().item_min_height - - views::MenuConfig::instance().separator_height); + generator.MoveMouseBy( + 0, -3 * views::MenuConfig::instance().touchable_menu_height); generator.ReleaseRightButton(); // Ash notifies Chrome's ShelfItemDelegate that the menu item was selected.
diff --git a/chrome/browser/vr/BUILD.gn b/chrome/browser/vr/BUILD.gn index c28747f..102639e 100644 --- a/chrome/browser/vr/BUILD.gn +++ b/chrome/browser/vr/BUILD.gn
@@ -214,6 +214,9 @@ component("vr_common") { sources = [ + "base_compositor_delegate.cc", + "base_compositor_delegate.h", + "compositor_delegate.h", "controller_delegate.h", "controller_delegate_for_testing.cc", "controller_delegate_for_testing.h", @@ -221,8 +224,6 @@ "fps_meter.h", "gesture_detector.cc", "gesture_detector.h", - "graphics_delegate.cc", - "graphics_delegate.h", "render_loop.cc", "render_loop.h", "render_loop_browser_interface.h",
diff --git a/chrome/browser/vr/base_compositor_delegate.cc b/chrome/browser/vr/base_compositor_delegate.cc new file mode 100644 index 0000000..bbd57d9 --- /dev/null +++ b/chrome/browser/vr/base_compositor_delegate.cc
@@ -0,0 +1,59 @@ +// Copyright 2018 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 "chrome/browser/vr/base_compositor_delegate.h" + +#include <utility> + +#include "ui/gl/gl_context.h" +#include "ui/gl/gl_share_group.h" +#include "ui/gl/gl_surface.h" +#include "ui/gl/init/gl_factory.h" + +namespace vr { + +BaseCompositorDelegate::BaseCompositorDelegate() {} + +BaseCompositorDelegate::~BaseCompositorDelegate() { + if (curr_context_id_ != kNone) + contexts_[curr_context_id_]->ReleaseCurrent(surface_.get()); +} + +bool BaseCompositorDelegate::Initialize( + const scoped_refptr<gl::GLSurface>& surface) { + surface_ = surface; + share_group_ = base::MakeRefCounted<gl::GLShareGroup>(); + for (auto& context : contexts_) { + context = gl::init::CreateGLContext(share_group_.get(), surface_.get(), + gl::GLContextAttribs()); + if (!context.get()) { + LOG(ERROR) << "gl::init::CreateGLContext failed"; + return false; + } + } + return MakeContextCurrent(kMainContext); +} + +bool BaseCompositorDelegate::RunInSkiaContext(SkiaContextCallback callback) { + DCHECK_EQ(curr_context_id_, kMainContext); + if (!MakeContextCurrent(kSkiaContext)) + return false; + std::move(callback).Run(); + return MakeContextCurrent(kMainContext); +} + +bool BaseCompositorDelegate::MakeContextCurrent(ContextId context_id) { + DCHECK(context_id > kNone && context_id < kNumContexts); + if (curr_context_id_ == context_id) + return true; + auto& context = contexts_[context_id]; + if (!context->MakeCurrent(surface_.get())) { + LOG(ERROR) << "gl::GLContext::MakeCurrent() failed"; + return false; + } + curr_context_id_ = context_id; + return true; +} + +} // namespace vr
diff --git a/chrome/browser/vr/base_compositor_delegate.h b/chrome/browser/vr/base_compositor_delegate.h new file mode 100644 index 0000000..2d83b08b --- /dev/null +++ b/chrome/browser/vr/base_compositor_delegate.h
@@ -0,0 +1,44 @@ +// Copyright 2018 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 CHROME_BROWSER_VR_BASE_COMPOSITOR_DELEGATE_H_ +#define CHROME_BROWSER_VR_BASE_COMPOSITOR_DELEGATE_H_ + +#include "base/macros.h" +#include "base/memory/scoped_refptr.h" +#include "chrome/browser/vr/compositor_delegate.h" + +namespace gl { +class GLContext; +class GLShareGroup; +class GLSurface; +} // namespace gl + +namespace vr { + +class VR_EXPORT BaseCompositorDelegate : public CompositorDelegate { + public: + BaseCompositorDelegate(); + ~BaseCompositorDelegate() override; + + // CompositorDelegate implementation. + bool Initialize(const scoped_refptr<gl::GLSurface>& surface) override; + bool RunInSkiaContext(SkiaContextCallback callback) override; + + private: + enum ContextId { kNone = -1, kMainContext, kSkiaContext, kNumContexts }; + + bool MakeContextCurrent(ContextId context_id); + + scoped_refptr<gl::GLSurface> surface_; + scoped_refptr<gl::GLShareGroup> share_group_; + scoped_refptr<gl::GLContext> contexts_[kNumContexts]; + ContextId curr_context_id_ = kNone; + + DISALLOW_COPY_AND_ASSIGN(BaseCompositorDelegate); +}; + +} // namespace vr + +#endif // CHROME_BROWSER_VR_BASE_COMPOSITOR_DELEGATE_H_
diff --git a/chrome/browser/vr/compositor_delegate.h b/chrome/browser/vr/compositor_delegate.h new file mode 100644 index 0000000..c10a8ee --- /dev/null +++ b/chrome/browser/vr/compositor_delegate.h
@@ -0,0 +1,29 @@ +// Copyright 2018 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 CHROME_BROWSER_VR_COMPOSITOR_DELEGATE_H_ +#define CHROME_BROWSER_VR_COMPOSITOR_DELEGATE_H_ + +#include "chrome/browser/vr/vr_export.h" + +namespace gl { +class GLSurface; +} // namespace gl + +namespace vr { + +class VR_EXPORT CompositorDelegate { + public: + typedef base::OnceCallback<void()> SkiaContextCallback; + + virtual ~CompositorDelegate() {} + + // These methods return true when succeeded. + virtual bool Initialize(const scoped_refptr<gl::GLSurface>& surface) = 0; + virtual bool RunInSkiaContext(SkiaContextCallback callback) = 0; +}; + +} // namespace vr + +#endif // CHROME_BROWSER_VR_COMPOSITOR_DELEGATE_H_
diff --git a/chrome/browser/vr/elements/platform_ui_element.cc b/chrome/browser/vr/elements/platform_ui_element.cc index 5b548289..02742fe 100644 --- a/chrome/browser/vr/elements/platform_ui_element.cc +++ b/chrome/browser/vr/elements/platform_ui_element.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 "chrome/browser/vr/elements/content_element.h" +#include "chrome/browser/vr/elements/platform_ui_element.h" #include "chrome/browser/vr/platform_ui_input_delegate.h" #include "chrome/browser/vr/ui_element_renderer.h"
diff --git a/chrome/browser/vr/graphics_delegate.cc b/chrome/browser/vr/graphics_delegate.cc deleted file mode 100644 index 99523a5..0000000 --- a/chrome/browser/vr/graphics_delegate.cc +++ /dev/null
@@ -1,55 +0,0 @@ -// Copyright 2018 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 "chrome/browser/vr/graphics_delegate.h" - -#include "ui/gl/gl_context.h" -#include "ui/gl/gl_share_group.h" -#include "ui/gl/gl_surface.h" -#include "ui/gl/init/gl_factory.h" - -namespace vr { - -GraphicsDelegate::GraphicsDelegate(const scoped_refptr<gl::GLSurface>& surface) - : surface_(surface) {} - -GraphicsDelegate::~GraphicsDelegate() { - if (curr_context_id_ != NONE) - contexts_[curr_context_id_]->ReleaseCurrent(surface_.get()); -} - -bool GraphicsDelegate::Initialize() { - share_group_ = base::MakeRefCounted<gl::GLShareGroup>(); - for (auto& context : contexts_) { - context = gl::init::CreateGLContext(share_group_.get(), surface_.get(), - gl::GLContextAttribs()); - if (!context.get()) { - LOG(ERROR) << "gl::init::CreateGLContext failed"; - return false; - } - } - return MakeMainContextCurrent(); -} - -bool GraphicsDelegate::MakeMainContextCurrent() { - return MakeContextCurrent(MAIN_CONTEXT); -} - -bool GraphicsDelegate::MakeSkiaContextCurrent() { - return MakeContextCurrent(SKIA_CONTEXT); -} - -bool GraphicsDelegate::MakeContextCurrent(ContextId context_id) { - DCHECK(context_id > NONE && context_id < NUM_CONTEXTS); - if (curr_context_id_ == context_id) - return true; - auto& context = contexts_[context_id]; - if (!context->MakeCurrent(surface_.get())) { - LOG(ERROR) << "gl::GLContext::MakeCurrent() failed"; - return false; - } - return true; -} - -} // namespace vr
diff --git a/chrome/browser/vr/graphics_delegate.h b/chrome/browser/vr/graphics_delegate.h deleted file mode 100644 index 719784b..0000000 --- a/chrome/browser/vr/graphics_delegate.h +++ /dev/null
@@ -1,44 +0,0 @@ -// Copyright 2018 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 CHROME_BROWSER_VR_GRAPHICS_DELEGATE_H_ -#define CHROME_BROWSER_VR_GRAPHICS_DELEGATE_H_ - -#include "base/macros.h" -#include "base/memory/scoped_refptr.h" -#include "chrome/browser/vr/vr_export.h" -#include "ui/gfx/native_widget_types.h" - -namespace gl { -class GLContext; -class GLShareGroup; -class GLSurface; -} // namespace gl - -namespace vr { - -class VR_EXPORT GraphicsDelegate { - public: - explicit GraphicsDelegate(const scoped_refptr<gl::GLSurface>& surface); - ~GraphicsDelegate(); - bool Initialize(); - bool MakeMainContextCurrent(); - bool MakeSkiaContextCurrent(); - - private: - enum ContextId { NONE = -1, MAIN_CONTEXT, SKIA_CONTEXT, NUM_CONTEXTS }; - - bool MakeContextCurrent(ContextId context_id); - - scoped_refptr<gl::GLSurface> surface_; - scoped_refptr<gl::GLShareGroup> share_group_; - scoped_refptr<gl::GLContext> contexts_[NUM_CONTEXTS]; - ContextId curr_context_id_ = NONE; - - DISALLOW_COPY_AND_ASSIGN(GraphicsDelegate); -}; - -} // namespace vr - -#endif // CHROME_BROWSER_VR_GRAPHICS_DELEGATE_H_
diff --git a/chrome/browser/vr/render_loop.cc b/chrome/browser/vr/render_loop.cc index f748f20..7401ef16 100644 --- a/chrome/browser/vr/render_loop.cc +++ b/chrome/browser/vr/render_loop.cc
@@ -8,8 +8,8 @@ #include "base/time/time.h" #include "base/trace_event/common/trace_event_common.h" +#include "chrome/browser/vr/compositor_delegate.h" #include "chrome/browser/vr/controller_delegate_for_testing.h" -#include "chrome/browser/vr/graphics_delegate.h" #include "chrome/browser/vr/input_event.h" #include "chrome/browser/vr/model/controller_model.h" #include "chrome/browser/vr/model/reticle_model.h" @@ -22,9 +22,11 @@ RenderLoop::RenderLoop(std::unique_ptr<UiInterface> ui, RenderLoopBrowserInterface* browser, + CompositorDelegate* compositor_delegate, size_t sliding_time_size) : ui_(std::move(ui)), browser_(browser), + compositor_delegate_(compositor_delegate), ui_processing_time_(sliding_time_size), ui_controller_update_time_(sliding_time_size) {} RenderLoop::~RenderLoop() = default; @@ -53,7 +55,6 @@ base::TimeTicks current_time, FrameType frame_type) { TRACE_EVENT0("gpu", __func__); - DCHECK(graphics_delegate_); // Update the render position of all UI elements. base::TimeTicks timing_start = base::TimeTicks::Now(); @@ -65,12 +66,8 @@ controller_time = ProcessControllerInput(render_info, current_time); if (ui_->SceneHasDirtyTextures()) { - if (!graphics_delegate_->MakeSkiaContextCurrent()) { - ForceExitVr(); - return; - } - ui_->UpdateSceneTextures(); - if (!graphics_delegate_->MakeMainContextCurrent()) { + if (!compositor_delegate_->RunInSkiaContext(base::BindOnce( + &UiInterface::UpdateSceneTextures, base::Unretained(ui_.get())))) { ForceExitVr(); return; }
diff --git a/chrome/browser/vr/render_loop.h b/chrome/browser/vr/render_loop.h index bb7bfb42..b59be28 100644 --- a/chrome/browser/vr/render_loop.h +++ b/chrome/browser/vr/render_loop.h
@@ -21,7 +21,7 @@ namespace vr { enum class VrUiTestActivityResult; -class GraphicsDelegate; +class CompositorDelegate; class RenderLoopBrowserInterface; class UiInterface; struct ControllerTestInput; @@ -40,6 +40,7 @@ explicit RenderLoop(std::unique_ptr<UiInterface> ui, RenderLoopBrowserInterface* browser, + CompositorDelegate* compositor_delegate, size_t sliding_time_size); virtual ~RenderLoop(); @@ -73,7 +74,6 @@ } std::unique_ptr<UiInterface> ui_; - std::unique_ptr<GraphicsDelegate> graphics_delegate_; private: base::TimeDelta ProcessControllerInput(const RenderInfo& render_info, @@ -85,6 +85,7 @@ RenderLoopBrowserInterface* browser_; + CompositorDelegate* compositor_delegate_; std::unique_ptr<ControllerDelegate> controller_delegate_; std::unique_ptr<ControllerDelegate> controller_delegate_for_testing_; bool using_controller_delegate_for_testing_ = false;
diff --git a/chrome/browser/vr/service/vr_service_impl.cc b/chrome/browser/vr/service/vr_service_impl.cc index 04e0a3f..e9df1ae 100644 --- a/chrome/browser/vr/service/vr_service_impl.cc +++ b/chrome/browser/vr/service/vr_service_impl.cc
@@ -25,8 +25,8 @@ content::WebContents::FromRenderFrameHost(render_frame_host)), render_frame_host_(render_frame_host) { DCHECK(render_frame_host_); - // TODO(crbug/701027): make sure that client_ is never null by initializing it - // in the constructor. + + XRRuntimeManager::GetInstance()->AddService(this); } // Constructor for testing. @@ -53,25 +53,44 @@ mojo::MakeStrongBinding(std::move(vr_service_impl), std::move(request))); } -void VRServiceImpl::SetClient(device::mojom::VRServiceClientPtr service_client, - SetClientCallback callback) { - DCHECK(!client_.get()); - client_ = std::move(service_client); - set_client_callback_ = std::move(callback); - - // Once a client has been connected AddService will force any VRDisplays to - // send ConnectDevice to it so that it's populated with the currently active - // displays. Thereafter it will stay up to date by virtue of listening for new - // connected events. - XRRuntimeManager::GetInstance()->AddService(this); +void VRServiceImpl::InitializationComplete() { + // device_ is returned after all providers have initialized. This means that + // we can correctly answer SupportsSession, and can provide correct display + // capabilities. + initialization_complete_ = true; + MaybeReturnDevice(); } -void VRServiceImpl::InitializationComplete() { - // device_ is added after all providers have initialized. This means that we - // can correctly answer SupportsSession, and can provide correct display - // capabilities. - device_ = std::make_unique<XRDeviceImpl>(render_frame_host_, client_.get()); - base::ResetAndReturn(&set_client_callback_).Run(); +void VRServiceImpl::RequestDevice(RequestDeviceCallback callback) { + if (request_device_callback_) { + // There should only be one pending VRService::RequestDevice at a time. + // If request device is called multiple times on the renderer side, the + // requests should be queued there and returned when this single call + // returns. + mojo::ReportBadMessage( + "Request device called before previous call completed."); + } + + request_device_callback_ = std::move(callback); + MaybeReturnDevice(); +} + +void VRServiceImpl::SetClient(device::mojom::VRServiceClientPtr client) { + client_ = std::move(client); +} + +void VRServiceImpl::MaybeReturnDevice() { + if (request_device_callback_ && initialization_complete_) { + // If we are requesting a new device, destroy the old one and create a new + // one. We assume that the renderer will use the old device until it has + // been destroyed, so it is safe to destroy it on the browser side. + device::mojom::XRDevicePtr device; + if (XRRuntimeManager::GetInstance()->HasAnyRuntime()) { + device_ = std::make_unique<XRDeviceImpl>(render_frame_host_, + mojo::MakeRequest(&device)); + } + base::ResetAndReturn(&request_device_callback_).Run(std::move(device)); + } } void VRServiceImpl::ConnectRuntime(BrowserXRRuntime* runtime) { @@ -82,17 +101,26 @@ if (device_) { device_->OnRuntimeAvailable(runtime); } + + if (client_) { + client_->OnDeviceChanged(); + } } void VRServiceImpl::RemoveRuntime(BrowserXRRuntime* runtime) { if (device_) { device_->OnRuntimeRemoved(runtime); } + + if (client_) { + client_->OnDeviceChanged(); + } } -void VRServiceImpl::SetListeningForActivate(bool listening) { +void VRServiceImpl::SetListeningForActivate( + device::mojom::VRDisplayClientPtr client) { if (device_) - device_->SetListeningForActivate(listening); + device_->SetListeningForActivate(std::move(client)); } void VRServiceImpl::OnWebContentsFocused(content::RenderWidgetHost* host) {
diff --git a/chrome/browser/vr/service/vr_service_impl.h b/chrome/browser/vr/service/vr_service_impl.h index 52f622f..ef529b10 100644 --- a/chrome/browser/vr/service/vr_service_impl.h +++ b/chrome/browser/vr/service/vr_service_impl.h
@@ -21,11 +21,8 @@ class XRDeviceImpl; class BrowserXRRuntime; -// Browser process representation of a WebVR site session. Instantiated through -// Mojo once the user loads a page containing WebVR. -// It instantiates a VRDisplayImpl for each newly connected VRDisplay and sends -// the display's info to the render process through its connected -// mojom::VRServiceClient. +// Browser process implementation of the VRService mojo interface. Instantiated +// through Mojo once the user loads a page containing WebXR. class VR_EXPORT VRServiceImpl : public device::mojom::VRService, content::WebContentsObserver { public: @@ -36,9 +33,8 @@ device::mojom::VRServiceRequest request); // device::mojom::VRService implementation - // Adds this service to the XRRuntimeManager. - void SetClient(device::mojom::VRServiceClientPtr service_client, - SetClientCallback callback) override; + void RequestDevice(RequestDeviceCallback callback) override; + void SetClient(device::mojom::VRServiceClientPtr service_client) override; // Tells the renderer that a new VR device is available. void ConnectRuntime(BrowserXRRuntime* device); @@ -56,7 +52,8 @@ void SetBinding(mojo::StrongBindingPtr<VRService> binding); // device::mojom::VRService implementation - void SetListeningForActivate(bool listening) override; + void SetListeningForActivate( + device::mojom::VRDisplayClientPtr client) override; // content::WebContentsObserver implementation void OnWebContentsFocused(content::RenderWidgetHost* host) override; @@ -65,11 +62,14 @@ void OnWebContentsFocusChanged(content::RenderWidgetHost* host, bool focused); + void MaybeReturnDevice(); + std::unique_ptr<XRDeviceImpl> device_; - SetClientCallback set_client_callback_; + RequestDeviceCallback request_device_callback_; device::mojom::VRServiceClientPtr client_; content::RenderFrameHost* render_frame_host_; mojo::StrongBindingPtr<VRService> binding_; + bool initialization_complete_ = false; DISALLOW_COPY_AND_ASSIGN(VRServiceImpl); };
diff --git a/chrome/browser/vr/service/xr_device_impl.cc b/chrome/browser/vr/service/xr_device_impl.cc index 8c535dbd..c53bb26 100644 --- a/chrome/browser/vr/service/xr_device_impl.cc +++ b/chrome/browser/vr/service/xr_device_impl.cc
@@ -104,7 +104,7 @@ } XRDeviceImpl::XRDeviceImpl(content::RenderFrameHost* render_frame_host, - device::mojom::VRServiceClient* service_client) + device::mojom::XRDeviceRequest request) : // TODO(https://crbug.com/846392): render_frame_host can be null because // of a test, not because a XRDeviceImpl can be created without it. in_focused_frame_( @@ -112,20 +112,10 @@ render_frame_host_(render_frame_host), binding_(this), weak_ptr_factory_(this) { - device::mojom::VRDisplayInfoPtr display_info = GetCurrentVRDisplayInfo(); - if (!display_info) { - return; - } - - // Tell blink that we are available. - device::mojom::XRDevicePtr device_ptr; - binding_.Bind(mojo::MakeRequest(&device_ptr)); - service_client->OnDisplayConnected(std::move(device_ptr), - mojo::MakeRequest(&client_), - std::move(display_info)); + binding_.Bind(std::move(request)); } -void XRDeviceImpl::OnMagicWindowSessionCreated( +void XRDeviceImpl::OnNonImmersiveSessionCreated( device::mojom::XRDevice::RequestSessionCallback callback, device::mojom::XRSessionPtr session, device::mojom::XRSessionControllerPtr controller) { @@ -139,6 +129,22 @@ magic_window_controllers_.AddPtr(std::move(controller)); + OnSessionCreated(std::move(callback), std::move(session)); +} + +void XRDeviceImpl::OnSessionCreated( + device::mojom::XRDevice::RequestSessionCallback callback, + device::mojom::XRSessionPtr session) { + if (!session) { + std::move(callback).Run(nullptr); + return; + } + + device::mojom::XRSessionClientPtr client; + session->client_request = mojo::MakeRequest(&client); + + session_clients_.AddPtr(std::move(client)); + std::move(callback).Run(std::move(session)); } @@ -198,29 +204,27 @@ ReportRequestPresent(); } + base::OnceCallback<void(device::mojom::XRSessionPtr)> immersive_callback = + base::BindOnce(&XRDeviceImpl::OnSessionCreated, + weak_ptr_factory_.GetWeakPtr(), std::move(callback)); runtime->RequestSession(this, std::move(runtime_options), - std::move(callback)); + std::move(immersive_callback)); } else { base::OnceCallback<void(device::mojom::XRSessionPtr, device::mojom::XRSessionControllerPtr)> - magic_window_callback = - base::BindOnce(&XRDeviceImpl::OnMagicWindowSessionCreated, + non_immersive_callback = + base::BindOnce(&XRDeviceImpl::OnNonImmersiveSessionCreated, weak_ptr_factory_.GetWeakPtr(), std::move(callback)); runtime->GetRuntime()->RequestSession(std::move(runtime_options), - std::move(magic_window_callback)); + std::move(non_immersive_callback)); } } void XRDeviceImpl::SupportsSession(device::mojom::XRSessionOptionsPtr options, SupportsSessionCallback callback) { - std::move(callback).Run(InternalSupportsSession(options.get())); -} - -bool XRDeviceImpl::InternalSupportsSession( - device::mojom::XRSessionOptions* options) { - // Return whether we can get a device that supports the specified options. - return XRRuntimeManager::GetInstance()->GetRuntimeForOptions(options) != - nullptr; + bool supports = XRRuntimeManager::GetInstance()->GetRuntimeForOptions( + options.get()) != nullptr; + std::move(callback).Run(supports); } void XRDeviceImpl::ReportRequestPresent() { @@ -242,17 +246,29 @@ immersive_runtime_->ExitPresent(this); } -void XRDeviceImpl::SetListeningForActivate(bool listening) { - listening_for_activate_ = listening; - if (!immersive_runtime_) { - return; +void XRDeviceImpl::SetListeningForActivate( + device::mojom::VRDisplayClientPtr client) { + client_ = std::move(client); + if (immersive_runtime_ && client) { + immersive_runtime_->UpdateListeningForActivate(this); } - immersive_runtime_->UpdateListeningForActivate(this); +} + +void XRDeviceImpl::GetImmersiveVRDisplayInfo( + device::mojom::XRDevice::GetImmersiveVRDisplayInfoCallback callback) { + BrowserXRRuntime* immersive_runtime = + XRRuntimeManager::GetInstance()->GetImmersiveRuntime(); + device::mojom::VRDisplayInfoPtr device_info = + immersive_runtime ? immersive_runtime->GetVRDisplayInfo() : nullptr; + std::move(callback).Run(std::move(device_info)); } void XRDeviceImpl::SetInFocusedFrame(bool in_focused_frame) { in_focused_frame_ = in_focused_frame; - SetListeningForActivate(listening_for_activate_); // No change, except focus. + if (ListeningForActivate() && immersive_runtime_) { + // No change, except focus. + immersive_runtime_->UpdateListeningForActivate(this); + } magic_window_controllers_.ForAllPtrs( [&in_focused_frame](device::mojom::XRSessionController* controller) { @@ -262,8 +278,12 @@ void XRDeviceImpl::OnChanged() { device::mojom::VRDisplayInfoPtr display_info = GetCurrentVRDisplayInfo(); - if (display_info && client_) - client_->OnChanged(std::move(display_info)); + if (display_info) { + session_clients_.ForAllPtrs( + [&display_info](device::mojom::XRSessionClient* client) { + client->OnChanged(display_info.Clone()); + }); + } } void XRDeviceImpl::OnRuntimeRemoved(BrowserXRRuntime* runtime) { @@ -289,24 +309,33 @@ } void XRDeviceImpl::OnExitPresent() { - client_->OnExitPresent(); + session_clients_.ForAllPtrs( + [](device::mojom::XRSessionClient* client) { client->OnExitPresent(); }); } +// TODO(http://crbug.com/845283): We should store the state here and send blur +// messages to sessions that start blurred. void XRDeviceImpl::OnBlur() { - client_->OnBlur(); + session_clients_.ForAllPtrs( + [](device::mojom::XRSessionClient* client) { client->OnBlur(); }); } void XRDeviceImpl::OnFocus() { - client_->OnFocus(); + session_clients_.ForAllPtrs( + [](device::mojom::XRSessionClient* client) { client->OnFocus(); }); } void XRDeviceImpl::OnActivate(device::mojom::VRDisplayEventReason reason, base::OnceCallback<void(bool)> on_handled) { - client_->OnActivate(reason, std::move(on_handled)); + if (client_) { + client_->OnActivate(reason, std::move(on_handled)); + } } void XRDeviceImpl::OnDeactivate(device::mojom::VRDisplayEventReason reason) { - client_->OnDeactivate(reason); + if (client_) { + client_->OnDeactivate(reason); + } } bool XRDeviceImpl::IsSecureContextRequirementSatisfied() {
diff --git a/chrome/browser/vr/service/xr_device_impl.h b/chrome/browser/vr/service/xr_device_impl.h index aff7bce..aa3df96 100644 --- a/chrome/browser/vr/service/xr_device_impl.h +++ b/chrome/browser/vr/service/xr_device_impl.h
@@ -32,7 +32,7 @@ class XRDeviceImpl : public device::mojom::XRDevice { public: XRDeviceImpl(content::RenderFrameHost* render_frame_host, - device::mojom::VRServiceClient* service_client); + device::mojom::XRDeviceRequest device_request); ~XRDeviceImpl() override; // device::mojom::XRDevice @@ -43,8 +43,13 @@ void SupportsSession(device::mojom::XRSessionOptionsPtr options, SupportsSessionCallback callback) override; void ExitPresent() override; + // device::mojom::XRDevice WebVR compatibility functions + void GetImmersiveVRDisplayInfo( + device::mojom::XRDevice::GetImmersiveVRDisplayInfoCallback callback) + override; - void SetListeningForActivate(bool listening); + void SetListeningForActivate(device::mojom::VRDisplayClientPtr client); + void SetInFocusedFrame(bool in_focused_frame); // Notifications when devices are added/removed. @@ -59,7 +64,7 @@ void OnActivate(device::mojom::VRDisplayEventReason reason, base::OnceCallback<void(bool)> on_handled); void OnDeactivate(device::mojom::VRDisplayEventReason reason); - bool ListeningForActivate() { return listening_for_activate_; } + bool ListeningForActivate() { return !!client_; } bool InFocusedFrame() { return in_focused_frame_; } base::WeakPtr<XRDeviceImpl> GetWeakPtr() { @@ -71,10 +76,13 @@ bool IsAnotherHostPresenting(); bool InternalSupportsSession(device::mojom::XRSessionOptions* options); - void OnMagicWindowSessionCreated( + void OnNonImmersiveSessionCreated( device::mojom::XRDevice::RequestSessionCallback callback, device::mojom::XRSessionPtr session, device::mojom::XRSessionControllerPtr controller); + void OnSessionCreated( + device::mojom::XRDevice::RequestSessionCallback callback, + device::mojom::XRSessionPtr session); // TODO(https://crbug.com/837538): Instead, check before returning this // object. @@ -83,10 +91,11 @@ device::mojom::VRDisplayInfoPtr GetCurrentVRDisplayInfo(); bool in_focused_frame_ = false; - bool listening_for_activate_ = false; content::RenderFrameHost* render_frame_host_; mojo::Binding<device::mojom::XRDevice> binding_; + mojo::InterfacePtrSet<device::mojom::XRSessionClient> session_clients_; + // This is required for WebVR 1.1 backwards compatibility. device::mojom::VRDisplayClientPtr client_; mojo::InterfacePtrSet<device::mojom::XRSessionController>
diff --git a/chrome/browser/vr/service/xr_runtime_manager.cc b/chrome/browser/vr/service/xr_runtime_manager.cc index f4cca662..d32601c 100644 --- a/chrome/browser/vr/service/xr_runtime_manager.cc +++ b/chrome/browser/vr/service/xr_runtime_manager.cc
@@ -152,6 +152,11 @@ return nullptr; } +bool XRRuntimeManager::HasAnyRuntime() { + device::mojom::XRSessionOptions options = device::mojom::XRSessionOptions(); + return GetRuntimeForOptions(&options) != nullptr; +} + bool XRRuntimeManager::HasInstance() { return g_xr_runtime_manager != nullptr; }
diff --git a/chrome/browser/vr/service/xr_runtime_manager.h b/chrome/browser/vr/service/xr_runtime_manager.h index 3d1832705..dc2cc11c 100644 --- a/chrome/browser/vr/service/xr_runtime_manager.h +++ b/chrome/browser/vr/service/xr_runtime_manager.h
@@ -43,9 +43,6 @@ // Adds a listener for runtime manager events. XRRuntimeManager does not own // this object. - // Automatically connects all currently available VR devices by querying - // the device providers and, for each returned device, calling - // VRServiceImpl::ConnectDevice. void AddService(VRServiceImpl* service); void RemoveService(VRServiceImpl* service); @@ -53,11 +50,15 @@ device::mojom::XRSessionOptions* options); BrowserXRRuntime* GetImmersiveRuntime(); + bool HasAnyRuntime(); + protected: using ProviderList = std::vector<std::unique_ptr<device::VRDeviceProvider>>; - // Used by tests to supply providers. + // Constructor also used by tests to supply an arbitrary list of providers, so + // make it protected rather than private. explicit XRRuntimeManager(ProviderList providers); + // Used by tests to check on device state. // TODO: Use XRDeviceId as appropriate. device::mojom::XRRuntime* GetRuntimeForTest(unsigned int id);
diff --git a/chrome/browser/vr/service/xr_runtime_manager_unittest.cc b/chrome/browser/vr/service/xr_runtime_manager_unittest.cc index 4fa4963e..82a48c0f 100644 --- a/chrome/browser/vr/service/xr_runtime_manager_unittest.cc +++ b/chrome/browser/vr/service/xr_runtime_manager_unittest.cc
@@ -47,7 +47,7 @@ class XRRuntimeManagerTest : public testing::Test { public: - void onDisplaySynced() {} + static void onDeviceReturned(device::mojom::XRDevicePtr ptr) {} protected: XRRuntimeManagerTest() = default; @@ -67,10 +67,10 @@ device::mojom::VRServiceClientPtr proxy; device::FakeVRServiceClient client(mojo::MakeRequest(&proxy)); auto service = base::WrapUnique(new VRServiceImplForTesting()); - service->SetClient( - std::move(proxy), - base::BindRepeating(&XRRuntimeManagerTest::onDisplaySynced, - base::Unretained(this))); + XRRuntimeManager::GetInstance()->AddService(service.get()); + service->RequestDevice( + base::BindRepeating(&XRRuntimeManagerTest::onDeviceReturned)); + service->SetClient(std::move(proxy)); return service; }
diff --git a/chrome/browser/vr/test/gl_test_environment.cc b/chrome/browser/vr/test/gl_test_environment.cc index 8f8cebe..9d1df9d8 100644 --- a/chrome/browser/vr/test/gl_test_environment.cc +++ b/chrome/browser/vr/test/gl_test_environment.cc
@@ -4,7 +4,7 @@ #include "chrome/browser/vr/test/gl_test_environment.h" -#include "chrome/browser/vr/graphics_delegate.h" +#include "chrome/browser/vr/base_compositor_delegate.h" #include "ui/gl/gl_version_info.h" #include "ui/gl/init/gl_factory.h" #include "ui/gl/test/gl_image_test_support.h" @@ -16,8 +16,8 @@ // Setup offscreen GL context. gl::GLImageTestSupport::InitializeGL(base::nullopt); surface_ = gl::init::CreateOffscreenGLSurface(gfx::Size()); - graphics_delegate_ = std::make_unique<GraphicsDelegate>(surface_); - if (!graphics_delegate_->Initialize()) + compositor_delegate_ = std::make_unique<BaseCompositorDelegate>(); + if (!compositor_delegate_->Initialize(surface_)) return; if (gl::GLContext::GetCurrent()->GetVersionInfo()->IsAtLeastGL(3, 3)) { @@ -36,7 +36,7 @@ if (vao_) { glDeleteVertexArraysOES(1, &vao_); } - graphics_delegate_.reset(); + compositor_delegate_.reset(); surface_ = nullptr; gl::GLImageTestSupport::CleanupGL(); }
diff --git a/chrome/browser/vr/test/gl_test_environment.h b/chrome/browser/vr/test/gl_test_environment.h index 5127683..d373cd3 100644 --- a/chrome/browser/vr/test/gl_test_environment.h +++ b/chrome/browser/vr/test/gl_test_environment.h
@@ -14,7 +14,7 @@ namespace vr { -class GraphicsDelegate; +class CompositorDelegate; class GlTestEnvironment { public: @@ -25,7 +25,7 @@ private: scoped_refptr<gl::GLSurface> surface_; - std::unique_ptr<GraphicsDelegate> graphics_delegate_; + std::unique_ptr<CompositorDelegate> compositor_delegate_; GLuint vao_ = 0; GLuint frame_buffer_ = 0; };
diff --git a/chrome/browser/vr/testapp/gl_renderer.cc b/chrome/browser/vr/testapp/gl_renderer.cc index 68514fa..31eb46e 100644 --- a/chrome/browser/vr/testapp/gl_renderer.cc +++ b/chrome/browser/vr/testapp/gl_renderer.cc
@@ -4,9 +4,12 @@ #include "chrome/browser/vr/testapp/gl_renderer.h" +#include <memory> +#include <utility> + #include "base/threading/thread_task_runner_handle.h" #include "base/time/time.h" -#include "chrome/browser/vr/graphics_delegate.h" +#include "chrome/browser/vr/base_compositor_delegate.h" #include "chrome/browser/vr/testapp/vr_test_context.h" #include "ui/gl/gl_bindings.h" #include "ui/gl/gl_context.h" @@ -37,12 +40,13 @@ GlRenderer::~GlRenderer() {} bool GlRenderer::Initialize() { - auto graphics_delegate = std::make_unique<GraphicsDelegate>(surface_); - if (!graphics_delegate->Initialize()) { + std::unique_ptr<CompositorDelegate> compositor_delegate = + std::make_unique<BaseCompositorDelegate>(); + if (!compositor_delegate->Initialize(surface_)) { return false; } - vr_->OnGlInitialized(std::move(graphics_delegate)); + vr_->OnGlInitialized(std::move(compositor_delegate)); PostRenderFrameTask(gfx::SwapResult::SWAP_ACK); return true;
diff --git a/chrome/browser/vr/testapp/vr_test_context.cc b/chrome/browser/vr/testapp/vr_test_context.cc index 4a2a04f..e60c7312 100644 --- a/chrome/browser/vr/testapp/vr_test_context.cc +++ b/chrome/browser/vr/testapp/vr_test_context.cc
@@ -5,6 +5,8 @@ #include "chrome/browser/vr/testapp/vr_test_context.h" #include <memory> +#include <utility> +#include <vector> #include "base/i18n/icu_util.h" #include "base/numerics/ranges.h" @@ -13,8 +15,8 @@ #include "base/strings/utf_string_conversions.h" #include "base/version.h" #include "chrome/browser/vr/assets_load_status.h" +#include "chrome/browser/vr/compositor_delegate.h" #include "chrome/browser/vr/gl_texture_location.h" -#include "chrome/browser/vr/graphics_delegate.h" #include "chrome/browser/vr/model/assets.h" #include "chrome/browser/vr/model/model.h" #include "chrome/browser/vr/model/omnibox_suggestions.h" @@ -171,9 +173,8 @@ UpdateController(render_info, current_time); - graphics_delegate_->MakeSkiaContextCurrent(); - ui_->UpdateSceneTextures(); - graphics_delegate_->MakeMainContextCurrent(); + compositor_delegate_->RunInSkiaContext( + base::BindOnce(&UiInterface::UpdateSceneTextures, base::Unretained(ui_))); auto load_progress = (current_time - page_load_start_).InMilliseconds() / kPageLoadTimeMilliseconds; @@ -455,8 +456,8 @@ } void VrTestContext::OnGlInitialized( - std::unique_ptr<GraphicsDelegate> graphics_delegate) { - graphics_delegate_ = std::move(graphics_delegate); + std::unique_ptr<CompositorDelegate> compositor_delegate) { + compositor_delegate_ = std::move(compositor_delegate); unsigned int content_texture_id = CreateTexture(0xFF000080); unsigned int ui_texture_id = CreateTexture(0xFF008000);
diff --git a/chrome/browser/vr/testapp/vr_test_context.h b/chrome/browser/vr/testapp/vr_test_context.h index 3b009709..d74ed06 100644 --- a/chrome/browser/vr/testapp/vr_test_context.h +++ b/chrome/browser/vr/testapp/vr_test_context.h
@@ -5,11 +5,10 @@ #ifndef CHROME_BROWSER_VR_TESTAPP_VR_TEST_CONTEXT_H_ #define CHROME_BROWSER_VR_TESTAPP_VR_TEST_CONTEXT_H_ -#include "base/macros.h" - -#include <cstdint> +#include <memory> #include <queue> +#include "base/macros.h" #include "base/time/time.h" #include "chrome/browser/vr/content_input_delegate.h" #include "chrome/browser/vr/model/controller_model.h" @@ -24,7 +23,7 @@ namespace vr { -class GraphicsDelegate; +class CompositorDelegate; class TextInputDelegate; class TestKeyboardDelegate; class Ui; @@ -37,7 +36,7 @@ VrTestContext(); ~VrTestContext() override; - void OnGlInitialized(std::unique_ptr<GraphicsDelegate> graphics_delegate); + void OnGlInitialized(std::unique_ptr<CompositorDelegate> compositor_delegate); // TODO(vollick): we should refactor VrShellGl's rendering logic and use it // directly. crbug.com/767282 void DrawFrame(); @@ -121,7 +120,7 @@ std::unique_ptr<TextInputDelegate> text_input_delegate_; std::unique_ptr<TestKeyboardDelegate> keyboard_delegate_; - std::unique_ptr<GraphicsDelegate> graphics_delegate_; + std::unique_ptr<CompositorDelegate> compositor_delegate_; PlatformController::Handedness handedness_ = PlatformController::kRightHanded;
diff --git a/chrome/common/chrome_content_client.cc b/chrome/common/chrome_content_client.cc index f98d01cf..06fc15a 100644 --- a/chrome/common/chrome_content_client.cc +++ b/chrome/common/chrome_content_client.cc
@@ -188,8 +188,7 @@ pdf_info.is_out_of_process = true; pdf_info.name = ChromeContentClient::kPDFInternalPluginName; pdf_info.description = kPDFPluginDescription; - pdf_info.path = base::FilePath::FromUTF8Unsafe( - ChromeContentClient::kPDFPluginPath); + pdf_info.path = base::FilePath(ChromeContentClient::kPDFPluginPath); content::WebPluginMimeType pdf_mime_type( kPDFPluginOutOfProcessMimeType, kPDFPluginExtension, @@ -207,27 +206,24 @@ // enabled by default for the non-portable case. This allows apps installed // from the Chrome Web Store to use NaCl even if the command line switch // isn't set. For other uses of NaCl we check for the command line switch. - base::FilePath path; - if (base::PathService::Get(chrome::FILE_NACL_PLUGIN, &path)) { - content::PepperPluginInfo nacl; - // The nacl plugin is now built into the Chromium binary. - nacl.is_internal = true; - nacl.path = path; - nacl.name = nacl::kNaClPluginName; - content::WebPluginMimeType nacl_mime_type(nacl::kNaClPluginMimeType, - nacl::kNaClPluginExtension, - nacl::kNaClPluginDescription); - nacl.mime_types.push_back(nacl_mime_type); - content::WebPluginMimeType pnacl_mime_type(nacl::kPnaclPluginMimeType, - nacl::kPnaclPluginExtension, - nacl::kPnaclPluginDescription); - nacl.mime_types.push_back(pnacl_mime_type); - nacl.internal_entry_points.get_interface = g_nacl_get_interface; - nacl.internal_entry_points.initialize_module = g_nacl_initialize_module; - nacl.internal_entry_points.shutdown_module = g_nacl_shutdown_module; - nacl.permissions = ppapi::PERMISSION_PRIVATE | ppapi::PERMISSION_DEV; - plugins->push_back(nacl); - } + content::PepperPluginInfo nacl; + // The nacl plugin is now built into the Chromium binary. + nacl.is_internal = true; + nacl.path = base::FilePath(ChromeContentClient::kNaClPluginFileName); + nacl.name = nacl::kNaClPluginName; + content::WebPluginMimeType nacl_mime_type(nacl::kNaClPluginMimeType, + nacl::kNaClPluginExtension, + nacl::kNaClPluginDescription); + nacl.mime_types.push_back(nacl_mime_type); + content::WebPluginMimeType pnacl_mime_type(nacl::kPnaclPluginMimeType, + nacl::kPnaclPluginExtension, + nacl::kPnaclPluginDescription); + nacl.mime_types.push_back(pnacl_mime_type); + nacl.internal_entry_points.get_interface = g_nacl_get_interface; + nacl.internal_entry_points.initialize_module = g_nacl_initialize_module; + nacl.internal_entry_points.shutdown_module = g_nacl_shutdown_module; + nacl.permissions = ppapi::PERMISSION_PRIVATE | ppapi::PERMISSION_DEV; + plugins->push_back(nacl); #endif // BUILDFLAG(ENABLE_NACL) } @@ -518,9 +514,9 @@ // nothing that guarantees the component update will give us the // FLAPPER_VERSION_STRING version of Flash, but using this version seems // better than any other hardcoded alternative. - plugins->push_back(CreatePepperFlashInfo( - base::FilePath::FromUTF8Unsafe(ChromeContentClient::kNotPresent), - FLAPPER_VERSION_STRING, false)); + plugins->push_back( + CreatePepperFlashInfo(base::FilePath(ChromeContentClient::kNotPresent), + FLAPPER_VERSION_STRING, false)); #endif // defined(GOOGLE_CHROME_BUILD) && defined(FLAPPER_AVAILABLE) } #endif // BUILDFLAG(ENABLE_PLUGINS)
diff --git a/chrome/common/chrome_content_client.h b/chrome/common/chrome_content_client.h index 9eb2c04..5efde49 100644 --- a/chrome/common/chrome_content_client.h +++ b/chrome/common/chrome_content_client.h
@@ -30,14 +30,19 @@ class ChromeContentClient : public content::ContentClient { public: #if defined(GOOGLE_CHROME_BUILD) - // kNotPresent is a placeholder plugin location for plugins that are not + // |kNotPresent| is a placeholder plugin location for plugins that are not // currently present in this installation of Chrome, but which can be fetched // on-demand and therefore should still appear in navigator.plugins. - static const char kNotPresent[]; + static const base::FilePath::CharType kNotPresent[]; #endif + +#if BUILDFLAG(ENABLE_NACL) + static const base::FilePath::CharType kNaClPluginFileName[]; +#endif + static const char kPDFExtensionPluginName[]; static const char kPDFInternalPluginName[]; - static const char kPDFPluginPath[]; + static const base::FilePath::CharType kPDFPluginPath[]; ChromeContentClient(); ~ChromeContentClient() override;
diff --git a/chrome/common/chrome_content_client_constants.cc b/chrome/common/chrome_content_client_constants.cc index 5f10118..a8365688 100644 --- a/chrome/common/chrome_content_client_constants.cc +++ b/chrome/common/chrome_content_client_constants.cc
@@ -5,7 +5,16 @@ #include "chrome/common/chrome_content_client.h" #if defined(GOOGLE_CHROME_BUILD) -const char ChromeContentClient::kNotPresent[] = "internal-not-yet-present"; +const base::FilePath::CharType ChromeContentClient::kNotPresent[] = + FILE_PATH_LITERAL("internal-not-yet-present"); +#endif + +#if BUILDFLAG(ENABLE_NACL) +const base::FilePath::CharType ChromeContentClient::kNaClPluginFileName[] = + FILE_PATH_LITERAL("internal-nacl-plugin"); +#endif + +#if defined(GOOGLE_CHROME_BUILD) const char ChromeContentClient::kPDFExtensionPluginName[] = "Chrome PDF Viewer"; const char ChromeContentClient::kPDFInternalPluginName[] = "Chrome PDF Plugin"; #else @@ -14,4 +23,6 @@ const char ChromeContentClient::kPDFInternalPluginName[] = "Chromium PDF Plugin"; #endif -const char ChromeContentClient::kPDFPluginPath[] = "internal-pdf-viewer"; + +const base::FilePath::CharType ChromeContentClient::kPDFPluginPath[] = + FILE_PATH_LITERAL("internal-pdf-viewer");
diff --git a/chrome/common/chrome_features.cc b/chrome/common/chrome_features.cc index fa4bff8..0f7a761 100644 --- a/chrome/common/chrome_features.cc +++ b/chrome/common/chrome_features.cc
@@ -430,6 +430,14 @@ base::FEATURE_ENABLED_BY_DEFAULT}; #endif +#if defined(OS_CHROMEOS) +// Enables the Recommend Apps screen in OOBE. +// TODO(https://crbug.com/862774): Remove this after the feature is fully +// launched. +const base::Feature kOobeRecommendAppsScreen{"OobeRecommendAppsScreen", + base::FEATURE_ENABLED_BY_DEFAULT}; +#endif + // Adds the base language code to the Language-Accept headers if at least one // corresponding language+region code is present in the user preferences. // For example: "en-US, fr-FR" --> "en-US, en, fr-FR, fr".
diff --git a/chrome/common/chrome_features.h b/chrome/common/chrome_features.h index 0d98206e..1b56c28 100644 --- a/chrome/common/chrome_features.h +++ b/chrome/common/chrome_features.h
@@ -230,6 +230,10 @@ extern const base::Feature kOneGoogleBarOnLocalNtp; #endif +#if defined(OS_CHROMEOS) +extern const base::Feature kOobeRecommendAppsScreen; +#endif + extern const base::Feature kUseNewAcceptLanguageHeader; extern const base::Feature kPermissionDelegation;
diff --git a/chrome/common/chrome_paths.cc b/chrome/common/chrome_paths.cc index 829f1dc..831d2dc 100644 --- a/chrome/common/chrome_paths.cc +++ b/chrome/common/chrome_paths.cc
@@ -49,9 +49,6 @@ FILE_PATH_LITERAL("Internet Plug-Ins/PepperFlashPlayer"); #endif -const base::FilePath::CharType kInternalNaClPluginFileName[] = - FILE_PATH_LITERAL("internal-nacl-plugin"); - #if defined(OS_LINUX) // The path to the external extension <id>.json files. // /usr/share seems like a good choice, see: http://www.pathname.com/fhs/ @@ -333,14 +330,6 @@ return false; cur = cur.Append(chrome::kPepperFlashPluginFilename); break; - // TODO(teravest): Remove this case once the internal NaCl plugin is gone. - // We currently need a path here to look up whether the plugin is disabled - // and what its permissions are. - case chrome::FILE_NACL_PLUGIN: - if (!GetInternalPluginsDirectory(&cur)) - return false; - cur = cur.Append(kInternalNaClPluginFileName); - break; // PNaCl is currenly installable via the component updater or by being // simply built-in. DIR_PNACL_BASE is used as the base directory for // installation via component updater. DIR_PNACL_COMPONENT will be
diff --git a/chrome/common/chrome_paths.h b/chrome/common/chrome_paths.h index 5556c9d5..1fe0600 100644 --- a/chrome/common/chrome_paths.h +++ b/chrome/common/chrome_paths.h
@@ -89,7 +89,6 @@ // Pepper Flash plugin, downloadable from // Adobe website. Querying this path might // succeed no matter the file exists or not. - FILE_NACL_PLUGIN, // Full path to the internal NaCl plugin file. DIR_PNACL_BASE, // Full path to the base dir for PNaCl. DIR_PNACL_COMPONENT, // Full path to the latest PNaCl version // (subdir of DIR_PNACL_BASE).
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc index 6f6c9e10..55e4f4c 100644 --- a/chrome/common/pref_names.cc +++ b/chrome/common/pref_names.cc
@@ -874,6 +874,12 @@ // session" mode which has lifted restrictions (true). const char kManagedSessionEnabled[] = "managed_session.enabled"; +// Boolean pref indicating whether the user has previously dismissed the +// one-time notification indicating the need for a cleanup powerwash after TPM +// firmware update that didn't flush the TPM SRK. +extern const char kTPMFirmwareUpdateCleanupDismissed[] = + "tpm_firmware_update.cleanup_dismissed"; + #endif // defined(OS_CHROMEOS) // A boolean pref set to true if a Home button to open the Home pages should be
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h index 1071b02..7bb8d49 100644 --- a/chrome/common/pref_names.h +++ b/chrome/common/pref_names.h
@@ -281,6 +281,7 @@ extern const char kEnableSyncConsent[]; extern const char kNetworkFileSharesAllowed[]; extern const char kManagedSessionEnabled[]; +extern const char kTPMFirmwareUpdateCleanupDismissed[]; #endif // defined(OS_CHROMEOS) extern const char kShowHomeButton[]; extern const char kSpeechRecognitionFilterProfanities[];
diff --git a/chrome/renderer/chrome_content_renderer_client.cc b/chrome/renderer/chrome_content_renderer_client.cc index 892be5e..dfabe32 100644 --- a/chrome/renderer/chrome_content_renderer_client.cc +++ b/chrome/renderer/chrome_content_renderer_client.cc
@@ -102,7 +102,6 @@ #include "content/public/renderer/render_frame_visitor.h" #include "content/public/renderer/render_view.h" #include "extensions/buildflags/buildflags.h" -#include "extensions/common/constants.h" #include "ipc/ipc_sync_channel.h" #include "media/base/media_switches.h" #include "media/media_buildflags.h" @@ -1390,8 +1389,7 @@ bool ChromeContentRendererClient::IsOriginIsolatedPepperPlugin( const base::FilePath& plugin_path) { - return plugin_path == - base::FilePath::FromUTF8Unsafe(ChromeContentClient::kPDFPluginPath); + return plugin_path.value() == ChromeContentClient::kPDFPluginPath; } #if BUILDFLAG(ENABLE_PLUGINS) && BUILDFLAG(ENABLE_EXTENSIONS)
diff --git a/chrome/renderer/pepper/pepper_uma_host.cc b/chrome/renderer/pepper/pepper_uma_host.cc index 8876cea..b3e4a3a 100644 --- a/chrome/renderer/pepper/pepper_uma_host.cc +++ b/chrome/renderer/pepper/pepper_uma_host.cc
@@ -51,7 +51,7 @@ "3FEA4650221C5E6C39CF5C5C9F464FF74EAB6CE1", // see http://crbug.com/521189 }; -const char* const kWhitelistedPluginBaseNames[] = { +const base::FilePath::CharType* const kWhitelistedPluginBaseNames[] = { ChromeContentClient::kPDFPluginPath, }; @@ -121,10 +121,8 @@ return true; } - if (base::ContainsKey(allowed_plugin_base_names_, - plugin_base_name_.MaybeAsASCII())) { + if (base::ContainsKey(allowed_plugin_base_names_, plugin_base_name_.value())) return true; - } LOG(ERROR) << "Host or histogram name is not allowed to use the UMA API."; return false;
diff --git a/chrome/renderer/pepper/pepper_uma_host.h b/chrome/renderer/pepper/pepper_uma_host.h index 3c2ce66d..3cf36406 100644 --- a/chrome/renderer/pepper/pepper_uma_host.h +++ b/chrome/renderer/pepper/pepper_uma_host.h
@@ -74,7 +74,7 @@ // Set of hashed histogram prefixes that can be used from this interface. std::set<std::string> allowed_histogram_prefixes_; // Set of plugin files names that are allowed to use this interface. - std::set<std::string> allowed_plugin_base_names_; + std::set<base::FilePath::StringType> allowed_plugin_base_names_; DISALLOW_COPY_AND_ASSIGN(PepperUMAHost); };
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index fa813c6..11d9855 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -2618,10 +2618,10 @@ "../browser/prerender/prerender_unittest.cc", "../browser/prerender/prerender_util_unittest.cc", "../browser/previews/previews_infobar_delegate_unittest.cc", - "../browser/previews/previews_infobar_tab_helper_unittest.cc", "../browser/previews/previews_lite_page_decider_unittest.cc", "../browser/previews/previews_lite_page_navigation_throttle_unittest.cc", "../browser/previews/previews_service_unittest.cc", + "../browser/previews/previews_ui_tab_helper_unittest.cc", "../browser/process_singleton_win_unittest.cc", "../browser/profiles/gaia_info_update_service_unittest.cc", "../browser/profiles/guest_mode_policy_handler_unittest.cc", @@ -4386,8 +4386,8 @@ "../browser/ui/views/confirm_bubble_views_unittest.cc", "../browser/ui/views/fullscreen_control/fullscreen_control_popup_unittest.cc", "../browser/ui/views/global_error_bubble_view_unittest.cc", - "../browser/ui/views/harmony/layout_provider_unittest.cc", "../browser/ui/views/hover_button_unittest.cc", + "../browser/ui/views/layout_provider_unittest.cc", "../browser/ui/views/media_router/cast_dialog_metrics_unittest.cc", "../browser/ui/views/media_router/cast_dialog_no_sinks_view_unittest.cc", "../browser/ui/views/media_router/cast_dialog_sink_button_unittest.cc",
diff --git a/chrome/test/base/browser_with_test_window_test.cc b/chrome/test/base/browser_with_test_window_test.cc index 81f0943..8a2551f 100644 --- a/chrome/test/base/browser_with_test_window_test.cc +++ b/chrome/test/base/browser_with_test_window_test.cc
@@ -28,7 +28,7 @@ #if defined(TOOLKIT_VIEWS) #include "chrome/browser/ui/views/chrome_constrained_window_views_client.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" #include "components/constrained_window/constrained_window_views.h" #if defined(OS_CHROMEOS)
diff --git a/chrome/test/data/xr/e2e_test_files/html/test_payment_request.html b/chrome/test/data/xr/e2e_test_files/html/test_payment_request.html new file mode 100644 index 0000000..cfcb1bf9 --- /dev/null +++ b/chrome/test/data/xr/e2e_test_files/html/test_payment_request.html
@@ -0,0 +1,78 @@ +<!doctype html> +<!-- +Tests that attempts to use the Payment Request API are denied while in the VR +Browser. +--> +<html> + <head> + <link rel="stylesheet" type="text/css" href="../resources/webxr_e2e.css"> + </head> + <body> + <script src="../../../../../../third_party/WebKit/LayoutTests/resources/testharness.js"></script> + <script src="../resources/webxr_e2e.js"></script> + <script> + var t = async_test("Payment Request API disabled while in VR Browser"); + + // Arbitrary but valid data to pass to PaymentRequest to trigger the + // native Payment Request UI. + var methods = [ + { + supportedMethods: "basic-card", + data: { + supportedNetworks: [ + "visa", + "mastercard", + ], + supportedTypes: [ + "debit", + "credit", + ], + }, + }, + ]; + + var details = { + id: "Super VR Store", + displayItems: [ + { + label: "Sub-total", + amount: { + currency: "USD", + value: "10.00", + }, + }, + { + label: "Sales Tax", + amount: { + currency: "USD", + value: "1.00", + }, + }, + ], + total: { + label: "Total", + amount: { + currency: "USD", + value: "11.00", + }, + }, + }; + + var request = new PaymentRequest(methods, details); + + function stepRequestPayment() { + request.show().then(() => { + t.step(() => { + assert_unreached("Payment request was shown and accepted"); + }); + }, (err) => { + t.step(() => { + assert_true(err instanceof DOMException, + "Payment request denied, but not for expected reason"); + }); + t.done(); + }); + } + </script> + </body> +</html>
diff --git a/chrome/test/ppapi/ppapi_browsertest.cc b/chrome/test/ppapi/ppapi_browsertest.cc index 9f38038..53a8efbe 100644 --- a/chrome/test/ppapi/ppapi_browsertest.cc +++ b/chrome/test/ppapi/ppapi_browsertest.cc
@@ -27,13 +27,19 @@ #include "components/nacl/common/nacl_switches.h" #include "content/public/browser/web_contents.h" #include "content/public/common/content_switches.h" +#include "content/public/common/service_manager_connection.h" +#include "content/public/common/service_names.mojom.h" #include "content/public/common/url_constants.h" +#include "content/public/test/browser_test_utils.h" #include "content/public/test/javascript_test_observer.h" #include "content/public/test/test_renderer_host.h" #include "extensions/common/constants.h" #include "extensions/test/extension_test_message_listener.h" #include "ppapi/shared_impl/test_utils.h" #include "rlz/buildflags/buildflags.h" +#include "services/network/public/cpp/features.h" +#include "services/network/public/mojom/network_service_test.mojom.h" +#include "services/service_manager/public/cpp/connector.h" #if defined(OS_MACOSX) #include "base/mac/mac_util.h" @@ -319,6 +325,21 @@ TEST_PPAPI_OUT_OF_PROCESS_WITH_SSL_SERVER(TCPSocketPrivateTrusted) +IN_PROC_BROWSER_TEST_F(OutOfProcessPPAPITest, TCPSocketPrivateCrash_Resolve) { + if (!base::FeatureList::IsEnabled(network::features::kNetworkService) || + content::IsNetworkServiceRunningInProcess()) + return; + + network::mojom::NetworkServiceTestPtr network_service_test; + content::ServiceManagerConnection::GetForProcess() + ->GetConnector() + ->BindInterface(content::mojom::kNetworkServiceName, + &network_service_test); + network_service_test->CrashOnResolveHost("crash.com"); + + RunTestViaHTTP(STRIP_PREFIXES(TCPSocketPrivateCrash_Resolve)); +} + // UDPSocket tests. #define UDPSOCKET_TEST(_test) \
diff --git a/chrome/test/views/chrome_test_views_delegate.cc b/chrome/test/views/chrome_test_views_delegate.cc index 76ece24..22a9385 100644 --- a/chrome/test/views/chrome_test_views_delegate.cc +++ b/chrome/test/views/chrome_test_views_delegate.cc
@@ -4,7 +4,7 @@ #include "chrome/test/views/chrome_test_views_delegate.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" ChromeTestViewsDelegate::ChromeTestViewsDelegate() : views::TestViewsDelegate() {
diff --git a/chrome/test/vr/auto_bisect.py b/chrome/test/vr/auto_bisect.py index ea0bc4e..7c48cc26 100755 --- a/chrome/test/vr/auto_bisect.py +++ b/chrome/test/vr/auto_bisect.py
@@ -78,6 +78,9 @@ # Arguments related to the actual bisection parser.add_argument_group('bisect arguments') + parser.add_argument('--binary-bisect', action='store_true', default=False, + help='Bisect a binary size regression instead of a ' + 'regular perf regression.') parser.add_argument('--good-revision', required=True, help='A known good Git revision') parser.add_argument('--bad-revision', required=True, @@ -152,9 +155,9 @@ 'fixing bad DEPS entries in the revision range.') parser.add_argument_group('swarming arguments') - parser.add_argument('--swarming-server', required=True, + parser.add_argument('--swarming-server', help='The swarming server to trigger the test on') - parser.add_argument('--isolate-server', required=True, + parser.add_argument('--isolate-server', help='The isolate server to upload the test to') parser.add_argument('--dimension', action='append', type=comma_separated, default=[], dest='dimensions', @@ -176,7 +179,13 @@ help='The directory that builds will take place in. ' 'Assumes that gn args have already been generated ' 'for the provided directory. Must be relative to ' - 'the Chromium src/ directory, e.g. out/Release.') + 'the Chromium src/ directory, e.g. out/Release. ' + 'When using --binary-bisect, this should be the ' + 'output directory for the base build.') + parser.add_argument('--diff-build-output-dir', + default=os.path.join('out', 'Release_diff'), + help='Only used when --binary-bisect is set. The same as ' + '--build-output-dir, but for the diff build.') parser.add_argument('--regenerate-args-after-sync', action='store_true', default=False, help='Causes the build output directory to be deleted ' @@ -186,36 +195,53 @@ 'available unless the directory is re-created.') parser.add_argument('--build-target', required=True, help='The target to build for testing') + parser.add_argument('--apk-name', + help='Only used when --binary-bisect is set. The name of ' + 'the APK that will be diffed.') args, unknown_args = parser.parse_known_args() - # Set defaults - if not args.isolate_target: - args.isolate_target = args.build_target + if args.binary_bisect: + if not args.apk_name: + raise RuntimeError('--apk-name must be set when using --binary-bisect.') - # Make sure we have at least one swarming dimension - if len(args.dimensions) == 0: - raise RuntimeError('No swarming dimensions provided') + if not args.diff_build_output_dir: + raise RuntimeError('--diff-build-output-dir must be set when using ' + '--binary-bisect.') - # Make sure we're set to run at least one attempt per revision - if args.num_attempts_before_marking_good < 1: - raise RuntimeError( - '--num-attempts-before-marking-good set to invalid value %d' % - args.num_attempts_before_marking_good) + else: + # Set defaults + if not args.isolate_target: + args.isolate_target = args.build_target - # Make sure the provided data format is supported. - if args.expected_json_result_format not in SUPPORTED_JSON_RESULT_FORMATS: - raise RuntimeError( - '--expected-json-result-format set to invalid value %s' % - args.expected_json_result_format) + # Make sure we have at least one swarming dimension + if len(args.dimensions) == 0: + raise RuntimeError('No swarming dimensions provided') - # Determining initial values is not currently supported if we're bisecting a - # roll. Since bisecting a roll is almost always a product of a normal bisect - # pointing to a roll anyways, the user should have the good/bad values - # already. - if args.bisect_repo and (args.good_value is None or args.bad_value is None): - raise RuntimeError( - '--bisect-repo requires good and bad values to be set.') + # Make sure we have all the information we need in order to run on Swarming. + if not (args.swarming_server and args.isolate_server): + raise RuntimeError('--swarming-server and --isolate-server must be set ' + 'when running a non-binary-size bisection.') + + # Make sure we're set to run at least one attempt per revision + if args.num_attempts_before_marking_good < 1: + raise RuntimeError( + '--num-attempts-before-marking-good set to invalid value %d' % + args.num_attempts_before_marking_good) + + # Make sure the provided data format is supported. + if args.expected_json_result_format not in SUPPORTED_JSON_RESULT_FORMATS: + raise RuntimeError( + '--expected-json-result-format set to invalid value %s' % + args.expected_json_result_format) + + # Determining initial values is not currently supported if we're bisecting a + # roll. Since bisecting a roll is almost always a product of a normal bisect + # pointing to a roll anyways, the user should have the good/bad values + # already. + if args.bisect_repo and (args.good_value is None or args.bad_value is None): + raise RuntimeError( + '--bisect-repo requires good and bad values to be set.') return (args, unknown_args) @@ -236,6 +262,8 @@ 'will not be run, so ensure you are synced to the correct revision ' 'and any patches, etc. you need are applied before running.' % args.bisect_repo) + if args.binary_bisect: + print 'Script is running in binary size bisect mode.' print 'This will start a bisect for a for:' print 'Metric: %s' % args.metric print 'Story: %s' % args.story @@ -267,21 +295,27 @@ args.expected_json_result_format, SUPPORTED_JSON_RESULT_FORMATS[args.expected_json_result_format]) print '======' - print 'The test target %s will be built to %s' % (args.build_target, - args.build_output_dir) + if args.binary_bisect: + print '%s will be built in both %s and %s' % (args.build_target, + args.build_output_dir, + args.diff_build_output_dir) + else: + print 'The test target %s will be built to %s' % (args.build_target, + args.build_output_dir) print '%d parallel jobs will be used with a load limit of %d' % ( args.parallel_jobs, args.load_limit) if args.regenerate_args_after_sync: print 'The build output directory will be recreated after each sync' print '======' - print 'The target %s will be isolated and uploaded to %s' % ( - args.isolate_target, args.isolate_server) - print 'The test will be triggered on %s with the following dimensions:' % ( - args.swarming_server) - for pair in args.dimensions: - for key, val in pair.iteritems(): - print '%s = %s' % (key, val) - print '======' + if not args.binary_bisect: + print 'The target %s will be isolated and uploaded to %s' % ( + args.isolate_target, args.isolate_server) + print 'The test will be triggered on %s with the following dimensions:' % ( + args.swarming_server) + for pair in args.dimensions: + for key, val in pair.iteritems(): + print '%s = %s' % (key, val) + print '======' print 'The test will be run with these additional arguments:' for extra_arg in unknown_args: print extra_arg @@ -388,25 +422,66 @@ subprocess.check_output(swarming_args) -def GetSwarmingResult(args, unknown_args, output_dir): +def RunBinarySizeDiff(args, output_dir): + """Locally runs a binary size diff on the two APKs specified by args. + + Args: + args: The known args parsed from the argument parser + output_dir: The directory to save diff results to + """ + print 'Diffing APKs' + subprocess.check_output( + ['python', os.path.join('build', 'android', 'diff_resource_sizes.py'), + '--base-apk', os.path.join(args.build_output_dir, 'apks', args.apk_name), + '--chromium-output-directory-base', args.build_output_dir, + '--diff-apk', + os.path.join(args.diff_build_output_dir, 'apks', args.apk_name), + '--chromium-output-directory-diff', args.diff_build_output_dir, + '--include-intermediate-results', + '--chartjson', + '--output-dir', output_dir]) + + +def GetSwarmingResult(args, output_dir): """Extracts the value for the story/metric combo of interest from swarming. Args: args: The known args parsed from the argument parser - unknown_args: The unknown args parsed from the argument parser output_dir: The directory where swarming results have been saved to Returns: The value for the story/metric combo that the last swarming run produced """ - with open( - os.path.join(output_dir, '0', 'perftest-output.json'), 'r') as infile: + return _GetResultsFromJson(args, os.path.join(output_dir, '0', + 'perftest-output.json')) + + +def GetBinarySizeResult(args, output_dir): + """Extracts the value for the story/metric combo of interest locally. + + Args: + args: The known args parsed from the argument parser + output_dir: The directory where local results have been saved to + + Returns: + The value for the story/metric combo that the last binary size diff produced + """ + return _GetResultsFromJson(args, + os.path.join(output_dir, 'results-chart.json')) + + +def _GetResultsFromJson(args, filepath): + with open(filepath, 'r') as infile: perf_results = json.load(infile) all_results = [] if args.expected_json_result_format == 'chartjson': - all_results = perf_results.get(unicode('charts'), {}).get( - unicode(args.metric), {}).get(unicode(args.story), {}).get( - unicode('values'), []) + # Perf tests use a 'values' array, while binary size uses a single 'value' + # field. So, check for both. + story = perf_results.get(unicode('charts'), {}).get( + unicode(args.metric), {}).get(unicode(args.story), {}) + all_results = story.get(unicode('values'), []) + if 'value' in story: + all_results = [story[unicode('value')]] elif args.expected_json_result_format == 'printedjson': all_results = perf_results.get(args.metric, {}).get('traces', {}).get( args.story, []) @@ -478,17 +553,25 @@ subprocess.check_output(['ninja', '-C', args.build_output_dir, '-j', str(args.parallel_jobs), '-l', str(args.load_limit), args.build_target]) + if args.binary_bisect: + subprocess.check_output(['ninja', '-C', args.diff_build_output_dir, + '-j', str(args.parallel_jobs), + '-l', str(args.load_limit), args.build_target]) def RegenerateGnArgs(args): """Recreates the build output directory using existing GN args.""" - with open(os.path.join(args.build_output_dir, 'args.gn'), 'r') as args_file: - gn_args = args_file.read() - shutil.rmtree(args.build_output_dir) - os.mkdir(args.build_output_dir) - with open(os.path.join(args.build_output_dir, 'args.gn'), 'w') as args_file: - args_file.write(gn_args) - subprocess.check_output(['gn', 'gen', args.build_output_dir]) + directories = [args.build_output_dir] + if args.binary_bisect: + directories.append(args.diff_build_output_dir) + for d in directories: + with open(os.path.join(d, 'args.gn'), 'r') as args_file: + gn_args = args_file.read() + shutil.rmtree(d) + os.mkdir(d) + with open(os.path.join(d, 'args.gn'), 'w') as args_file: + args_file.write(gn_args) + subprocess.check_output(['gn', 'gen', d]) def SyncAndBuild(args, unknown_args, revision): @@ -605,8 +688,12 @@ BuildTarget(args) elif sync: SyncAndBuild(args, unknown_args, revision) - RunTestOnSwarming(args, unknown_args, output_dir) - return GetSwarmingResult(args, unknown_args, output_dir) + if args.binary_bisect: + RunBinarySizeDiff(args, output_dir) + return GetBinarySizeResult(args, output_dir) + else: + RunTestOnSwarming(args, unknown_args, output_dir) + return GetSwarmingResult(args, output_dir) def main(): VerifyCwd()
diff --git a/chrome_elf/third_party_dlls/main_unittest.cc b/chrome_elf/third_party_dlls/main_unittest.cc index b1d19fa..cfca6450 100644 --- a/chrome_elf/third_party_dlls/main_unittest.cc +++ b/chrome_elf/third_party_dlls/main_unittest.cc
@@ -251,8 +251,13 @@ // configurations. //------------------------------------------------------------------------------ +#if defined(OS_WIN) +#define MAYBE_Base DISABLED_Base +#else +#define MAYBE_Base Base +#endif // Note: The test module used in this unittest has no export table. -TEST_F(ThirdPartyTest, Base) { +TEST_F(ThirdPartyTest, MAYBE_Base) { // 1. Spawn the test process with NO blacklist. Expect successful // initialization. base::CommandLine cmd_line1 = base::CommandLine::FromString(kTestExeFilename);
diff --git a/chromecast/browser/accessibility/accessibility_manager.cc b/chromecast/browser/accessibility/accessibility_manager.cc index 7f653d8..0afd97f4 100644 --- a/chromecast/browser/accessibility/accessibility_manager.cc +++ b/chromecast/browser/accessibility/accessibility_manager.cc
@@ -28,12 +28,12 @@ std::make_unique<AccessibilityFocusRingController>(root_window); touch_exploration_manager_ = std::make_unique<TouchExplorationManager>( root_window, activation_client, - accessibility_focus_ring_controller_.get(), - &accessibility_sound_proxy_, + accessibility_focus_ring_controller_.get(), &accessibility_sound_proxy_, window_manager->GetGestureHandler()); triple_tap_detector_ = std::make_unique<TripleTapDetector>(root_window, this); magnification_controller_ = - std::make_unique<FullscreenMagnificationController>(root_window); + std::make_unique<FullscreenMagnificationController>( + root_window, window_manager->GetGestureHandler()); } AccessibilityManager::~AccessibilityManager() {} @@ -87,8 +87,16 @@ return window_tree_host_; } -void AccessibilityManager::SetMagnificationGestureEnabled(bool enabled) { - triple_tap_detector_->set_enabled(enabled); +void AccessibilityManager::SetMagnificationGestureEnabled( + bool gesture_enabled) { + triple_tap_detector_->set_enabled(gesture_enabled); + + // If the gesture is not enabled, make sure that magnification is turned off, + // in case we're already in magnification. Otherwise the user will be stuck in + // magnifier and unable to get out. + if (!gesture_enabled) { + magnification_controller_->SetEnabled(false); + } } bool AccessibilityManager::IsMagnificationGestureEnabled() const {
diff --git a/chromecast/browser/accessibility/touch_exploration_controller.cc b/chromecast/browser/accessibility/touch_exploration_controller.cc index fe5c078..0afe1b7 100644 --- a/chromecast/browser/accessibility/touch_exploration_controller.cc +++ b/chromecast/browser/accessibility/touch_exploration_controller.cc
@@ -577,6 +577,8 @@ void TouchExplorationController::SendSimulatedClickOrTap() { // If we got an anchor point from ChromeVox, send a double-tap gesture // and let ChromeVox handle the click. + const gfx::Point location; + delegate_->HandleTap(location); if (anchor_point_state_ == ANCHOR_POINT_EXPLICITLY_SET) { delegate_->HandleAccessibilityGesture(ax::mojom::Gesture::kClick); return; @@ -611,8 +613,6 @@ lift_activation_bounds_.Contains(location)) { accessibility_sound_player_->PlayTouchTypeEarcon(); SendSimulatedTap(); - } else { - delegate_->HandleTap(location); } }
diff --git a/chromecast/graphics/accessibility/fullscreen_magnification_controller.cc b/chromecast/graphics/accessibility/fullscreen_magnification_controller.cc index 97c64a72..f722754 100644 --- a/chromecast/graphics/accessibility/fullscreen_magnification_controller.cc +++ b/chromecast/graphics/accessibility/fullscreen_magnification_controller.cc
@@ -5,6 +5,7 @@ #include "chromecast/graphics/accessibility/fullscreen_magnification_controller.h" #include "base/numerics/ranges.h" +#include "chromecast/graphics/cast_gesture_handler.h" #include "ui/aura/window.h" #include "ui/aura/window_event_dispatcher.h" #include "ui/aura/window_tree_host.h" @@ -75,9 +76,11 @@ }; FullscreenMagnificationController::FullscreenMagnificationController( - aura::Window* root_window) + aura::Window* root_window, + CastGestureHandler* cast_gesture_handler) : root_window_(root_window), - magnification_scale_(kDefaultMagnificationScale) { + magnification_scale_(kDefaultMagnificationScale), + cast_gesture_handler_(cast_gesture_handler) { DCHECK(root_window); root_window->GetHost()->GetEventSource()->AddEventRewriter(this); @@ -341,6 +344,10 @@ (gesture_center.y() - magnification_origin_.y())); RedrawDIP(origin, scale); + + // Invoke the tap gesture so we don't go idle in the UI while zooming. + cast_gesture_handler_->HandleTapGesture( + gfx::ToFlooredPoint(gesture_center)); } else if (gesture->type() == ui::ET_GESTURE_SCROLL_BEGIN) { original_magnification_origin_ = magnification_origin_; @@ -371,6 +378,9 @@ } } RedrawDIP(gfx::PointF(new_x, new_y), magnification_scale_); + + // Invoke the tap gesture so we don't go idle in the UI whiole dragging. + cast_gesture_handler_->HandleTapGesture(gfx::Point(new_x, new_y)); } }
diff --git a/chromecast/graphics/accessibility/fullscreen_magnification_controller.h b/chromecast/graphics/accessibility/fullscreen_magnification_controller.h index 829498c7..b12d7363 100644 --- a/chromecast/graphics/accessibility/fullscreen_magnification_controller.h +++ b/chromecast/graphics/accessibility/fullscreen_magnification_controller.h
@@ -23,11 +23,15 @@ namespace chromecast { +class CastGestureHandler; + class FullscreenMagnificationController : public MagnificationController, public ui::EventRewriter, public ui::GestureConsumer { public: - explicit FullscreenMagnificationController(aura::Window* root_window); + explicit FullscreenMagnificationController( + aura::Window* root_window, + CastGestureHandler* cast_gesture_handler); ~FullscreenMagnificationController() override; void SetEnabled(bool enabled) override; @@ -95,6 +99,8 @@ // events are cancelled, i.e. size of this map can be different from number of // touches on the screen. Key is pointer id. std::map<int32_t, std::unique_ptr<ui::TouchEvent>> press_event_map_; + + CastGestureHandler* cast_gesture_handler_; }; } // namespace chromecast
diff --git a/chromeos/chromeos_switches.cc b/chromeos/chromeos_switches.cc index 4be99e7..2b06cbc4 100644 --- a/chromeos/chromeos_switches.cc +++ b/chromeos/chromeos_switches.cc
@@ -345,10 +345,6 @@ // and it requires |kEnableDemoMode| flag to be enabled to take effect. const char kEnableOfflineDemoMode[] = "enable-offline-demo-mode"; -// Enables Recommend Apps screen in OOBE. -const char kEnableOobeRecommendAppsScreen[] = - "enable-oobe-recommend-apps-screen"; - // Enables suggestions while typing on a physical keyboard. const char kEnablePhysicalKeyboardAutocorrect[] = "enable-physical-keyboard-autocorrect";
diff --git a/chromeos/chromeos_switches.h b/chromeos/chromeos_switches.h index 0e5c6ef..3dffb29 100644 --- a/chromeos/chromeos_switches.h +++ b/chromeos/chromeos_switches.h
@@ -102,7 +102,6 @@ CHROMEOS_EXPORT extern const char kEnableFirstRunUITransitions[]; CHROMEOS_EXPORT extern const char kEnableNetworkPortalNotification[]; CHROMEOS_EXPORT extern const char kEnableOfflineDemoMode[]; -CHROMEOS_EXPORT extern const char kEnableOobeRecommendAppsScreen[]; CHROMEOS_EXPORT extern const char kEnablePhysicalKeyboardAutocorrect[]; CHROMEOS_EXPORT extern const char kEnableRequestTabletSite[]; CHROMEOS_EXPORT extern const char kEnableScreenshotTestingWithMode[];
diff --git a/chromeos/cryptohome/async_method_caller.cc b/chromeos/cryptohome/async_method_caller.cc index 5e0cef0..6d6df50 100644 --- a/chromeos/cryptohome/async_method_caller.cc +++ b/chromeos/cryptohome/async_method_caller.cc
@@ -35,15 +35,6 @@ DBusThreadManager::Get()->GetCryptohomeClient()->RemoveObserver(this); } - void AsyncRemove(const Identification& cryptohome_id, - Callback callback) override { - DBusThreadManager::Get()->GetCryptohomeClient()->AsyncRemove( - CreateAccountIdentifierFromIdentification(cryptohome_id), - base::BindOnce(&AsyncMethodCallerImpl::RegisterAsyncCallback, - weak_ptr_factory_.GetWeakPtr(), callback, - "Couldn't initiate async removal of cryptohome.")); - } - void AsyncTpmAttestationCreateEnrollRequest( chromeos::attestation::PrivacyCAType pca_type, const DataCallback& callback) override {
diff --git a/chromeos/cryptohome/async_method_caller.h b/chromeos/cryptohome/async_method_caller.h index 5d69a14..9f3604623 100644 --- a/chromeos/cryptohome/async_method_caller.h +++ b/chromeos/cryptohome/async_method_caller.h
@@ -33,11 +33,6 @@ virtual ~AsyncMethodCaller() {} - // Asks cryptohomed to asynchronously try to find the cryptohome for - // |user_id| and then nuke it. - virtual void AsyncRemove(const Identification& user_id, - Callback callback) = 0; - // Asks cryptohomed to asynchronously create an attestation enrollment // request. On success the data sent to |callback| is a request to be sent // to the Privacy CA of type |pca_type|.
diff --git a/chromeos/cryptohome/cryptohome_util.cc b/chromeos/cryptohome/cryptohome_util.cc index b33c436..6a23526 100644 --- a/chromeos/cryptohome/cryptohome_util.cc +++ b/chromeos/cryptohome/cryptohome_util.cc
@@ -329,6 +329,8 @@ case CRYPTOHOME_ERROR_MOUNT_PREVIOUS_MIGRATION_INCOMPLETE: return MOUNT_ERROR_PREVIOUS_MIGRATION_INCOMPLETE; // TODO(crbug.com/797563): Split the error space and/or handle everything. + case CRYPTOHOME_ERROR_REMOVE_FAILED: + return MOUNT_ERROR_REMOVE_FAILED; case CRYPTOHOME_ERROR_LOCKBOX_SIGNATURE_INVALID: case CRYPTOHOME_ERROR_LOCKBOX_CANNOT_SIGN: case CRYPTOHOME_ERROR_BOOT_ATTRIBUTE_NOT_FOUND: @@ -342,7 +344,6 @@ case CRYPTOHOME_ERROR_FIRMWARE_MANAGEMENT_PARAMETERS_INVALID: case CRYPTOHOME_ERROR_FIRMWARE_MANAGEMENT_PARAMETERS_CANNOT_STORE: case CRYPTOHOME_ERROR_FIRMWARE_MANAGEMENT_PARAMETERS_CANNOT_REMOVE: - case CRYPTOHOME_ERROR_REMOVE_FAILED: NOTREACHED(); return MOUNT_ERROR_FATAL; }
diff --git a/chromeos/cryptohome/mock_async_method_caller.cc b/chromeos/cryptohome/mock_async_method_caller.cc index 69fc7c8..5d12363 100644 --- a/chromeos/cryptohome/mock_async_method_caller.cc +++ b/chromeos/cryptohome/mock_async_method_caller.cc
@@ -26,9 +26,6 @@ void MockAsyncMethodCaller::SetUp(bool success, MountError return_code) { success_ = success; return_code_ = return_code; - ON_CALL(*this, AsyncRemove(_, _)) - .WillByDefault( - WithArgs<1>(Invoke(this, &MockAsyncMethodCaller::DoCallback))); ON_CALL(*this, AsyncTpmAttestationCreateEnrollRequest(_, _)) .WillByDefault( WithArgs<1>(Invoke(this,
diff --git a/chromeos/cryptohome/mock_async_method_caller.h b/chromeos/cryptohome/mock_async_method_caller.h index 4df7c15c..a0003fb 100644 --- a/chromeos/cryptohome/mock_async_method_caller.h +++ b/chromeos/cryptohome/mock_async_method_caller.h
@@ -28,8 +28,6 @@ void SetUp(bool success, MountError return_code); - MOCK_METHOD2(AsyncRemove, - void(const Identification& user_id, Callback callback)); MOCK_METHOD2(AsyncTpmAttestationCreateEnrollRequest, void(chromeos::attestation::PrivacyCAType pca_type, const DataCallback& callback));
diff --git a/chromeos/dbus/cryptohome_client.cc b/chromeos/dbus/cryptohome_client.cc index c9f9f43..89f4af5 100644 --- a/chromeos/dbus/cryptohome_client.cc +++ b/chromeos/dbus/cryptohome_client.cc
@@ -114,15 +114,16 @@ } // CryptohomeClient override. - void AsyncRemove(const cryptohome::AccountIdentifier& id, - AsyncMethodCallback callback) override { + void RemoveEx(const cryptohome::AccountIdentifier& account, + DBusMethodCallback<cryptohome::BaseReply> callback) override { dbus::MethodCall method_call(cryptohome::kCryptohomeInterface, - cryptohome::kCryptohomeAsyncRemove); + cryptohome::kCryptohomeRemoveEx); dbus::MessageWriter writer(&method_call); - writer.AppendString(id.account_id()); + writer.AppendProtoAsArrayOfBytes(account); + proxy_->CallMethod( &method_call, kTpmDBusTimeoutMs, - base::BindOnce(&CryptohomeClientImpl::OnAsyncMethodCall, + base::BindOnce(&CryptohomeClientImpl::OnBaseReplyMethod, weak_ptr_factory_.GetWeakPtr(), std::move(callback))); }
diff --git a/chromeos/dbus/cryptohome_client.h b/chromeos/dbus/cryptohome_client.h index f2434c8..b1e404b 100644 --- a/chromeos/dbus/cryptohome_client.h +++ b/chromeos/dbus/cryptohome_client.h
@@ -156,10 +156,10 @@ const cryptohome::MigrateKeyRequest& migrate_request, DBusMethodCallback<cryptohome::BaseReply> callback) = 0; - // Calls AsyncRemove method. |callback| is called after the method call + // Calls RemoveEx method. |callback| is called after the method call // succeeds. - virtual void AsyncRemove(const cryptohome::AccountIdentifier& id, - AsyncMethodCallback callback) = 0; + virtual void RemoveEx(const cryptohome::AccountIdentifier& account, + DBusMethodCallback<cryptohome::BaseReply> callback) = 0; // Calls RenameCryptohome method. |callback| is called after the method // call succeeds.
diff --git a/chromeos/dbus/fake_cryptohome_client.cc b/chromeos/dbus/fake_cryptohome_client.cc index fe1cc368..4b6817b7 100644 --- a/chromeos/dbus/fake_cryptohome_client.cc +++ b/chromeos/dbus/fake_cryptohome_client.cc
@@ -97,10 +97,10 @@ ReturnProtobufMethodCallback(cryptohome::BaseReply(), std::move(callback)); } -void FakeCryptohomeClient::AsyncRemove( - const cryptohome::AccountIdentifier& cryptohome_id, - AsyncMethodCallback callback) { - ReturnAsyncMethodResult(std::move(callback)); +void FakeCryptohomeClient::RemoveEx( + const cryptohome::AccountIdentifier& account, + DBusMethodCallback<cryptohome::BaseReply> callback) { + ReturnProtobufMethodCallback(cryptohome::BaseReply(), std::move(callback)); } void FakeCryptohomeClient::RenameCryptohome(
diff --git a/chromeos/dbus/fake_cryptohome_client.h b/chromeos/dbus/fake_cryptohome_client.h index 137bb4d..9eb1ea29 100644 --- a/chromeos/dbus/fake_cryptohome_client.h +++ b/chromeos/dbus/fake_cryptohome_client.h
@@ -41,8 +41,8 @@ const cryptohome::AuthorizationRequest& auth_request, const cryptohome::MigrateKeyRequest& migrate_request, DBusMethodCallback<cryptohome::BaseReply> callback) override; - void AsyncRemove(const cryptohome::AccountIdentifier& cryptohome_id, - AsyncMethodCallback callback) override; + void RemoveEx(const cryptohome::AccountIdentifier& account, + DBusMethodCallback<cryptohome::BaseReply> callback) override; void RenameCryptohome( const cryptohome::AccountIdentifier& cryptohome_id_from, const cryptohome::AccountIdentifier& cryptohome_id_to,
diff --git a/chromeos/login/auth/cryptohome_authenticator.cc b/chromeos/login/auth/cryptohome_authenticator.cc index 2a2fdf7..1a393f7 100644 --- a/chromeos/login/auth/cryptohome_authenticator.cc +++ b/chromeos/login/auth/cryptohome_authenticator.cc
@@ -99,18 +99,6 @@ resolver->Resolve(); } -// Records status and calls resolver->Resolve() while adding login time marker. -void TriggerResolveWithLoginTimeMarker( - const std::string& marker_name, - const base::WeakPtr<AuthAttemptState>& attempt, - scoped_refptr<CryptohomeAuthenticator> resolver, - bool success, - cryptohome::MountError return_code) { - chromeos::LoginEventRecorder::Get()->AddLoginTimeMarker(marker_name, false); - attempt->RecordCryptohomeStatus(return_code); - resolver->Resolve(); -} - // Records an error in accessing the user's cryptohome with the given key and // calls resolver->Resolve() after adding a login time marker. void RecordKeyErrorAndResolve(const base::WeakPtr<AuthAttemptState>& attempt, @@ -504,10 +492,14 @@ scoped_refptr<CryptohomeAuthenticator> resolver) { chromeos::LoginEventRecorder::Get()->AddLoginTimeMarker( "CryptohomeRemove-Start", false); - cryptohome::AsyncMethodCaller::GetInstance()->AsyncRemove( - cryptohome::Identification(attempt->user_context.GetAccountId()), - base::Bind(&TriggerResolveWithLoginTimeMarker, "CryptohomeRemove-End", - attempt, resolver)); + + cryptohome::AccountIdentifier account_id; + account_id.set_account_id( + cryptohome::Identification(attempt->user_context.GetAccountId()).id()); + + DBusThreadManager::Get()->GetCryptohomeClient()->RemoveEx( + account_id, base::BindOnce(&OnBaseReplyMethod, attempt, resolver, + "CryptohomeRemove-End")); } void OnKeyChecked(const base::WeakPtr<AuthAttemptState>& attempt,
diff --git a/chromeos/services/multidevice_setup/BUILD.gn b/chromeos/services/multidevice_setup/BUILD.gn index 4d9e6cf..6bd0e83 100644 --- a/chromeos/services/multidevice_setup/BUILD.gn +++ b/chromeos/services/multidevice_setup/BUILD.gn
@@ -17,6 +17,10 @@ "eligible_host_devices_provider.h", "eligible_host_devices_provider_impl.cc", "eligible_host_devices_provider_impl.h", + "feature_state_manager.cc", + "feature_state_manager.h", + "feature_state_manager_impl.cc", + "feature_state_manager_impl.h", "host_backend_delegate.cc", "host_backend_delegate.h", "host_backend_delegate_impl.cc", @@ -73,6 +77,10 @@ "fake_account_status_change_delegate_notifier.h", "fake_eligible_host_devices_provider.cc", "fake_eligible_host_devices_provider.h", + "fake_feature_state_manager.cc", + "fake_feature_state_manager.h", + "fake_feature_state_observer.cc", + "fake_feature_state_observer.h", "fake_host_backend_delegate.cc", "fake_host_backend_delegate.h", "fake_host_status_observer.cc", @@ -101,6 +109,7 @@ sources = [ "account_status_change_delegate_notifier_impl_unittest.cc", "eligible_host_devices_provider_impl_unittest.cc", + "feature_state_manager_impl_unittest.cc", "host_backend_delegate_impl_unittest.cc", "host_status_provider_impl_unittest.cc", "host_verifier_impl_unittest.cc", @@ -115,6 +124,7 @@ "//base", "//base/test:test_support", "//chromeos/services/device_sync/public/cpp:test_support", + "//chromeos/services/multidevice_setup/public/cpp:prefs", "//chromeos/services/multidevice_setup/public/cpp:test_support", "//chromeos/services/multidevice_setup/public/cpp:unit_tests", "//chromeos/services/multidevice_setup/public/mojom",
diff --git a/chromeos/services/multidevice_setup/fake_feature_state_manager.cc b/chromeos/services/multidevice_setup/fake_feature_state_manager.cc new file mode 100644 index 0000000..e3b8fc6 --- /dev/null +++ b/chromeos/services/multidevice_setup/fake_feature_state_manager.cc
@@ -0,0 +1,77 @@ +// Copyright 2018 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 "chromeos/services/multidevice_setup/fake_feature_state_manager.h" + +namespace chromeos { + +namespace multidevice_setup { + +namespace { + +// Each feature's default value is kUnavailableNoVerifiedHost until proven +// otherwise. +FeatureStateManager::FeatureStatesMap GenerateInitialDefaultCachedStateMap() { + return FeatureStateManager::FeatureStatesMap{ + {mojom::Feature::kBetterTogetherSuite, + mojom::FeatureState::kUnavailableNoVerifiedHost}, + {mojom::Feature::kInstantTethering, + mojom::FeatureState::kUnavailableNoVerifiedHost}, + {mojom::Feature::kMessages, + mojom::FeatureState::kUnavailableNoVerifiedHost}, + {mojom::Feature::kSmartLock, + mojom::FeatureState::kUnavailableNoVerifiedHost}}; +} + +} // namespace + +FakeFeatureStateManager::FakeFeatureStateManager() + : feature_states_map_(GenerateInitialDefaultCachedStateMap()) {} + +FakeFeatureStateManager::~FakeFeatureStateManager() = default; + +void FakeFeatureStateManager::SetFeatureState(mojom::Feature feature, + mojom::FeatureState state) { + if (feature_states_map_[feature] == state) + return; + + feature_states_map_[feature] = state; + NotifyFeatureStatesChange(feature_states_map_); +} + +void FakeFeatureStateManager::SetFeatureStates( + const FeatureStatesMap& feature_states_map) { + if (feature_states_map_ == feature_states_map) + return; + + feature_states_map_ = feature_states_map; + NotifyFeatureStatesChange(feature_states_map_); +} + +FeatureStateManager::FeatureStatesMap +FakeFeatureStateManager::GetFeatureStates() { + return feature_states_map_; +} + +void FakeFeatureStateManager::PerformSetFeatureEnabledState( + mojom::Feature feature, + bool enabled) { + if (enabled) + SetFeatureState(feature, mojom::FeatureState::kEnabledByUser); + else + SetFeatureState(feature, mojom::FeatureState::kDisabledByUser); +} + +FakeFeatureStateManagerObserver::FakeFeatureStateManagerObserver() = default; + +FakeFeatureStateManagerObserver::~FakeFeatureStateManagerObserver() = default; + +void FakeFeatureStateManagerObserver::OnFeatureStatesChange( + const FeatureStateManager::FeatureStatesMap& feature_states_map) { + feature_state_updates_.emplace_back(feature_states_map); +} + +} // namespace multidevice_setup + +} // namespace chromeos
diff --git a/chromeos/services/multidevice_setup/fake_feature_state_manager.h b/chromeos/services/multidevice_setup/fake_feature_state_manager.h new file mode 100644 index 0000000..9a6969c --- /dev/null +++ b/chromeos/services/multidevice_setup/fake_feature_state_manager.h
@@ -0,0 +1,65 @@ +// Copyright 2018 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 CHROMEOS_SERVICES_MULTIDEVICE_SETUP_FAKE_FEATURE_STATE_MANAGER_H_ +#define CHROMEOS_SERVICES_MULTIDEVICE_SETUP_FAKE_FEATURE_STATE_MANAGER_H_ + +#include "base/containers/flat_map.h" +#include "base/macros.h" +#include "chromeos/services/multidevice_setup/feature_state_manager.h" +#include "chromeos/services/multidevice_setup/public/mojom/multidevice_setup.mojom.h" + +namespace chromeos { + +namespace multidevice_setup { + +// Test FeatureStateManager implementation. This class initializes all features +// to be state mojom::FeatureState::kUnavailableNoVerifiedHost. +class FakeFeatureStateManager : public FeatureStateManager { + public: + FakeFeatureStateManager(); + ~FakeFeatureStateManager() override; + + void SetFeatureState(mojom::Feature feature, mojom::FeatureState state); + void SetFeatureStates(const FeatureStatesMap& feature_states_map); + + using FeatureStateManager::NotifyFeatureStatesChange; + + private: + // FeatureStateManager: + FeatureStatesMap GetFeatureStates() override; + void PerformSetFeatureEnabledState(mojom::Feature feature, + bool enabled) override; + + FeatureStatesMap feature_states_map_; + + DISALLOW_COPY_AND_ASSIGN(FakeFeatureStateManager); +}; + +// Test FeatureStateManager::Observer implementation. +class FakeFeatureStateManagerObserver : public FeatureStateManager::Observer { + public: + FakeFeatureStateManagerObserver(); + ~FakeFeatureStateManagerObserver() override; + + const std::vector<FeatureStateManager::FeatureStatesMap>& + feature_state_updates() const { + return feature_state_updates_; + } + + private: + // FeatureStateManager::Observer: + void OnFeatureStatesChange( + const FeatureStateManager::FeatureStatesMap& feature_states_map) override; + + std::vector<FeatureStateManager::FeatureStatesMap> feature_state_updates_; + + DISALLOW_COPY_AND_ASSIGN(FakeFeatureStateManagerObserver); +}; + +} // namespace multidevice_setup + +} // namespace chromeos + +#endif // CHROMEOS_SERVICES_MULTIDEVICE_SETUP_FAKE_FEATURE_STATE_MANAGER_H_
diff --git a/chromeos/services/multidevice_setup/fake_feature_state_observer.cc b/chromeos/services/multidevice_setup/fake_feature_state_observer.cc new file mode 100644 index 0000000..3b2503d --- /dev/null +++ b/chromeos/services/multidevice_setup/fake_feature_state_observer.cc
@@ -0,0 +1,30 @@ +// Copyright 2018 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 "chromeos/services/multidevice_setup/fake_feature_state_observer.h" + +namespace chromeos { + +namespace multidevice_setup { + +FakeFeatureStateObserver::FakeFeatureStateObserver() = default; + +FakeFeatureStateObserver::~FakeFeatureStateObserver() = default; + +mojom::FeatureStateObserverPtr +FakeFeatureStateObserver::GenerateInterfacePtr() { + mojom::FeatureStateObserverPtr interface_ptr; + bindings_.AddBinding(this, mojo::MakeRequest(&interface_ptr)); + return interface_ptr; +} + +void FakeFeatureStateObserver::OnFeatureStatesChanged( + const base::flat_map<mojom::Feature, mojom::FeatureState>& + feature_states_map) { + feature_state_updates_.emplace_back(feature_states_map); +} + +} // namespace multidevice_setup + +} // namespace chromeos
diff --git a/chromeos/services/multidevice_setup/fake_feature_state_observer.h b/chromeos/services/multidevice_setup/fake_feature_state_observer.h new file mode 100644 index 0000000..2764644c --- /dev/null +++ b/chromeos/services/multidevice_setup/fake_feature_state_observer.h
@@ -0,0 +1,49 @@ +// Copyright 2018 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 CHROMEOS_SERVICES_MULTIDEVICE_SETUP_FAKE_FEATURE_STATE_OBSERVER_H_ +#define CHROMEOS_SERVICES_MULTIDEVICE_SETUP_FAKE_FEATURE_STATE_OBSERVER_H_ + +#include "base/containers/flat_map.h" +#include "base/macros.h" +#include "base/optional.h" +#include "chromeos/services/multidevice_setup/public/mojom/multidevice_setup.mojom.h" +#include "mojo/public/cpp/bindings/binding_set.h" + +namespace chromeos { + +namespace multidevice_setup { + +// Fake mojom::FeatureStateObserver implementation for tests. +class FakeFeatureStateObserver : public mojom::FeatureStateObserver { + public: + FakeFeatureStateObserver(); + ~FakeFeatureStateObserver() override; + + mojom::FeatureStateObserverPtr GenerateInterfacePtr(); + + const std::vector<base::flat_map<mojom::Feature, mojom::FeatureState>>& + feature_state_updates() { + return feature_state_updates_; + } + + private: + // mojom::FeatureStateObserver: + void OnFeatureStatesChanged( + const base::flat_map<mojom::Feature, mojom::FeatureState>& + feature_states_map) override; + + std::vector<base::flat_map<mojom::Feature, mojom::FeatureState>> + feature_state_updates_; + + mojo::BindingSet<mojom::FeatureStateObserver> bindings_; + + DISALLOW_COPY_AND_ASSIGN(FakeFeatureStateObserver); +}; + +} // namespace multidevice_setup + +} // namespace chromeos + +#endif // CHROMEOS_SERVICES_MULTIDEVICE_SETUP_FAKE_FEATURE_STATE_OBSERVER_H_
diff --git a/chromeos/services/multidevice_setup/fake_host_status_provider.h b/chromeos/services/multidevice_setup/fake_host_status_provider.h index 30b7b866..c0fbe6a 100644 --- a/chromeos/services/multidevice_setup/fake_host_status_provider.h +++ b/chromeos/services/multidevice_setup/fake_host_status_provider.h
@@ -24,10 +24,10 @@ mojom::HostStatus host_status, const base::Optional<cryptauth::RemoteDeviceRef>& host_device); - private: // HostStatusProvider: HostStatusWithDevice GetHostWithStatus() const override; + private: mojom::HostStatus host_status_ = mojom::HostStatus::kNoEligibleHosts; base::Optional<cryptauth::RemoteDeviceRef> host_device_;
diff --git a/chromeos/services/multidevice_setup/feature_state_manager.cc b/chromeos/services/multidevice_setup/feature_state_manager.cc new file mode 100644 index 0000000..bb078348 --- /dev/null +++ b/chromeos/services/multidevice_setup/feature_state_manager.cc
@@ -0,0 +1,46 @@ +// Copyright 2018 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 "chromeos/services/multidevice_setup/feature_state_manager.h" + +namespace chromeos { + +namespace multidevice_setup { + +FeatureStateManager::FeatureStateManager() = default; + +FeatureStateManager::~FeatureStateManager() = default; + +bool FeatureStateManager::SetFeatureEnabledState(mojom::Feature feature, + bool enabled) { + mojom::FeatureState state = GetFeatureStates()[feature]; + + // Changing the state is only allowed when changing from enabled to disabled + // or disabled to enabled. + if ((state == mojom::FeatureState::kEnabledByUser && !enabled) || + (state == mojom::FeatureState::kDisabledByUser && enabled)) { + PerformSetFeatureEnabledState(feature, enabled); + return true; + } + + return false; +} + +void FeatureStateManager::AddObserver(Observer* observer) { + observer_list_.AddObserver(observer); +} + +void FeatureStateManager::RemoveObserver(Observer* observer) { + observer_list_.RemoveObserver(observer); +} + +void FeatureStateManager::NotifyFeatureStatesChange( + const FeatureStatesMap& feature_states_map) { + for (auto& observer : observer_list_) + observer.OnFeatureStatesChange(feature_states_map); +} + +} // namespace multidevice_setup + +} // namespace chromeos
diff --git a/chromeos/services/multidevice_setup/feature_state_manager.h b/chromeos/services/multidevice_setup/feature_state_manager.h new file mode 100644 index 0000000..9af9292 --- /dev/null +++ b/chromeos/services/multidevice_setup/feature_state_manager.h
@@ -0,0 +1,65 @@ +// Copyright 2018 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 CHROMEOS_SERVICES_MULTIDEVICE_SETUP_FEATURE_STATE_MANAGER_H_ +#define CHROMEOS_SERVICES_MULTIDEVICE_SETUP_FEATURE_STATE_MANAGER_H_ + +#include "base/containers/flat_map.h" +#include "base/macros.h" +#include "base/observer_list.h" +#include "chromeos/services/multidevice_setup/public/mojom/multidevice_setup.mojom.h" + +namespace chromeos { + +namespace multidevice_setup { + +// Tracks the state of the multi-device features, providing a getter/observer +// interface as well as a way to toggle a feature on/off when appropriate. +class FeatureStateManager { + public: + using FeatureStatesMap = base::flat_map<mojom::Feature, mojom::FeatureState>; + + class Observer { + public: + virtual ~Observer() = default; + + // Invoked when one or more features have changed state. + virtual void OnFeatureStatesChange( + const FeatureStatesMap& feature_states_map) = 0; + }; + + virtual ~FeatureStateManager(); + + virtual FeatureStatesMap GetFeatureStates() = 0; + + // Attempts to enable or disable the feature; returns whether this operation + // succeeded. A feature can only be changed via this function if the current + // state is mojom::FeatureState::kEnabledByUser or + // mojom::FeatureState::kDisabledByUser. + bool SetFeatureEnabledState(mojom::Feature feature, bool enabled); + + void AddObserver(Observer* observer); + void RemoveObserver(Observer* observer); + + protected: + FeatureStateManager(); + + // Enables or disables the feature; by the time this function has been called, + // it has already been confirmed that the state is indeed able to be changed. + virtual void PerformSetFeatureEnabledState(mojom::Feature feature, + bool enabled) = 0; + + void NotifyFeatureStatesChange(const FeatureStatesMap& feature_states_map); + + private: + base::ObserverList<Observer> observer_list_; + + DISALLOW_COPY_AND_ASSIGN(FeatureStateManager); +}; + +} // namespace multidevice_setup + +} // namespace chromeos + +#endif // CHROMEOS_SERVICES_MULTIDEVICE_SETUP_FEATURE_STATE_MANAGER_H_
diff --git a/chromeos/services/multidevice_setup/feature_state_manager_impl.cc b/chromeos/services/multidevice_setup/feature_state_manager_impl.cc new file mode 100644 index 0000000..4ae4b67 --- /dev/null +++ b/chromeos/services/multidevice_setup/feature_state_manager_impl.cc
@@ -0,0 +1,292 @@ +// Copyright 2018 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 "chromeos/services/multidevice_setup/feature_state_manager_impl.h" + +#include "base/bind.h" +#include "base/logging.h" +#include "base/memory/ptr_util.h" +#include "base/no_destructor.h" +#include "base/optional.h" +#include "base/stl_util.h" +#include "chromeos/components/proximity_auth/logging/logging.h" +#include "chromeos/services/multidevice_setup/public/cpp/prefs.h" +#include "components/cryptauth/remote_device_ref.h" +#include "components/prefs/pref_service.h" + +namespace chromeos { + +namespace multidevice_setup { + +namespace { + +// TODO(jordynass): Use constants declared in +// chromeos/services/multidevice_setup/public/cpp/prefs.h once migration is +// complete, then delete these fields which are duplicates. See +// https://crbug.com/870065. +const char kSmartLockFeatureEnabledPrefName[] = "easy_unlock.enabled"; +const char kSmartLockFeatureAllowedPrefName[] = "easy_unlock.allowed"; + +base::flat_map<mojom::Feature, std::string> +GenerateFeatureToEnabledPrefNameMap() { + return base::flat_map<mojom::Feature, std::string>{ + {mojom::Feature::kBetterTogetherSuite, kSuiteEnabledPrefName}, + {mojom::Feature::kInstantTethering, + kInstantTetheringFeatureEnabledPrefName}, + {mojom::Feature::kMessages, kAndroidMessagesFeatureEnabledPrefName}, + {mojom::Feature::kSmartLock, kSmartLockFeatureEnabledPrefName}}; +} + +base::flat_map<mojom::Feature, std::string> +GenerateFeatureToAllowedPrefNameMap() { + return base::flat_map<mojom::Feature, std::string>{ + {mojom::Feature::kInstantTethering, + kInstantTetheringFeatureAllowedPrefName}, + {mojom::Feature::kSmartLock, kSmartLockFeatureAllowedPrefName}}; +} + +// Each feature's default value is kUnavailableNoVerifiedHost until proven +// otherwise. +base::flat_map<mojom::Feature, mojom::FeatureState> +GenerateInitialDefaultCachedStateMap() { + return base::flat_map<mojom::Feature, mojom::FeatureState>{ + {mojom::Feature::kBetterTogetherSuite, + mojom::FeatureState::kUnavailableNoVerifiedHost}, + {mojom::Feature::kInstantTethering, + mojom::FeatureState::kUnavailableNoVerifiedHost}, + {mojom::Feature::kMessages, + mojom::FeatureState::kUnavailableNoVerifiedHost}, + {mojom::Feature::kSmartLock, + mojom::FeatureState::kUnavailableNoVerifiedHost}}; +} + +} // namespace + +// static +FeatureStateManagerImpl::Factory* + FeatureStateManagerImpl::Factory::test_factory_ = nullptr; + +// static +FeatureStateManagerImpl::Factory* FeatureStateManagerImpl::Factory::Get() { + if (test_factory_) + return test_factory_; + + static base::NoDestructor<Factory> factory; + return factory.get(); +} + +// static +void FeatureStateManagerImpl::Factory::SetFactoryForTesting( + Factory* test_factory) { + test_factory_ = test_factory; +} + +FeatureStateManagerImpl::Factory::~Factory() = default; + +std::unique_ptr<FeatureStateManager> +FeatureStateManagerImpl::Factory::BuildInstance( + PrefService* pref_service, + HostStatusProvider* host_status_provider, + device_sync::DeviceSyncClient* device_sync_client) { + return base::WrapUnique(new FeatureStateManagerImpl( + pref_service, host_status_provider, device_sync_client)); +} + +FeatureStateManagerImpl::FeatureStateManagerImpl( + PrefService* pref_service, + HostStatusProvider* host_status_provider, + device_sync::DeviceSyncClient* device_sync_client) + : pref_service_(pref_service), + host_status_provider_(host_status_provider), + device_sync_client_(device_sync_client), + feature_to_enabled_pref_name_map_(GenerateFeatureToEnabledPrefNameMap()), + feature_to_allowed_pref_name_map_(GenerateFeatureToAllowedPrefNameMap()), + cached_feature_state_map_(GenerateInitialDefaultCachedStateMap()) { + host_status_provider_->AddObserver(this); + device_sync_client_->AddObserver(this); + + registrar_.Init(pref_service_); + + // Listen for changes to each of the "enabled" feature names. + for (const auto& map_entry : feature_to_enabled_pref_name_map_) { + registrar_.Add( + map_entry.second, + base::BindRepeating(&FeatureStateManagerImpl::OnPrefValueChanged, + base::Unretained(this))); + } + + // Also listen for changes to each of the "allowed" feature names. + for (const auto& map_entry : feature_to_allowed_pref_name_map_) { + registrar_.Add( + map_entry.second, + base::BindRepeating(&FeatureStateManagerImpl::OnPrefValueChanged, + base::Unretained(this))); + } + + // Prime the cache. Since this is the initial computation, it does not + // represent a true change of feature state values, so observers should not be + // notified. + UpdateFeatureStateCache(false /* notify_observers_of_changes */); +} + +FeatureStateManagerImpl::~FeatureStateManagerImpl() { + host_status_provider_->RemoveObserver(this); + device_sync_client_->RemoveObserver(this); +} + +FeatureStateManager::FeatureStatesMap +FeatureStateManagerImpl::GetFeatureStates() { + return cached_feature_state_map_; +} + +void FeatureStateManagerImpl::PerformSetFeatureEnabledState( + mojom::Feature feature, + bool enabled) { + // Note: Since |registrar_| observes changes to all relevant preferences, + // this call will result in OnPrefValueChanged() being invoked, resulting in + // observers being notified of the change. + pref_service_->SetBoolean(feature_to_enabled_pref_name_map_[feature], + enabled); +} + +void FeatureStateManagerImpl::OnHostStatusChange( + const HostStatusProvider::HostStatusWithDevice& host_status_with_device) { + UpdateFeatureStateCache(true /* notify_observers_of_changes */); +} + +void FeatureStateManagerImpl::OnNewDevicesSynced() { + UpdateFeatureStateCache(true /* notify_observers_of_changes */); +} + +void FeatureStateManagerImpl::OnPrefValueChanged() { + UpdateFeatureStateCache(true /* notify_observers_of_changes */); +} + +void FeatureStateManagerImpl::UpdateFeatureStateCache( + bool notify_observers_of_changes) { + // Make a copy of |cached_feature_state_map_| before making edits to it. + FeatureStatesMap previous_cached_feature_state_map = + cached_feature_state_map_; + + // Update |cached_feature_state_map_|. + auto it = cached_feature_state_map_.begin(); + while (it != cached_feature_state_map_.end()) { + it->second = ComputeFeatureState(it->first); + ++it; + } + + if (previous_cached_feature_state_map == cached_feature_state_map_) + return; + + NotifyFeatureStatesChange(cached_feature_state_map_); +} + +mojom::FeatureState FeatureStateManagerImpl::ComputeFeatureState( + mojom::Feature feature) { + HostStatusProvider::HostStatusWithDevice status_with_device = + host_status_provider_->GetHostWithStatus(); + + if (status_with_device.host_status() != mojom::HostStatus::kHostVerified) + return mojom::FeatureState::kUnavailableNoVerifiedHost; + + if (!IsSupportedByChromebook(feature)) + return mojom::FeatureState::kNotSupportedByChromebook; + + if (!HasSufficientSecurity(feature, *status_with_device.host_device())) + return mojom::FeatureState::kUnavailableInsufficientSecurity; + + if (!HasBeenActivatedByPhone(feature, *status_with_device.host_device())) + return mojom::FeatureState::kNotSupportedByPhone; + + return GetEnabledOrDisabledState(feature); +} + +bool FeatureStateManagerImpl::IsSupportedByChromebook(mojom::Feature feature) { + static const std::pair<mojom::Feature, cryptauth::SoftwareFeature> + kFeatureAndClientSoftwareFeaturePairs[] = { + {mojom::Feature::kBetterTogetherSuite, + cryptauth::SoftwareFeature::BETTER_TOGETHER_CLIENT}, + {mojom::Feature::kInstantTethering, + cryptauth::SoftwareFeature::MAGIC_TETHER_CLIENT}, + {mojom::Feature::kMessages, + cryptauth::SoftwareFeature::SMS_CONNECT_CLIENT}, + {mojom::Feature::kSmartLock, + cryptauth::SoftwareFeature::EASY_UNLOCK_CLIENT}}; + + for (const auto& pair : kFeatureAndClientSoftwareFeaturePairs) { + if (pair.first != feature) + continue; + + return device_sync_client_->GetLocalDeviceMetadata() + ->GetSoftwareFeatureState(pair.second) != + cryptauth::SoftwareFeatureState::kNotSupported; + } + + NOTREACHED(); + return false; +} + +bool FeatureStateManagerImpl::HasSufficientSecurity( + mojom::Feature feature, + const cryptauth::RemoteDeviceRef& host_device) { + if (feature != mojom::Feature::kSmartLock) + return true; + + // Special case for Smart Lock: if the host device does not have a lock screen + // set, its SoftwareFeatureState for EASY_UNLOCK_HOST is supported but not + // enabled. + return host_device.GetSoftwareFeatureState( + cryptauth::SoftwareFeature::EASY_UNLOCK_HOST) != + cryptauth::SoftwareFeatureState::kSupported; +} + +bool FeatureStateManagerImpl::HasBeenActivatedByPhone( + mojom::Feature feature, + const cryptauth::RemoteDeviceRef& host_device) { + static const std::pair<mojom::Feature, cryptauth::SoftwareFeature> + kFeatureAndHostSoftwareFeaturePairs[] = { + {mojom::Feature::kBetterTogetherSuite, + cryptauth::SoftwareFeature::BETTER_TOGETHER_HOST}, + {mojom::Feature::kInstantTethering, + cryptauth::SoftwareFeature::MAGIC_TETHER_HOST}, + {mojom::Feature::kMessages, + cryptauth::SoftwareFeature::SMS_CONNECT_HOST}, + {mojom::Feature::kSmartLock, + cryptauth::SoftwareFeature::EASY_UNLOCK_HOST}}; + + for (const auto& pair : kFeatureAndHostSoftwareFeaturePairs) { + if (pair.first != feature) + continue; + + return host_device.GetSoftwareFeatureState(pair.second) == + cryptauth::SoftwareFeatureState::kEnabled; + } + + NOTREACHED(); + return false; +} + +mojom::FeatureState FeatureStateManagerImpl::GetEnabledOrDisabledState( + mojom::Feature feature) { + // If an "allowed pref" exists for this feature and that preference is set to + // false, the feature is disabled by policy. + if (base::ContainsKey(feature_to_allowed_pref_name_map_, feature) && + !pref_service_->GetBoolean(feature_to_allowed_pref_name_map_[feature])) { + return mojom::FeatureState::kDisabledByPolicy; + } + + if (!base::ContainsKey(feature_to_enabled_pref_name_map_, feature)) { + PA_LOG(ERROR) << "FeatureStateManagerImpl::GetEnabledOrDisabledState(): " + << "Feature not present in \"enabled pref\" map: " << feature; + NOTREACHED(); + } + + return pref_service_->GetBoolean(feature_to_enabled_pref_name_map_[feature]) + ? mojom::FeatureState::kEnabledByUser + : mojom::FeatureState::kDisabledByUser; +} + +} // namespace multidevice_setup + +} // namespace chromeos
diff --git a/chromeos/services/multidevice_setup/feature_state_manager_impl.h b/chromeos/services/multidevice_setup/feature_state_manager_impl.h new file mode 100644 index 0000000..04c7724 --- /dev/null +++ b/chromeos/services/multidevice_setup/feature_state_manager_impl.h
@@ -0,0 +1,100 @@ +// Copyright 2018 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 CHROMEOS_SERVICES_MULTIDEVICE_SETUP_FEATURE_STATE_MANAGER_IMPL_H_ +#define CHROMEOS_SERVICES_MULTIDEVICE_SETUP_FEATURE_STATE_MANAGER_IMPL_H_ + +#include "base/containers/flat_map.h" +#include "base/macros.h" +#include "chromeos/services/device_sync/public/cpp/device_sync_client.h" +#include "chromeos/services/multidevice_setup/feature_state_manager.h" +#include "chromeos/services/multidevice_setup/host_status_provider.h" +#include "chromeos/services/multidevice_setup/public/mojom/multidevice_setup.mojom.h" +#include "components/prefs/pref_change_registrar.h" + +class PrefService; + +namespace chromeos { + +namespace multidevice_setup { + +// Concrete FeatureStateManager implementation. This class relies on +// HostStatusProvider and DeviceSyncClient to determine if features are +// available at all (features are not available unless a verified host is set +// which has enabled the features). To track enabled/disabled/policy state, this +// class utilizes per-user preferences. +class FeatureStateManagerImpl : public FeatureStateManager, + public HostStatusProvider::Observer, + public device_sync::DeviceSyncClient::Observer { + public: + class Factory { + public: + static Factory* Get(); + static void SetFactoryForTesting(Factory* test_factory); + virtual ~Factory(); + virtual std::unique_ptr<FeatureStateManager> BuildInstance( + PrefService* pref_service, + HostStatusProvider* host_status_provider, + device_sync::DeviceSyncClient* device_sync_client); + + private: + static Factory* test_factory_; + }; + + ~FeatureStateManagerImpl() override; + + private: + FeatureStateManagerImpl(PrefService* pref_service, + HostStatusProvider* host_status_provider, + device_sync::DeviceSyncClient* device_sync_client); + + // FeatureStateManager: + FeatureStatesMap GetFeatureStates() override; + void PerformSetFeatureEnabledState(mojom::Feature feature, + bool enabled) override; + + // HostStatusProvider::Observer, + void OnHostStatusChange(const HostStatusProvider::HostStatusWithDevice& + host_status_with_device) override; + + // DeviceSyncClient::Observer: + void OnNewDevicesSynced() override; + + void OnPrefValueChanged(); + void UpdateFeatureStateCache(bool notify_observers_of_changes); + mojom::FeatureState ComputeFeatureState(mojom::Feature feature); + bool IsSupportedByChromebook(mojom::Feature feature); + bool HasSufficientSecurity(mojom::Feature feature, + const cryptauth::RemoteDeviceRef& host_device); + bool HasBeenActivatedByPhone(mojom::Feature feature, + const cryptauth::RemoteDeviceRef& host_device); + mojom::FeatureState GetEnabledOrDisabledState(mojom::Feature feature); + + PrefService* pref_service_; + HostStatusProvider* host_status_provider_; + device_sync::DeviceSyncClient* device_sync_client_; + + // Map from feature to the pref name which indicates the enabled/disabled + // boolean state for the feature. + base::flat_map<mojom::Feature, std::string> feature_to_enabled_pref_name_map_; + + // Same as above, except that the pref names represent whether the feature is + // allowed by policy or not. + base::flat_map<mojom::Feature, std::string> feature_to_allowed_pref_name_map_; + + // Map from feature to state, which is updated each time a feature's state + // changes. This cache is used to determine when a feature's state has changed + // so that observers can be notified. + FeatureStatesMap cached_feature_state_map_; + + PrefChangeRegistrar registrar_; + + DISALLOW_COPY_AND_ASSIGN(FeatureStateManagerImpl); +}; + +} // namespace multidevice_setup + +} // namespace chromeos + +#endif // CHROMEOS_SERVICES_MULTIDEVICE_SETUP_FEATURE_STATE_MANAGER_IMPL_H_
diff --git a/chromeos/services/multidevice_setup/feature_state_manager_impl_unittest.cc b/chromeos/services/multidevice_setup/feature_state_manager_impl_unittest.cc new file mode 100644 index 0000000..eb7da62 --- /dev/null +++ b/chromeos/services/multidevice_setup/feature_state_manager_impl_unittest.cc
@@ -0,0 +1,335 @@ +// Copyright 2018 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 "chromeos/services/multidevice_setup/feature_state_manager_impl.h" + +#include <memory> + +#include "base/macros.h" +#include "base/optional.h" +#include "chromeos/services/device_sync/public/cpp/fake_device_sync_client.h" +#include "chromeos/services/multidevice_setup/fake_feature_state_manager.h" +#include "chromeos/services/multidevice_setup/fake_host_status_provider.h" +#include "chromeos/services/multidevice_setup/public/cpp/prefs.h" +#include "components/cryptauth/remote_device_test_util.h" +#include "components/sync_preferences/testing_pref_service_syncable.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace chromeos { + +namespace multidevice_setup { + +namespace { + +// TODO(jordynass): Use constants declared in +// chromeos/services/multidevice_setup/public/cpp/prefs.h once migration is +// complete, then delete these fields which are duplicates. +const char kSmartLockFeatureEnabledPrefName[] = "easy_unlock.enabled"; +const char kSmartLockFeatureAllowedPrefName[] = "easy_unlock.allowed"; + +cryptauth::RemoteDeviceRef CreateTestHostDevice() { + cryptauth::RemoteDeviceRef host_device = + cryptauth::CreateRemoteDeviceRefForTest(); + + // Set all host features to supported. + cryptauth::RemoteDevice* raw_device = + cryptauth::GetMutableRemoteDevice(host_device); + raw_device + ->software_features[cryptauth::SoftwareFeature::BETTER_TOGETHER_HOST] = + cryptauth::SoftwareFeatureState::kSupported; + raw_device->software_features[cryptauth::SoftwareFeature::EASY_UNLOCK_HOST] = + cryptauth::SoftwareFeatureState::kSupported; + raw_device->software_features[cryptauth::SoftwareFeature::MAGIC_TETHER_HOST] = + cryptauth::SoftwareFeatureState::kSupported; + raw_device->software_features[cryptauth::SoftwareFeature::SMS_CONNECT_HOST] = + cryptauth::SoftwareFeatureState::kSupported; + + return host_device; +} + +} // namespace + +class MultiDeviceSetupFeatureStateManagerImplTest : public testing::Test { + protected: + MultiDeviceSetupFeatureStateManagerImplTest() + : test_local_device_(cryptauth::CreateRemoteDeviceRefForTest()), + test_host_device_(CreateTestHostDevice()) {} + ~MultiDeviceSetupFeatureStateManagerImplTest() override = default; + + // testing::Test: + void SetUp() override { + test_pref_service_ = + std::make_unique<sync_preferences::TestingPrefServiceSyncable>(); + user_prefs::PrefRegistrySyncable* registry = test_pref_service_->registry(); + RegisterFeaturePrefs(registry); + // TODO(jordynass): Remove the registration of these preferences once they + // are migrated. + registry->RegisterBooleanPref(kSmartLockFeatureAllowedPrefName, true); + registry->RegisterBooleanPref(kSmartLockFeatureEnabledPrefName, true); + + fake_host_status_provider_ = std::make_unique<FakeHostStatusProvider>(); + + fake_device_sync_client_ = + std::make_unique<device_sync::FakeDeviceSyncClient>(); + fake_device_sync_client_->set_synced_devices( + cryptauth::RemoteDeviceRefList{test_local_device_, test_host_device_}); + fake_device_sync_client_->set_local_device_metadata(test_local_device_); + + manager_ = FeatureStateManagerImpl::Factory::Get()->BuildInstance( + test_pref_service_.get(), fake_host_status_provider_.get(), + fake_device_sync_client_.get()); + + fake_observer_ = std::make_unique<FakeFeatureStateManagerObserver>(); + manager_->AddObserver(fake_observer_.get()); + } + + void TryAllUnverifiedHostStatesAndVerifyFeatureState(mojom::Feature feature) { + bool was_previously_verified = + fake_host_status_provider_->GetHostWithStatus().host_status() == + mojom::HostStatus::kHostVerified; + size_t num_observer_events_before_call = + fake_observer_->feature_state_updates().size(); + size_t expected_num_observer_events_after_call = + num_observer_events_before_call + (was_previously_verified ? 1u : 0u); + + fake_host_status_provider_->SetHostWithStatus( + mojom::HostStatus::kNoEligibleHosts, base::nullopt /* host_device */); + if (was_previously_verified) { + VerifyFeatureStateChange(num_observer_events_before_call, feature, + mojom::FeatureState::kUnavailableNoVerifiedHost); + } + EXPECT_EQ(mojom::FeatureState::kUnavailableNoVerifiedHost, + manager_->GetFeatureStates()[feature]); + EXPECT_EQ(expected_num_observer_events_after_call, + fake_observer_->feature_state_updates().size()); + + fake_host_status_provider_->SetHostWithStatus( + mojom::HostStatus::kEligibleHostExistsButNoHostSet, + base::nullopt /* host_device */); + EXPECT_EQ(mojom::FeatureState::kUnavailableNoVerifiedHost, + manager_->GetFeatureStates()[feature]); + EXPECT_EQ(expected_num_observer_events_after_call, + fake_observer_->feature_state_updates().size()); + + fake_host_status_provider_->SetHostWithStatus( + mojom::HostStatus::kHostSetLocallyButWaitingForBackendConfirmation, + test_host_device_); + EXPECT_EQ(mojom::FeatureState::kUnavailableNoVerifiedHost, + manager_->GetFeatureStates()[feature]); + EXPECT_EQ(expected_num_observer_events_after_call, + fake_observer_->feature_state_updates().size()); + + fake_host_status_provider_->SetHostWithStatus( + mojom::HostStatus::kHostSetButNotYetVerified, test_host_device_); + EXPECT_EQ(mojom::FeatureState::kUnavailableNoVerifiedHost, + manager_->GetFeatureStates()[feature]); + EXPECT_EQ(expected_num_observer_events_after_call, + fake_observer_->feature_state_updates().size()); + } + + void SetVerifiedHost() { + // Should not already be verified if we are setting it to be verified. + EXPECT_NE(mojom::HostStatus::kHostVerified, + fake_host_status_provider_->GetHostWithStatus().host_status()); + + size_t num_observer_events_before_call = + fake_observer_->feature_state_updates().size(); + + SetSoftwareFeatureState(false /* use_local_device */, + cryptauth::SoftwareFeature::BETTER_TOGETHER_HOST, + cryptauth::SoftwareFeatureState::kEnabled); + fake_host_status_provider_->SetHostWithStatus( + mojom::HostStatus::kHostVerified, test_host_device_); + + // Since the host is now verified, there should be a feature state update + // for all features. + EXPECT_EQ(num_observer_events_before_call + 1u, + fake_observer_->feature_state_updates().size()); + } + + void VerifyFeatureStateChange(size_t expected_index, + mojom::Feature expected_feature, + mojom::FeatureState expected_feature_state) { + const FeatureStateManager::FeatureStatesMap& map = + fake_observer_->feature_state_updates()[expected_index]; + const auto it = map.find(expected_feature); + EXPECT_NE(map.end(), it); + EXPECT_EQ(expected_feature_state, it->second); + } + + void SetSoftwareFeatureState( + bool use_local_device, + cryptauth::SoftwareFeature software_feature, + cryptauth::SoftwareFeatureState software_feature_state) { + cryptauth::RemoteDeviceRef& device = + use_local_device ? test_local_device_ : test_host_device_; + cryptauth::GetMutableRemoteDevice(device) + ->software_features[software_feature] = software_feature_state; + fake_device_sync_client_->NotifyNewDevicesSynced(); + } + + sync_preferences::TestingPrefServiceSyncable* test_pref_service() { + return test_pref_service_.get(); + } + + FeatureStateManager* manager() { return manager_.get(); } + + private: + cryptauth::RemoteDeviceRef test_local_device_; + cryptauth::RemoteDeviceRef test_host_device_; + + std::unique_ptr<sync_preferences::TestingPrefServiceSyncable> + test_pref_service_; + std::unique_ptr<FakeHostStatusProvider> fake_host_status_provider_; + std::unique_ptr<device_sync::FakeDeviceSyncClient> fake_device_sync_client_; + + std::unique_ptr<FakeFeatureStateManagerObserver> fake_observer_; + + std::unique_ptr<FeatureStateManager> manager_; + + DISALLOW_COPY_AND_ASSIGN(MultiDeviceSetupFeatureStateManagerImplTest); +}; + +TEST_F(MultiDeviceSetupFeatureStateManagerImplTest, BetterTogetherSuite) { + TryAllUnverifiedHostStatesAndVerifyFeatureState( + mojom::Feature::kBetterTogetherSuite); + + SetVerifiedHost(); + EXPECT_EQ( + mojom::FeatureState::kNotSupportedByChromebook, + manager()->GetFeatureStates()[mojom::Feature::kBetterTogetherSuite]); + + SetSoftwareFeatureState(true /* use_local_device */, + cryptauth::SoftwareFeature::BETTER_TOGETHER_CLIENT, + cryptauth::SoftwareFeatureState::kSupported); + EXPECT_EQ( + mojom::FeatureState::kEnabledByUser, + manager()->GetFeatureStates()[mojom::Feature::kBetterTogetherSuite]); + VerifyFeatureStateChange(1u /* expected_index */, + mojom::Feature::kBetterTogetherSuite, + mojom::FeatureState::kEnabledByUser); + + test_pref_service()->SetBoolean(kSuiteEnabledPrefName, false); + EXPECT_EQ( + mojom::FeatureState::kDisabledByUser, + manager()->GetFeatureStates()[mojom::Feature::kBetterTogetherSuite]); + VerifyFeatureStateChange(2u /* expected_index */, + mojom::Feature::kBetterTogetherSuite, + mojom::FeatureState::kDisabledByUser); +} + +TEST_F(MultiDeviceSetupFeatureStateManagerImplTest, InstantTethering) { + TryAllUnverifiedHostStatesAndVerifyFeatureState( + mojom::Feature::kInstantTethering); + + SetVerifiedHost(); + EXPECT_EQ(mojom::FeatureState::kNotSupportedByChromebook, + manager()->GetFeatureStates()[mojom::Feature::kInstantTethering]); + + SetSoftwareFeatureState(true /* use_local_device */, + cryptauth::SoftwareFeature::MAGIC_TETHER_CLIENT, + cryptauth::SoftwareFeatureState::kSupported); + EXPECT_EQ(mojom::FeatureState::kNotSupportedByPhone, + manager()->GetFeatureStates()[mojom::Feature::kInstantTethering]); + VerifyFeatureStateChange(1u /* expected_index */, + mojom::Feature::kInstantTethering, + mojom::FeatureState::kNotSupportedByPhone); + + SetSoftwareFeatureState(false /* use_local_device */, + cryptauth::SoftwareFeature::MAGIC_TETHER_HOST, + cryptauth::SoftwareFeatureState::kEnabled); + EXPECT_EQ(mojom::FeatureState::kEnabledByUser, + manager()->GetFeatureStates()[mojom::Feature::kInstantTethering]); + VerifyFeatureStateChange(2u /* expected_index */, + mojom::Feature::kInstantTethering, + mojom::FeatureState::kEnabledByUser); + + test_pref_service()->SetBoolean(kInstantTetheringFeatureEnabledPrefName, + false); + EXPECT_EQ(mojom::FeatureState::kDisabledByUser, + manager()->GetFeatureStates()[mojom::Feature::kInstantTethering]); + VerifyFeatureStateChange(3u /* expected_index */, + mojom::Feature::kInstantTethering, + mojom::FeatureState::kDisabledByUser); + + test_pref_service()->SetBoolean(kInstantTetheringFeatureAllowedPrefName, + false); + EXPECT_EQ(mojom::FeatureState::kDisabledByPolicy, + manager()->GetFeatureStates()[mojom::Feature::kInstantTethering]); + VerifyFeatureStateChange(4u /* expected_index */, + mojom::Feature::kInstantTethering, + mojom::FeatureState::kDisabledByPolicy); +} + +TEST_F(MultiDeviceSetupFeatureStateManagerImplTest, Messages) { + TryAllUnverifiedHostStatesAndVerifyFeatureState(mojom::Feature::kMessages); + + SetVerifiedHost(); + EXPECT_EQ(mojom::FeatureState::kNotSupportedByChromebook, + manager()->GetFeatureStates()[mojom::Feature::kMessages]); + + SetSoftwareFeatureState(true /* use_local_device */, + cryptauth::SoftwareFeature::SMS_CONNECT_CLIENT, + cryptauth::SoftwareFeatureState::kSupported); + EXPECT_EQ(mojom::FeatureState::kNotSupportedByPhone, + manager()->GetFeatureStates()[mojom::Feature::kMessages]); + VerifyFeatureStateChange(1u /* expected_index */, mojom::Feature::kMessages, + mojom::FeatureState::kNotSupportedByPhone); + + SetSoftwareFeatureState(false /* use_local_device */, + cryptauth::SoftwareFeature::SMS_CONNECT_HOST, + cryptauth::SoftwareFeatureState::kEnabled); + EXPECT_EQ(mojom::FeatureState::kEnabledByUser, + manager()->GetFeatureStates()[mojom::Feature::kMessages]); + VerifyFeatureStateChange(2u /* expected_index */, mojom::Feature::kMessages, + mojom::FeatureState::kEnabledByUser); + + test_pref_service()->SetBoolean(kAndroidMessagesFeatureEnabledPrefName, + false); + EXPECT_EQ(mojom::FeatureState::kDisabledByUser, + manager()->GetFeatureStates()[mojom::Feature::kMessages]); + VerifyFeatureStateChange(3u /* expected_index */, mojom::Feature::kMessages, + mojom::FeatureState::kDisabledByUser); +} + +TEST_F(MultiDeviceSetupFeatureStateManagerImplTest, SmartLock) { + TryAllUnverifiedHostStatesAndVerifyFeatureState(mojom::Feature::kSmartLock); + + SetVerifiedHost(); + EXPECT_EQ(mojom::FeatureState::kNotSupportedByChromebook, + manager()->GetFeatureStates()[mojom::Feature::kSmartLock]); + + SetSoftwareFeatureState(true /* use_local_device */, + cryptauth::SoftwareFeature::EASY_UNLOCK_CLIENT, + cryptauth::SoftwareFeatureState::kSupported); + EXPECT_EQ(mojom::FeatureState::kUnavailableInsufficientSecurity, + manager()->GetFeatureStates()[mojom::Feature::kSmartLock]); + VerifyFeatureStateChange( + 1u /* expected_index */, mojom::Feature::kSmartLock, + mojom::FeatureState::kUnavailableInsufficientSecurity); + + SetSoftwareFeatureState(false /* use_local_device */, + cryptauth::SoftwareFeature::EASY_UNLOCK_HOST, + cryptauth::SoftwareFeatureState::kEnabled); + EXPECT_EQ(mojom::FeatureState::kEnabledByUser, + manager()->GetFeatureStates()[mojom::Feature::kSmartLock]); + VerifyFeatureStateChange(2u /* expected_index */, mojom::Feature::kSmartLock, + mojom::FeatureState::kEnabledByUser); + + test_pref_service()->SetBoolean(kSmartLockFeatureEnabledPrefName, false); + EXPECT_EQ(mojom::FeatureState::kDisabledByUser, + manager()->GetFeatureStates()[mojom::Feature::kSmartLock]); + VerifyFeatureStateChange(3u /* expected_index */, mojom::Feature::kSmartLock, + mojom::FeatureState::kDisabledByUser); + + test_pref_service()->SetBoolean(kSmartLockFeatureAllowedPrefName, false); + EXPECT_EQ(mojom::FeatureState::kDisabledByPolicy, + manager()->GetFeatureStates()[mojom::Feature::kSmartLock]); + VerifyFeatureStateChange(4u /* expected_index */, mojom::Feature::kSmartLock, + mojom::FeatureState::kDisabledByPolicy); +} + +} // namespace multidevice_setup + +} // namespace chromeos
diff --git a/chromeos/services/multidevice_setup/multidevice_setup_impl.cc b/chromeos/services/multidevice_setup/multidevice_setup_impl.cc index 9bb2e4c..42d59f5 100644 --- a/chromeos/services/multidevice_setup/multidevice_setup_impl.cc +++ b/chromeos/services/multidevice_setup/multidevice_setup_impl.cc
@@ -10,6 +10,7 @@ #include "chromeos/components/proximity_auth/logging/logging.h" #include "chromeos/services/multidevice_setup/account_status_change_delegate_notifier_impl.h" #include "chromeos/services/multidevice_setup/eligible_host_devices_provider_impl.h" +#include "chromeos/services/multidevice_setup/feature_state_manager_impl.h" #include "chromeos/services/multidevice_setup/host_backend_delegate_impl.h" #include "chromeos/services/multidevice_setup/host_status_provider_impl.h" #include "chromeos/services/multidevice_setup/host_verifier_impl.h" @@ -71,6 +72,11 @@ host_backend_delegate_.get(), host_verifier_.get(), device_sync_client)), + feature_state_manager_( + FeatureStateManagerImpl::Factory::Get()->BuildInstance( + pref_service, + host_status_provider_.get(), + device_sync_client)), setup_flow_completion_recorder_( SetupFlowCompletionRecorderImpl::Factory::Get()->BuildInstance( pref_service, @@ -82,10 +88,12 @@ setup_flow_completion_recorder_.get(), base::DefaultClock::GetInstance())) { host_status_provider_->AddObserver(this); + feature_state_manager_->AddObserver(this); } MultiDeviceSetupImpl::~MultiDeviceSetupImpl() { host_status_provider_->RemoveObserver(this); + feature_state_manager_->RemoveObserver(this); } void MultiDeviceSetupImpl::SetAccountStatusChangeDelegate( @@ -98,6 +106,11 @@ host_status_observers_.AddPtr(std::move(observer)); } +void MultiDeviceSetupImpl::AddFeatureStateObserver( + mojom::FeatureStateObserverPtr observer) { + feature_state_observers_.AddPtr(std::move(observer)); +} + void MultiDeviceSetupImpl::GetEligibleHostDevices( GetEligibleHostDevicesCallback callback) { std::vector<cryptauth::RemoteDevice> eligible_remote_devices; @@ -149,6 +162,18 @@ device_for_callback); } +void MultiDeviceSetupImpl::SetFeatureEnabledState( + mojom::Feature feature, + bool enabled, + SetFeatureEnabledStateCallback callback) { + std::move(callback).Run( + feature_state_manager_->SetFeatureEnabledState(feature, enabled)); +} + +void MultiDeviceSetupImpl::GetFeatureStates(GetFeatureStatesCallback callback) { + std::move(callback).Run(feature_state_manager_->GetFeatureStates()); +} + void MultiDeviceSetupImpl::RetrySetHostNow(RetrySetHostNowCallback callback) { HostStatusProvider::HostStatusWithDevice host_status_with_device = host_status_provider_->GetHostWithStatus(); @@ -223,8 +248,17 @@ }); } +void MultiDeviceSetupImpl::OnFeatureStatesChange( + const FeatureStateManager::FeatureStatesMap& feature_states_map) { + feature_state_observers_.ForAllPtrs( + [&feature_states_map](mojom::FeatureStateObserver* observer) { + observer->OnFeatureStatesChanged(feature_states_map); + }); +} + void MultiDeviceSetupImpl::FlushForTesting() { host_status_observers_.FlushForTesting(); + feature_state_observers_.FlushForTesting(); } } // namespace multidevice_setup
diff --git a/chromeos/services/multidevice_setup/multidevice_setup_impl.h b/chromeos/services/multidevice_setup/multidevice_setup_impl.h index d5ab44c..6194779 100644 --- a/chromeos/services/multidevice_setup/multidevice_setup_impl.h +++ b/chromeos/services/multidevice_setup/multidevice_setup_impl.h
@@ -7,6 +7,8 @@ #include <memory> +#include "base/containers/flat_map.h" +#include "chromeos/services/multidevice_setup/feature_state_manager.h" #include "chromeos/services/multidevice_setup/host_status_provider.h" #include "chromeos/services/multidevice_setup/public/mojom/multidevice_setup.mojom.h" #include "mojo/public/cpp/bindings/binding_set.h" @@ -35,7 +37,8 @@ // Concrete MultiDeviceSetup implementation. class MultiDeviceSetupImpl : public mojom::MultiDeviceSetup, - public HostStatusProvider::Observer { + public HostStatusProvider::Observer, + public FeatureStateManager::Observer { public: class Factory { public: @@ -65,11 +68,17 @@ void SetAccountStatusChangeDelegate( mojom::AccountStatusChangeDelegatePtr delegate) override; void AddHostStatusObserver(mojom::HostStatusObserverPtr observer) override; + void AddFeatureStateObserver( + mojom::FeatureStateObserverPtr observer) override; void GetEligibleHostDevices(GetEligibleHostDevicesCallback callback) override; void SetHostDevice(const std::string& host_device_id, SetHostDeviceCallback callback) override; void RemoveHostDevice() override; void GetHostStatus(GetHostStatusCallback callback) override; + void SetFeatureEnabledState(mojom::Feature feature, + bool enabled, + SetFeatureEnabledStateCallback callback) override; + void GetFeatureStates(GetFeatureStatesCallback callback) override; void RetrySetHostNow(RetrySetHostNowCallback callback) override; void TriggerEventForDebugging( mojom::EventTypeForDebugging type, @@ -79,16 +88,22 @@ void OnHostStatusChange(const HostStatusProvider::HostStatusWithDevice& host_status_with_device) override; + // FeatureStateManager::Observer: + void OnFeatureStatesChange( + const FeatureStateManager::FeatureStatesMap& feature_states_map) override; + void FlushForTesting(); std::unique_ptr<EligibleHostDevicesProvider> eligible_host_devices_provider_; std::unique_ptr<HostBackendDelegate> host_backend_delegate_; std::unique_ptr<HostVerifier> host_verifier_; std::unique_ptr<HostStatusProvider> host_status_provider_; + std::unique_ptr<FeatureStateManager> feature_state_manager_; std::unique_ptr<SetupFlowCompletionRecorder> setup_flow_completion_recorder_; std::unique_ptr<AccountStatusChangeDelegateNotifier> delegate_notifier_; mojo::InterfacePtrSet<mojom::HostStatusObserver> host_status_observers_; + mojo::InterfacePtrSet<mojom::FeatureStateObserver> feature_state_observers_; DISALLOW_COPY_AND_ASSIGN(MultiDeviceSetupImpl); };
diff --git a/chromeos/services/multidevice_setup/multidevice_setup_impl_unittest.cc b/chromeos/services/multidevice_setup/multidevice_setup_impl_unittest.cc index a03ab740d..abd860a 100644 --- a/chromeos/services/multidevice_setup/multidevice_setup_impl_unittest.cc +++ b/chromeos/services/multidevice_setup/multidevice_setup_impl_unittest.cc
@@ -14,11 +14,14 @@ #include "chromeos/services/multidevice_setup/fake_account_status_change_delegate.h" #include "chromeos/services/multidevice_setup/fake_account_status_change_delegate_notifier.h" #include "chromeos/services/multidevice_setup/fake_eligible_host_devices_provider.h" +#include "chromeos/services/multidevice_setup/fake_feature_state_manager.h" +#include "chromeos/services/multidevice_setup/fake_feature_state_observer.h" #include "chromeos/services/multidevice_setup/fake_host_backend_delegate.h" #include "chromeos/services/multidevice_setup/fake_host_status_observer.h" #include "chromeos/services/multidevice_setup/fake_host_status_provider.h" #include "chromeos/services/multidevice_setup/fake_host_verifier.h" #include "chromeos/services/multidevice_setup/fake_setup_flow_completion_recorder.h" +#include "chromeos/services/multidevice_setup/feature_state_manager_impl.h" #include "chromeos/services/multidevice_setup/host_backend_delegate_impl.h" #include "chromeos/services/multidevice_setup/host_status_provider_impl.h" #include "chromeos/services/multidevice_setup/host_verifier_impl.h" @@ -223,6 +226,47 @@ DISALLOW_COPY_AND_ASSIGN(FakeHostStatusProviderFactory); }; +class FakeFeatureStateManagerFactory : public FeatureStateManagerImpl::Factory { + public: + FakeFeatureStateManagerFactory( + sync_preferences::TestingPrefServiceSyncable* + expected_testing_pref_service, + FakeHostStatusProviderFactory* fake_host_status_provider_factory, + device_sync::FakeDeviceSyncClient* expected_device_sync_client) + : expected_testing_pref_service_(expected_testing_pref_service), + fake_host_status_provider_factory_(fake_host_status_provider_factory), + expected_device_sync_client_(expected_device_sync_client) {} + + ~FakeFeatureStateManagerFactory() override = default; + + FakeFeatureStateManager* instance() { return instance_; } + + private: + // FeatureStateManagerImpl::Factory: + std::unique_ptr<FeatureStateManager> BuildInstance( + PrefService* pref_service, + HostStatusProvider* host_status_provider, + device_sync::DeviceSyncClient* device_sync_client) override { + EXPECT_FALSE(instance_); + EXPECT_EQ(expected_testing_pref_service_, pref_service); + EXPECT_EQ(fake_host_status_provider_factory_->instance(), + host_status_provider); + EXPECT_EQ(expected_device_sync_client_, device_sync_client); + + auto instance = std::make_unique<FakeFeatureStateManager>(); + instance_ = instance.get(); + return instance; + } + + sync_preferences::TestingPrefServiceSyncable* expected_testing_pref_service_; + FakeHostStatusProviderFactory* fake_host_status_provider_factory_; + device_sync::FakeDeviceSyncClient* expected_device_sync_client_; + + FakeFeatureStateManager* instance_ = nullptr; + + DISALLOW_COPY_AND_ASSIGN(FakeFeatureStateManagerFactory); +}; + class FakeSetupFlowCompletionRecorderFactory : public SetupFlowCompletionRecorderImpl::Factory { public: @@ -345,6 +389,13 @@ HostStatusProviderImpl::Factory::SetFactoryForTesting( fake_host_status_provider_factory_.get()); + fake_feature_state_manager_factory_ = + std::make_unique<FakeFeatureStateManagerFactory>( + test_pref_service_.get(), fake_host_status_provider_factory_.get(), + fake_device_sync_client_.get()); + FeatureStateManagerImpl::Factory::SetFactoryForTesting( + fake_feature_state_manager_factory_.get()); + fake_setup_flow_completion_recorder_factory_ = std::make_unique<FakeSetupFlowCompletionRecorderFactory>( test_pref_service_.get()); @@ -368,6 +419,7 @@ HostBackendDelegateImpl::Factory::SetFactoryForTesting(nullptr); HostVerifierImpl::Factory::SetFactoryForTesting(nullptr); HostStatusProviderImpl::Factory::SetFactoryForTesting(nullptr); + FeatureStateManagerImpl::Factory::SetFactoryForTesting(nullptr); SetupFlowCompletionRecorderImpl::Factory::SetFactoryForTesting(nullptr); AccountStatusChangeDelegateNotifierImpl::Factory::SetFactoryForTesting( nullptr); @@ -428,6 +480,34 @@ return host_status_update; } + bool CallSetFeatureEnabledState(mojom::Feature feature, bool enabled) { + base::RunLoop run_loop; + multidevice_setup_->SetFeatureEnabledState( + feature, enabled, + base::BindOnce(&MultiDeviceSetupImplTest::OnSetFeatureEnabled, + base::Unretained(this), run_loop.QuitClosure())); + run_loop.Run(); + + bool success = *last_set_host_success_; + last_set_host_success_.reset(); + + return success; + } + + base::flat_map<mojom::Feature, mojom::FeatureState> CallGetFeatureStates() { + base::RunLoop run_loop; + multidevice_setup_->GetFeatureStates( + base::BindOnce(&MultiDeviceSetupImplTest::OnGetFeatureStates, + base::Unretained(this), run_loop.QuitClosure())); + run_loop.Run(); + + base::flat_map<mojom::Feature, mojom::FeatureState> feature_states_map = + *last_get_feature_states_result_; + last_get_feature_states_result_.reset(); + + return feature_states_map; + } + bool CallRetrySetHostNow() { base::RunLoop run_loop; multidevice_setup_->RetrySetHostNow( @@ -503,6 +583,10 @@ return fake_host_status_provider_factory_->instance(); } + FakeFeatureStateManager* fake_feature_state_manager() { + return fake_feature_state_manager_factory_->instance(); + } + FakeSetupFlowCompletionRecorder* fake_setup_flow_completion_recorder() { return fake_setup_flow_completion_recorder_factory_->instance(); } @@ -542,6 +626,21 @@ std::move(quit_closure).Run(); } + void OnSetFeatureEnabled(base::OnceClosure quit_closure, bool success) { + EXPECT_FALSE(last_set_host_success_); + last_set_host_success_ = success; + std::move(quit_closure).Run(); + } + + void OnGetFeatureStates( + base::OnceClosure quit_closure, + const base::flat_map<mojom::Feature, mojom::FeatureState>& + feature_states_map) { + EXPECT_FALSE(last_get_feature_states_result_); + last_get_feature_states_result_ = feature_states_map; + std::move(quit_closure).Run(); + } + void OnHostRetried(base::OnceClosure quit_closure, bool success) { EXPECT_FALSE(last_retry_success_); last_retry_success_ = success; @@ -571,6 +670,8 @@ std::unique_ptr<FakeHostVerifierFactory> fake_host_verifier_factory_; std::unique_ptr<FakeHostStatusProviderFactory> fake_host_status_provider_factory_; + std::unique_ptr<FakeFeatureStateManagerFactory> + fake_feature_state_manager_factory_; std::unique_ptr<FakeSetupFlowCompletionRecorderFactory> fake_setup_flow_completion_recorder_factory_; std::unique_ptr<FakeAccountStatusChangeDelegateNotifierFactory> @@ -585,6 +686,9 @@ base::Optional< std::pair<mojom::HostStatus, base::Optional<cryptauth::RemoteDevice>>> last_host_status_; + base::Optional<bool> last_set_feature_enabled_state_success_; + base::Optional<base::flat_map<mojom::Feature, mojom::FeatureState>> + last_get_feature_states_result_; base::Optional<bool> last_retry_success_; std::unique_ptr<mojom::MultiDeviceSetup> multidevice_setup_; @@ -621,6 +725,38 @@ ->num_existing_user_chromebook_added_events_handled()); } +TEST_F(MultiDeviceSetupImplTest, FeatureStateChanges) { + auto observer = std::make_unique<FakeFeatureStateObserver>(); + multidevice_setup()->AddFeatureStateObserver( + observer->GenerateInterfacePtr()); + + EXPECT_EQ(mojom::FeatureState::kUnavailableNoVerifiedHost, + CallGetFeatureStates()[mojom::Feature::kBetterTogetherSuite]); + + fake_feature_state_manager()->SetFeatureState( + mojom::Feature::kBetterTogetherSuite, + mojom::FeatureState::kNotSupportedByChromebook); + SendPendingObserverMessages(); + EXPECT_EQ(mojom::FeatureState::kNotSupportedByChromebook, + CallGetFeatureStates()[mojom::Feature::kBetterTogetherSuite]); + EXPECT_EQ(1u, observer->feature_state_updates().size()); + + fake_feature_state_manager()->SetFeatureState( + mojom::Feature::kBetterTogetherSuite, + mojom::FeatureState::kEnabledByUser); + SendPendingObserverMessages(); + EXPECT_EQ(mojom::FeatureState::kEnabledByUser, + CallGetFeatureStates()[mojom::Feature::kBetterTogetherSuite]); + EXPECT_EQ(2u, observer->feature_state_updates().size()); + + EXPECT_TRUE(CallSetFeatureEnabledState(mojom::Feature::kBetterTogetherSuite, + false /* enabled */)); + SendPendingObserverMessages(); + EXPECT_EQ(mojom::FeatureState::kDisabledByUser, + CallGetFeatureStates()[mojom::Feature::kBetterTogetherSuite]); + EXPECT_EQ(3u, observer->feature_state_updates().size()); +} + TEST_F(MultiDeviceSetupImplTest, ComprehensiveHostTest) { // Start with no eligible devices. EXPECT_TRUE(CallGetEligibleHostDevices().empty());
diff --git a/chromeos/services/multidevice_setup/multidevice_setup_initializer.cc b/chromeos/services/multidevice_setup/multidevice_setup_initializer.cc index 77892e43..308e7777 100644 --- a/chromeos/services/multidevice_setup/multidevice_setup_initializer.cc +++ b/chromeos/services/multidevice_setup/multidevice_setup_initializer.cc
@@ -80,7 +80,17 @@ return; } - pending_observers_.push_back(std::move(observer)); + pending_host_status_observers_.push_back(std::move(observer)); +} + +void MultiDeviceSetupInitializer::AddFeatureStateObserver( + mojom::FeatureStateObserverPtr observer) { + if (multidevice_setup_impl_) { + multidevice_setup_impl_->AddFeatureStateObserver(std::move(observer)); + return; + } + + pending_feature_state_observers_.push_back(std::move(observer)); } void MultiDeviceSetupInitializer::GetEligibleHostDevices( @@ -139,6 +149,30 @@ pending_get_host_args_.push_back(std::move(callback)); } +void MultiDeviceSetupInitializer::SetFeatureEnabledState( + mojom::Feature feature, + bool enabled, + SetFeatureEnabledStateCallback callback) { + if (multidevice_setup_impl_) { + multidevice_setup_impl_->SetFeatureEnabledState(feature, enabled, + std::move(callback)); + return; + } + + pending_set_feature_enabled_args_.emplace_back(feature, enabled, + std::move(callback)); +} + +void MultiDeviceSetupInitializer::GetFeatureStates( + GetFeatureStatesCallback callback) { + if (multidevice_setup_impl_) { + multidevice_setup_impl_->GetFeatureStates(std::move(callback)); + return; + } + + pending_get_feature_states_args_.emplace_back(std::move(callback)); +} + void MultiDeviceSetupInitializer::RetrySetHostNow( RetrySetHostNowCallback callback) { if (multidevice_setup_impl_) { @@ -178,9 +212,13 @@ std::move(pending_delegate_)); } - for (auto& observer : pending_observers_) + for (auto& observer : pending_host_status_observers_) multidevice_setup_impl_->AddHostStatusObserver(std::move(observer)); - pending_observers_.clear(); + pending_host_status_observers_.clear(); + + for (auto& observer : pending_feature_state_observers_) + multidevice_setup_impl_->AddFeatureStateObserver(std::move(observer)); + pending_feature_state_observers_.clear(); if (pending_set_host_args_) { DCHECK(!pending_should_remove_host_device_); @@ -194,6 +232,20 @@ multidevice_setup_impl_->RemoveHostDevice(); pending_should_remove_host_device_ = false; + for (auto& set_feature_enabled_args : pending_set_feature_enabled_args_) { + multidevice_setup_impl_->SetFeatureEnabledState( + std::get<0>(set_feature_enabled_args), + std::get<1>(set_feature_enabled_args), + std::move(std::get<2>(set_feature_enabled_args))); + } + pending_set_feature_enabled_args_.clear(); + + for (auto& get_feature_states_callback : pending_get_feature_states_args_) { + multidevice_setup_impl_->GetFeatureStates( + std::move(get_feature_states_callback)); + } + pending_get_feature_states_args_.clear(); + for (auto& retry_callback : pending_retry_set_host_args_) multidevice_setup_impl_->RetrySetHostNow(std::move(retry_callback)); pending_retry_set_host_args_.clear();
diff --git a/chromeos/services/multidevice_setup/multidevice_setup_initializer.h b/chromeos/services/multidevice_setup/multidevice_setup_initializer.h index 51533d75..ad44cea7 100644 --- a/chromeos/services/multidevice_setup/multidevice_setup_initializer.h +++ b/chromeos/services/multidevice_setup/multidevice_setup_initializer.h
@@ -5,6 +5,8 @@ #ifndef CHROMEOS_SERVICES_MULTIDEVICE_SETUP_MULTIDEVICE_SETUP_INITIALIZER_H_ #define CHROMEOS_SERVICES_MULTIDEVICE_SETUP_MULTIDEVICE_SETUP_INITIALIZER_H_ +#include <tuple> +#include <utility> #include <vector> #include "chromeos/services/device_sync/public/cpp/device_sync_client.h" @@ -55,11 +57,17 @@ void SetAccountStatusChangeDelegate( mojom::AccountStatusChangeDelegatePtr delegate) override; void AddHostStatusObserver(mojom::HostStatusObserverPtr observer) override; + void AddFeatureStateObserver( + mojom::FeatureStateObserverPtr observer) override; void GetEligibleHostDevices(GetEligibleHostDevicesCallback callback) override; void SetHostDevice(const std::string& host_device_id, SetHostDeviceCallback callback) override; void RemoveHostDevice() override; void GetHostStatus(GetHostStatusCallback callback) override; + void SetFeatureEnabledState(mojom::Feature feature, + bool enabled, + SetFeatureEnabledStateCallback callback) override; + void GetFeatureStates(GetFeatureStatesCallback callback) override; void RetrySetHostNow(RetrySetHostNowCallback callback) override; void TriggerEventForDebugging( mojom::EventTypeForDebugging type, @@ -80,9 +88,13 @@ // parameters are cached here. Once asynchronous initialization is complete, // the parameters are passed to |multidevice_setup_impl_|. mojom::AccountStatusChangeDelegatePtr pending_delegate_; - std::vector<mojom::HostStatusObserverPtr> pending_observers_; + std::vector<mojom::HostStatusObserverPtr> pending_host_status_observers_; + std::vector<mojom::FeatureStateObserverPtr> pending_feature_state_observers_; std::vector<GetEligibleHostDevicesCallback> pending_get_eligible_hosts_args_; std::vector<GetHostStatusCallback> pending_get_host_args_; + std::vector<std::tuple<mojom::Feature, bool, SetFeatureEnabledStateCallback>> + pending_set_feature_enabled_args_; + std::vector<GetFeatureStatesCallback> pending_get_feature_states_args_; std::vector<RetrySetHostNowCallback> pending_retry_set_host_args_; // Special case: for SetHostDevice() and RemoveHostDevice(), only keep track
diff --git a/chromeos/services/multidevice_setup/multidevice_setup_service_unittest.cc b/chromeos/services/multidevice_setup/multidevice_setup_service_unittest.cc index 8a54f39..ca55e78 100644 --- a/chromeos/services/multidevice_setup/multidevice_setup_service_unittest.cc +++ b/chromeos/services/multidevice_setup/multidevice_setup_service_unittest.cc
@@ -195,6 +195,16 @@ multidevice_setup_ptr()->GetHostStatus(base::DoNothing()); multidevice_setup_ptr().FlushForTesting(); + // SetFeatureEnabledState(). + multidevice_setup_ptr()->SetFeatureEnabledState( + mojom::Feature::kBetterTogetherSuite, true /* enabled */, + base::DoNothing()); + multidevice_setup_ptr().FlushForTesting(); + + // GetFeatureStates(). + multidevice_setup_ptr()->GetFeatureStates(base::DoNothing()); + multidevice_setup_ptr().FlushForTesting(); + // RetrySetHostNow(). multidevice_setup_ptr()->RetrySetHostNow(base::DoNothing()); multidevice_setup_ptr().FlushForTesting(); @@ -206,9 +216,11 @@ // Finish initialization; all of the pending calls should have been forwarded. FinishInitialization(); EXPECT_TRUE(fake_multidevice_setup()->delegate()); - EXPECT_EQ(1u, fake_multidevice_setup()->observers().size()); + EXPECT_EQ(1u, fake_multidevice_setup()->host_status_observers().size()); EXPECT_EQ(1u, fake_multidevice_setup()->get_eligible_hosts_args().size()); EXPECT_EQ(1u, fake_multidevice_setup()->get_host_args().size()); + EXPECT_EQ(1u, fake_multidevice_setup()->set_feature_enabled_args().size()); + EXPECT_EQ(1u, fake_multidevice_setup()->get_feature_states_args().size()); EXPECT_EQ(1u, fake_multidevice_setup()->retry_set_host_now_args().size()); } @@ -267,7 +279,7 @@ multidevice_setup_ptr()->AddHostStatusObserver( fake_host_status_observer->GenerateInterfacePtr()); multidevice_setup_ptr().FlushForTesting(); - EXPECT_EQ(1u, fake_multidevice_setup()->observers().size()); + EXPECT_EQ(1u, fake_multidevice_setup()->host_status_observers().size()); // GetEligibleHostDevices(). multidevice_setup_ptr()->GetEligibleHostDevices(base::DoNothing()); @@ -289,6 +301,18 @@ multidevice_setup_ptr().FlushForTesting(); EXPECT_EQ(1u, fake_multidevice_setup()->get_host_args().size()); + // SetFeatureEnabledState(). + multidevice_setup_ptr()->SetFeatureEnabledState( + mojom::Feature::kBetterTogetherSuite, true /* enabled */, + base::DoNothing()); + multidevice_setup_ptr().FlushForTesting(); + EXPECT_EQ(1u, fake_multidevice_setup()->set_feature_enabled_args().size()); + + // GetFeatureStates(). + multidevice_setup_ptr()->GetFeatureStates(base::DoNothing()); + multidevice_setup_ptr().FlushForTesting(); + EXPECT_EQ(1u, fake_multidevice_setup()->get_feature_states_args().size()); + // RetrySetHostNow(). multidevice_setup_ptr()->RetrySetHostNow(base::DoNothing()); multidevice_setup_ptr().FlushForTesting();
diff --git a/chromeos/services/multidevice_setup/public/cpp/fake_multidevice_setup.cc b/chromeos/services/multidevice_setup/public/cpp/fake_multidevice_setup.cc index fce02d2..323df4e 100644 --- a/chromeos/services/multidevice_setup/public/cpp/fake_multidevice_setup.cc +++ b/chromeos/services/multidevice_setup/public/cpp/fake_multidevice_setup.cc
@@ -4,6 +4,7 @@ #include "chromeos/services/multidevice_setup/public/cpp/fake_multidevice_setup.h" +#include "base/containers/flat_map.h" #include "components/cryptauth/remote_device.h" namespace chromeos { @@ -33,6 +34,18 @@ } } + for (auto& set_feature_enabled_args : set_feature_enabled_args_) { + if (std::get<2>(set_feature_enabled_args)) + std::move(std::get<2>(set_feature_enabled_args)).Run(false /* success */); + } + + for (auto& get_feature_states_arg : get_feature_states_args_) { + if (get_feature_states_arg) { + std::move(get_feature_states_arg) + .Run(base::flat_map<mojom::Feature, mojom::FeatureState>()); + } + } + for (auto& retry_set_host_now_arg : retry_set_host_now_args_) { if (retry_set_host_now_arg) std::move(retry_set_host_now_arg).Run(false /* success */); @@ -56,7 +69,12 @@ void FakeMultiDeviceSetup::AddHostStatusObserver( mojom::HostStatusObserverPtr observer) { - observers_.push_back(std::move(observer)); + host_status_observers_.push_back(std::move(observer)); +} + +void FakeMultiDeviceSetup::AddFeatureStateObserver( + mojom::FeatureStateObserverPtr observer) { + feature_state_observers_.push_back(std::move(observer)); } void FakeMultiDeviceSetup::GetEligibleHostDevices( @@ -77,6 +95,17 @@ get_host_args_.push_back(std::move(callback)); } +void FakeMultiDeviceSetup::SetFeatureEnabledState( + mojom::Feature feature, + bool enabled, + SetFeatureEnabledStateCallback callback) { + set_feature_enabled_args_.emplace_back(feature, enabled, std::move(callback)); +} + +void FakeMultiDeviceSetup::GetFeatureStates(GetFeatureStatesCallback callback) { + get_feature_states_args_.emplace_back(std::move(callback)); +} + void FakeMultiDeviceSetup::RetrySetHostNow(RetrySetHostNowCallback callback) { retry_set_host_now_args_.push_back(std::move(callback)); }
diff --git a/chromeos/services/multidevice_setup/public/cpp/fake_multidevice_setup.h b/chromeos/services/multidevice_setup/public/cpp/fake_multidevice_setup.h index 8bd486b..eb5401e 100644 --- a/chromeos/services/multidevice_setup/public/cpp/fake_multidevice_setup.h +++ b/chromeos/services/multidevice_setup/public/cpp/fake_multidevice_setup.h
@@ -5,6 +5,7 @@ #ifndef CHROMEOS_SERVICES_MULTIDEVICE_SETUP_PUBLIC_CPP_FAKE_MULTIDEVICE_SETUP_H_ #define CHROMEOS_SERVICES_MULTIDEVICE_SETUP_PUBLIC_CPP_FAKE_MULTIDEVICE_SETUP_H_ +#include <tuple> #include <utility> #include <vector> @@ -26,7 +27,13 @@ mojom::AccountStatusChangeDelegatePtr& delegate() { return delegate_; } - std::vector<mojom::HostStatusObserverPtr>& observers() { return observers_; } + std::vector<mojom::HostStatusObserverPtr>& host_status_observers() { + return host_status_observers_; + } + + std::vector<mojom::FeatureStateObserverPtr>& feature_state_observers() { + return feature_state_observers_; + } std::vector<GetEligibleHostDevicesCallback>& get_eligible_hosts_args() { return get_eligible_hosts_args_; @@ -40,6 +47,15 @@ std::vector<GetHostStatusCallback>& get_host_args() { return get_host_args_; } + std::vector<std::tuple<mojom::Feature, bool, SetFeatureEnabledStateCallback>>& + set_feature_enabled_args() { + return set_feature_enabled_args_; + } + + std::vector<GetFeatureStatesCallback>& get_feature_states_args() { + return get_feature_states_args_; + } + std::vector<RetrySetHostNowCallback>& retry_set_host_now_args() { return retry_set_host_now_args_; } @@ -55,22 +71,32 @@ void SetAccountStatusChangeDelegate( mojom::AccountStatusChangeDelegatePtr delegate) override; void AddHostStatusObserver(mojom::HostStatusObserverPtr observer) override; + void AddFeatureStateObserver( + mojom::FeatureStateObserverPtr observer) override; void GetEligibleHostDevices(GetEligibleHostDevicesCallback callback) override; void SetHostDevice(const std::string& host_device_id, SetHostDeviceCallback callback) override; void RemoveHostDevice() override; void GetHostStatus(GetHostStatusCallback callback) override; + void SetFeatureEnabledState(mojom::Feature feature, + bool enabled, + SetFeatureEnabledStateCallback callback) override; + void GetFeatureStates(GetFeatureStatesCallback callback) override; void RetrySetHostNow(RetrySetHostNowCallback callback) override; void TriggerEventForDebugging( mojom::EventTypeForDebugging type, TriggerEventForDebuggingCallback callback) override; mojom::AccountStatusChangeDelegatePtr delegate_; - std::vector<mojom::HostStatusObserverPtr> observers_; + std::vector<mojom::HostStatusObserverPtr> host_status_observers_; + std::vector<mojom::FeatureStateObserverPtr> feature_state_observers_; std::vector<GetEligibleHostDevicesCallback> get_eligible_hosts_args_; std::vector<std::pair<std::string, SetHostDeviceCallback>> set_host_args_; size_t num_remove_host_calls_ = 0u; std::vector<GetHostStatusCallback> get_host_args_; + std::vector<std::tuple<mojom::Feature, bool, SetFeatureEnabledStateCallback>> + set_feature_enabled_args_; + std::vector<GetFeatureStatesCallback> get_feature_states_args_; std::vector<RetrySetHostNowCallback> retry_set_host_now_args_; std::vector< std::pair<mojom::EventTypeForDebugging, TriggerEventForDebuggingCallback>>
diff --git a/chromeos/services/multidevice_setup/public/mojom/multidevice_setup.mojom b/chromeos/services/multidevice_setup/public/mojom/multidevice_setup.mojom index 2754636..5bac9123 100644 --- a/chromeos/services/multidevice_setup/public/mojom/multidevice_setup.mojom +++ b/chromeos/services/multidevice_setup/public/mojom/multidevice_setup.mojom
@@ -42,6 +42,41 @@ kHostVerified }; +// Individual multi-device features types. +enum Feature { + kBetterTogetherSuite, + kInstantTethering, + kMessages, + kSmartLock +}; + +enum FeatureState { + // Feature was disabled by a device policy (e.g., EDU or Enterprise). + kDisabledByPolicy, + + // Feature was disabled by the user (i.e., via settings). + kDisabledByUser, + + // Feature was enabled by the user (i.e., via settings). + kEnabledByUser, + + // Feature is not supported by this Chromebook. + kNotSupportedByChromebook, + + // Feature is not supported by the current host phone device. + kNotSupportedByPhone, + + // The feature is unavailable because there is no verified multi-device host. + // To set a host, use SetHostDevice(); to verify a host, use + // RetrySetHostNow(). + kUnavailableNoVerifiedHost, + + // The feature is unavailable because there are insufficient security + // mechanisms in place (e.g., Smart Lock returns this value when the host + // phone device does not have a lock screen set). + kUnavailableInsufficientSecurity +}; + interface AccountStatusChangeDelegate { // Callback which indicates that one or more MultiDevice host phones are // available for setup with the MultiDevice setup flow. This function is only @@ -68,6 +103,11 @@ chromeos.device_sync.mojom.RemoteDevice? host_device); }; +interface FeatureStateObserver { + // Invoked when one or more features have changed state. + OnFeatureStatesChanged(map<Feature, FeatureState> feature_states_map); +}; + // Provides an API to the MultiDevice Setup flow. Designed to be exposed // primarily to the MultiDevice setup flow at chrome://multidevice-setup (normal // usage) as well as the ProximityAuth debug WebUI page at @@ -82,6 +122,10 @@ // HostStatusObserverPtr passed here. AddHostStatusObserver(HostStatusObserver observer); + // Adds an observer of feature state changes. To stop observing, disconnect + // the FeatureStateObserverPtr passed here. + AddFeatureStateObserver(FeatureStateObserver observer); + // Provides a list of all eligible host devices (i.e., those which can be // passed to SetHostDevice()). GetEligibleHostDevices() => @@ -107,6 +151,14 @@ GetHostStatus() => (HostStatus host_status, chromeos.device_sync.mojom.RemoteDevice? host_device); + // Attempts to enable or disable |feature|. This function succeeds only if + // |feature|'s current state is FeatureState::kEnabledByUser or + // FeatureState::kDisabledByUser. + SetFeatureEnabledState(Feature feature, bool enabled) => (bool success); + + // Provides the states of all Features. + GetFeatureStates() => (map<Feature, FeatureState> feature_states_map); + // Retries the most recent SetHostDevice() call. // // If the current status is
diff --git a/components/autofill/core/browser/contact_info.cc b/components/autofill/core/browser/contact_info.cc index 105d135c..c5e1156 100644 --- a/components/autofill/core/browser/contact_info.cc +++ b/components/autofill/core/browser/contact_info.cc
@@ -14,6 +14,7 @@ #include "base/strings/utf_string_conversions.h" #include "components/autofill/core/browser/autofill_data_util.h" #include "components/autofill/core/browser/autofill_type.h" +#include "components/autofill/core/common/autofill_features.h" #include "components/autofill/core/common/autofill_l10n_util.h" namespace autofill { @@ -240,7 +241,8 @@ } base::string16 CompanyInfo::GetRawInfo(ServerFieldType type) const { - if (type == COMPANY_NAME) + if (type == COMPANY_NAME && + base::FeatureList::IsEnabled(features::kAutofillEnableCompanyName)) return company_name_; return base::string16();
diff --git a/components/autofill/core/common/autofill_features.cc b/components/autofill/core/common/autofill_features.cc index 49d65b1..ba48e6f 100644 --- a/components/autofill/core/common/autofill_features.cc +++ b/components/autofill/core/common/autofill_features.cc
@@ -152,5 +152,8 @@ const base::Feature kSingleClickAutofill{"SingleClickAutofill", base::FEATURE_ENABLED_BY_DEFAULT}; +const base::Feature kAutofillEnableCompanyName{ + "AutofillEnableCompanyName", base::FEATURE_ENABLED_BY_DEFAULT}; + } // namespace features } // namespace autofill
diff --git a/components/autofill/core/common/autofill_features.h b/components/autofill/core/common/autofill_features.h index 9c7458c2..01a1a94 100644 --- a/components/autofill/core/common/autofill_features.h +++ b/components/autofill/core/common/autofill_features.h
@@ -16,6 +16,7 @@ extern const base::Feature kAutofillDownstreamUseGooglePayBrandingOniOS; extern const base::Feature kAutofillDynamicForms; extern const base::Feature kAutofillEnableAccountWalletStorage; +extern const base::Feature kAutofillEnableCompanyName; extern const base::Feature kAutofillEnablePaymentsInteractionsOnAuthError; extern const base::Feature kAutofillEnforceMinRequiredFieldsForHeuristics; extern const base::Feature kAutofillEnforceMinRequiredFieldsForQuery;
diff --git a/components/captive_portal/captive_portal_detector.cc b/components/captive_portal/captive_portal_detector.cc index f06d2fe..cf142c1 100644 --- a/components/captive_portal/captive_portal_detector.cc +++ b/components/captive_portal/captive_portal_detector.cc
@@ -38,7 +38,7 @@ auto resource_request = std::make_unique<network::ResourceRequest>(); resource_request->url = url; - // Can't safely use net::LOAD_DISABLE_CERT_REVOCATION_CHECKING here, + // Can't safely use net::LOAD_DISABLE_CERT_NETWORK_FETCHES here, // since then the connection may be reused without checking the cert. resource_request->load_flags = net::LOAD_BYPASS_CACHE | net::LOAD_DO_NOT_SAVE_COOKIES |
diff --git a/components/cast_channel/cast_socket.cc b/components/cast_channel/cast_socket.cc index a7b3206..8aaff00 100644 --- a/components/cast_channel/cast_socket.cc +++ b/components/cast_channel/cast_socket.cc
@@ -85,6 +85,7 @@ verify_result->verified_cert = params.certificate(); return net::OK; } + void SetConfig(const Config& config) override {} }; } // namespace
diff --git a/components/cast_channel/cast_socket_unittest.cc b/components/cast_channel/cast_socket_unittest.cc index 4a6c47a6..3d5ad6f1 100644 --- a/components/cast_channel/cast_socket_unittest.cc +++ b/components/cast_channel/cast_socket_unittest.cc
@@ -1026,7 +1026,7 @@ // Sends message data through an actual non-mocked CastTransport object and // non-mocked SSLClientSocket, testing the components in integration. -TEST_F(SslCastSocketTest, TestMessageEndToEndWithRealSSL) { +TEST_F(SslCastSocketTest, DISABLED_TestMessageEndToEndWithRealSSL) { CreateSockets(); ConnectSockets();
diff --git a/components/cronet/ios/Cronet.mm b/components/cronet/ios/Cronet.mm index 6f061d1..28b05fb 100644 --- a/components/cronet/ios/Cronet.mm +++ b/components/cronet/ios/Cronet.mm
@@ -86,6 +86,7 @@ verify_result->cert_status = net::MapNetErrorToCertStatus(result); return result; } + void SetConfig(const Config& config) override {} }; // net::HTTPProtocolHandlerDelegate for Cronet.
diff --git a/components/cronet/stale_host_resolver.cc b/components/cronet/stale_host_resolver.cc index dff2672..0e55309 100644 --- a/components/cronet/stale_host_resolver.cc +++ b/components/cronet/stale_host_resolver.cc
@@ -382,8 +382,10 @@ StaleHostResolver::~StaleHostResolver() {} std::unique_ptr<net::HostResolver::ResolveHostRequest> -StaleHostResolver::CreateRequest(const net::HostPortPair& host, - const net::NetLogWithSource& net_log) { +StaleHostResolver::CreateRequest( + const net::HostPortPair& host, + const net::NetLogWithSource& net_log, + const base::Optional<ResolveHostParameters>& optional_parameters) { // TODO(crbug.com/821021): Implement. NOTIMPLEMENTED(); return nullptr;
diff --git a/components/cronet/stale_host_resolver.h b/components/cronet/stale_host_resolver.h index 23619844..a49a8c4 100644 --- a/components/cronet/stale_host_resolver.h +++ b/components/cronet/stale_host_resolver.h
@@ -64,7 +64,9 @@ std::unique_ptr<ResolveHostRequest> CreateRequest( const net::HostPortPair& host, - const net::NetLogWithSource& net_log) override; + const net::NetLogWithSource& net_log, + const base::Optional<ResolveHostParameters>& optional_parameters) + override; // Resolves as a regular HostResolver, but if stale data is available and // usable (according to the options passed to the constructor), and fresh data
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_service_client.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_service_client.cc index b62bcafc..97cc1037bb 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_service_client.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_service_client.cc
@@ -48,6 +48,7 @@ #include "net/traffic_annotation/network_traffic_annotation.h" #include "net/url_request/url_fetcher.h" #include "net/url_request/url_request_status.h" +#include "services/network/public/cpp/features.h" #if defined(OS_ANDROID) #include "net/android/network_library.h" @@ -221,7 +222,11 @@ void DataReductionProxyConfigServiceClient::InitializeOnIOThread( net::URLRequestContextGetter* url_request_context_getter) { - DCHECK(url_request_context_getter); + // TODO(crbug.com/721403): DRP is disabled with network service enabled. When + // DRP is switched to mojo, we won't need URLRequestContext. + if (!base::FeatureList::IsEnabled(network::features::kNetworkService)) { + DCHECK(url_request_context_getter); + } #if defined(OS_ANDROID) // It is okay to use Unretained here because |app_status_listener| would be // destroyed before |this|.
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.cc index e89881ec..29b7657 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.cc
@@ -38,6 +38,7 @@ #include "net/url_request/url_request_context.h" #include "net/url_request/url_request_context_builder.h" #include "net/url_request/url_request_context_getter.h" +#include "services/network/public/cpp/features.h" namespace data_reduction_proxy { @@ -297,7 +298,12 @@ // Bug http://crbug/488190. void DataReductionProxyIOData::SetProxyPrefs(bool enabled, bool at_startup) { DCHECK(io_task_runner_->BelongsToCurrentThread()); - DCHECK(url_request_context_getter_->GetURLRequestContext()->proxy_resolution_service()); + // TODO(crbug.com/721403): DRP is disabled with network service enabled. When + // DRP is switched to mojo, we won't need URLRequestContext. + if (!base::FeatureList::IsEnabled(network::features::kNetworkService)) { + DCHECK(url_request_context_getter_->GetURLRequestContext() + ->proxy_resolution_service()); + } enabled_ = enabled; config_->SetProxyConfig(enabled, at_startup); if (config_client_) { @@ -308,9 +314,14 @@ // If Data Saver is disabled, reset data reduction proxy state. if (!enabled) { - net::ProxyResolutionService* proxy_resolution_service = - url_request_context_getter_->GetURLRequestContext()->proxy_resolution_service(); - proxy_resolution_service->ClearBadProxiesCache(); + // TODO(crbug.com/721403): Make DRP work with network service. + if (!base::FeatureList::IsEnabled(network::features::kNetworkService)) { + net::ProxyResolutionService* proxy_resolution_service = + url_request_context_getter_->GetURLRequestContext() + ->proxy_resolution_service(); + proxy_resolution_service->ClearBadProxiesCache(); + } + bypass_stats_->ClearRequestCounts(); bypass_stats_->NotifyUnavailabilityIfChanged(); }
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.cc index 96f4e58..c4272b8 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.cc
@@ -23,6 +23,7 @@ #include "components/prefs/pref_member.h" #include "components/prefs/pref_service.h" #include "net/base/network_change_notifier.h" +#include "services/network/public/cpp/features.h" namespace { @@ -114,6 +115,10 @@ } bool DataReductionProxySettings::IsDataReductionProxyEnabled() const { + // TODO(crbug.com/721403): Make DRP work with network service. + if (base::FeatureList::IsEnabled(network::features::kNetworkService)) + return false; + if (spdy_proxy_auth_enabled_.GetPrefName().empty()) return false; return spdy_proxy_auth_enabled_.GetValue() ||
diff --git a/components/data_reduction_proxy/core/browser/warmup_url_fetcher.cc b/components/data_reduction_proxy/core/browser/warmup_url_fetcher.cc index cadf7c0..79ecf34 100644 --- a/components/data_reduction_proxy/core/browser/warmup_url_fetcher.cc +++ b/components/data_reduction_proxy/core/browser/warmup_url_fetcher.cc
@@ -21,6 +21,7 @@ #include "net/url_request/url_request_context.h" #include "net/url_request/url_request_context_getter.h" #include "net/url_request/url_request_status.h" +#include "services/network/public/cpp/features.h" namespace data_reduction_proxy { @@ -34,7 +35,11 @@ url_request_context_getter_(url_request_context_getter), callback_(callback), get_http_rtt_callback_(get_http_rtt_callback) { - DCHECK(url_request_context_getter_); + // TODO(crbug.com/721403): DRP is disabled with network service enabled. When + // DRP is switched to mojo, we won't need URLRequestContext. + if (!base::FeatureList::IsEnabled(network::features::kNetworkService)) { + DCHECK(url_request_context_getter_); + } } WarmupURLFetcher::~WarmupURLFetcher() {}
diff --git a/components/exo/client_controlled_shell_surface.cc b/components/exo/client_controlled_shell_surface.cc index 9e5ad04..48078d6 100644 --- a/components/exo/client_controlled_shell_surface.cc +++ b/components/exo/client_controlled_shell_surface.cc
@@ -577,74 +577,10 @@ if (drag_finished_callback_) drag_finished_callback_.Run(location.x(), location.y(), canceled); } + //////////////////////////////////////////////////////////////////////////////// // SurfaceDelegate overrides: -void ClientControlledShellSurface::OnSurfaceCommit() { - if (!widget_) { - // Modify the |origin_| to the |pending_geometry_| to place the window - // on the intended display. See b/77472684 for the details. - if (!pending_geometry_.IsEmpty()) - origin_ = pending_geometry_.origin(); - CreateShellSurfaceWidget(ash::ToWindowShowState(pending_window_state_)); - } - - ash::wm::WindowState* window_state = GetWindowState(); - if (window_state->GetStateType() != pending_window_state_) { - if (!IsPinned(window_state)) { - ash::wm::ClientControlledState::BoundsChangeAnimationType animation_type = - ash::wm::ClientControlledState::kAnimationNone; - switch (pending_window_state_) { - case ash::mojom::WindowStateType::NORMAL: - if (widget_->IsMaximized() || widget_->IsFullscreen()) { - animation_type = - ash::wm::ClientControlledState::kAnimationCrossFade; - } - break; - - case ash::mojom::WindowStateType::MAXIMIZED: - case ash::mojom::WindowStateType::FULLSCREEN: - animation_type = ash::wm::ClientControlledState::kAnimationCrossFade; - break; - - default: - break; - } - client_controlled_state_->EnterNextState( - window_state, pending_window_state_, animation_type); - } else { - VLOG(1) << "State change was requested while it is pinned"; - } - } - - ShellSurfaceBase::OnSurfaceCommit(); - UpdateFrame(); - UpdateBackdrop(); - - if (geometry_changed_callback_) - geometry_changed_callback_.Run(GetVisibleBounds()); - - // Apply new top inset height. - if (pending_top_inset_height_ != top_inset_height_) { - widget_->GetNativeWindow()->SetProperty(aura::client::kTopViewInset, - pending_top_inset_height_); - top_inset_height_ = pending_top_inset_height_; - } - - // Update surface scale. - if (pending_scale_ != scale_) { - gfx::Transform transform; - DCHECK_NE(pending_scale_, 0.0); - transform.Scale(1.0 / pending_scale_, 1.0 / pending_scale_); - host_window()->SetTransform(transform); - scale_ = pending_scale_; - } - - orientation_ = pending_orientation_; - if (expected_orientation_ == orientation_) - orientation_compositor_lock_.reset(); -} - bool ClientControlledShellSurface::IsInputEnabled(Surface* surface) const { // Client-driven dragging/resizing relies on implicit grab, which ensures that // mouse/touch events are delivered to the focused surface until release, even @@ -795,7 +731,7 @@ } //////////////////////////////////////////////////////////////////////////////// -// ShellSurface overrides: +// ShellSurfaceBase overrides: void ClientControlledShellSurface::SetWidgetBounds(const gfx::Rect& bounds) { if (((!client_controlled_move_resize_ && !GetWindowState()->is_dragged()) || @@ -912,6 +848,75 @@ return gfx::Point(); } +void ClientControlledShellSurface::OnPreWidgetCommit() { + if (!widget_) { + // Modify the |origin_| to the |pending_geometry_| to place the window on + // the intended display. See b/77472684 for details. + if (!pending_geometry_.IsEmpty()) + origin_ = pending_geometry_.origin(); + CreateShellSurfaceWidget(ash::ToWindowShowState(pending_window_state_)); + } + + ash::wm::WindowState* window_state = GetWindowState(); + if (window_state->GetStateType() == pending_window_state_) + return; + + if (IsPinned(window_state)) { + VLOG(1) << "State change was requested while pinned"; + return; + } + + auto animation_type = ash::wm::ClientControlledState::kAnimationNone; + switch (pending_window_state_) { + case ash::mojom::WindowStateType::NORMAL: + if (widget_->IsMaximized() || widget_->IsFullscreen()) { + animation_type = ash::wm::ClientControlledState::kAnimationCrossFade; + } + break; + + case ash::mojom::WindowStateType::MAXIMIZED: + case ash::mojom::WindowStateType::FULLSCREEN: + animation_type = ash::wm::ClientControlledState::kAnimationCrossFade; + break; + + default: + break; + } + + client_controlled_state_->EnterNextState(window_state, pending_window_state_, + animation_type); +} + +void ClientControlledShellSurface::OnPostWidgetCommit() { + DCHECK(widget_); + + UpdateFrame(); + UpdateBackdrop(); + + if (geometry_changed_callback_) + geometry_changed_callback_.Run(GetVisibleBounds()); + + // Apply new top inset height. + if (pending_top_inset_height_ != top_inset_height_) { + widget_->GetNativeWindow()->SetProperty(aura::client::kTopViewInset, + pending_top_inset_height_); + top_inset_height_ = pending_top_inset_height_; + } + + // Update surface scale. + if (pending_scale_ != scale_) { + gfx::Transform transform; + DCHECK_NE(pending_scale_, 0.0); + transform.Scale(1.0 / pending_scale_, 1.0 / pending_scale_); + host_window()->SetTransform(transform); + scale_ = pending_scale_; + } + + orientation_ = pending_orientation_; + if (expected_orientation_ == orientation_) + orientation_compositor_lock_.reset(); +} + //////////////////////////////////////////////////////////////////////////////// // ClientControlledShellSurface, private:
diff --git a/components/exo/client_controlled_shell_surface.h b/components/exo/client_controlled_shell_surface.h index afbda15..62321a2 100644 --- a/components/exo/client_controlled_shell_surface.h +++ b/components/exo/client_controlled_shell_surface.h
@@ -183,7 +183,6 @@ void SetOrientationLock(ash::OrientationLockType orientation_lock); // Overridden from SurfaceDelegate: - void OnSurfaceCommit() override; bool IsInputEnabled(Surface* surface) const override; void OnSetFrame(SurfaceFrameType type) override; void OnSetFrameColors(SkColor active_color, SkColor inactive_color) override; @@ -230,13 +229,15 @@ class ScopedSetBoundsLocally; class ScopedLockedToRoot; - // Overridden from ShellSurface: + // Overridden from ShellSurfaceBase: void SetWidgetBounds(const gfx::Rect& bounds) override; gfx::Rect GetShadowBounds() const override; void InitializeWindowState(ash::wm::WindowState* window_state) override; float GetScale() const override; gfx::Rect GetWidgetBounds() const override; gfx::Point GetSurfaceOrigin() const override; + void OnPreWidgetCommit() override; + void OnPostWidgetCommit() override; // Update frame status. This may create (or destroy) a wide frame // that spans the full work area width if the surface didn't cover
diff --git a/components/exo/shell_surface.cc b/components/exo/shell_surface.cc index 9691dd2..6df863c 100644 --- a/components/exo/shell_surface.cc +++ b/components/exo/shell_surface.cc
@@ -236,6 +236,26 @@ scoped_animations_disabled_.reset(); } +//////////////////////////////////////////////////////////////////////////////// +// ShellSurfaceBase overrides: + +void ShellSurface::OnPreWidgetCommit() { + if (!widget_ && enabled()) { + // Defer widget creation until surface contains some contents. + if (host_window()->bounds().IsEmpty()) { + Configure(); + return; + } + + CreateShellSurfaceWidget(ui::SHOW_STATE_NORMAL); + } +} + +void ShellSurface::OnPostWidgetCommit() {} + +//////////////////////////////////////////////////////////////////////////////// +// ShellSurface, private: + void ShellSurface::AttemptToStartDrag(int component) { ash::wm::WindowState* window_state = ash::wm::GetWindowState(widget_->GetNativeWindow());
diff --git a/components/exo/shell_surface.h b/components/exo/shell_surface.h index 1c12e29..90b2688 100644 --- a/components/exo/shell_surface.h +++ b/components/exo/shell_surface.h
@@ -72,6 +72,10 @@ private: class ScopedAnimationsDisabled; + // Overridden from ShellSurfaceBase: + void OnPreWidgetCommit() override; + void OnPostWidgetCommit() override; + void AttemptToStartDrag(int component); void EndDrag();
diff --git a/components/exo/shell_surface_base.cc b/components/exo/shell_surface_base.cc index 7cbceb2..13b0dc2 100644 --- a/components/exo/shell_surface_base.cc +++ b/components/exo/shell_surface_base.cc
@@ -741,81 +741,11 @@ SurfaceTreeHost::OnSurfaceCommit(); - if (enabled() && !widget_) { - // Defer widget creation until surface contains some contents. - if (host_window()->bounds().IsEmpty()) { - Configure(); - return; - } - - CreateShellSurfaceWidget(ui::SHOW_STATE_NORMAL); - } - - // Apply the accumulated pending origin offset to reflect acknowledged - // configure requests. - origin_offset_ += pending_origin_offset_; - pending_origin_offset_ = gfx::Vector2d(); - - // Update resize direction to reflect acknowledged configure requests. - resize_component_ = pending_resize_component_; - - // Apply new window geometry. - geometry_ = pending_geometry_; - - // Apply new minimum/maximium size. - bool size_constraint_changed = minimum_size_ != pending_minimum_size_ || - maximum_size_ != pending_maximum_size_; - minimum_size_ = pending_minimum_size_; - maximum_size_ = pending_maximum_size_; - - if (widget_) { - UpdateWidgetBounds(); - UpdateShadow(); - - // System modal container is used by clients to implement overlay - // windows using a single ShellSurface instance. If hit-test - // region is empty, then it is non interactive window and won't be - // activated. - if (container_ == ash::kShellWindowId_SystemModalContainer) { - // Prevent window from being activated when hit test region is empty. - bool activatable = activatable_ && HasHitTestRegion(); - if (activatable != CanActivate()) { - set_can_activate(activatable); - // Activate or deactivate window if activation state changed. - if (activatable) { - // Automatically activate only if the window is modal. - // Non modal window should be activated by a user action. - // TODO(oshima): Non modal system window does not have an associated - // task ID, and as a result, it cannot be activated from client side. - // Fix this (b/65460424) and remove this if condition. - if (system_modal_) - wm::ActivateWindow(widget_->GetNativeWindow()); - } else if (widget_->IsActive()) { - wm::DeactivateWindow(widget_->GetNativeWindow()); - } - } - } - - UpdateSurfaceBounds(); - - // Show widget if needed. - if (pending_show_widget_) { - DCHECK(!widget_->IsClosed()); - DCHECK(!widget_->IsVisible()); - pending_show_widget_ = false; - widget_->Show(); - if (has_grab_) - StartCapture(); - - if (container_ == ash::kShellWindowId_SystemModalContainer) - UpdateSystemModal(); - } - } + OnPreWidgetCommit(); + CommitWidget(); + OnPostWidgetCommit(); SubmitCompositorFrame(); - - if (size_constraint_changed) - widget_->OnSizeConstraintsChanged(); } bool ShellSurfaceBase::IsInputEnabled(Surface*) const { @@ -1505,4 +1435,71 @@ widget_->SetCapture(nullptr /* view */); } +void ShellSurfaceBase::CommitWidget() { + // Apply the accumulated pending origin offset to reflect acknowledged + // configure requests. + origin_offset_ += pending_origin_offset_; + pending_origin_offset_ = gfx::Vector2d(); + + // Update resize direction to reflect acknowledged configure requests. + resize_component_ = pending_resize_component_; + + // Apply new window geometry. + geometry_ = pending_geometry_; + + // Apply new minimum/maximium size. + bool size_constraint_changed = minimum_size_ != pending_minimum_size_ || + maximum_size_ != pending_maximum_size_; + minimum_size_ = pending_minimum_size_; + maximum_size_ = pending_maximum_size_; + + if (!widget_) + return; + + UpdateWidgetBounds(); + UpdateShadow(); + + // System modal container is used by clients to implement overlay + // windows using a single ShellSurface instance. If hit-test + // region is empty, then it is non interactive window and won't be + // activated. + if (container_ == ash::kShellWindowId_SystemModalContainer) { + // Prevent window from being activated when hit test region is empty. + bool activatable = activatable_ && HasHitTestRegion(); + if (activatable != CanActivate()) { + set_can_activate(activatable); + // Activate or deactivate window if activation state changed. + if (activatable) { + // Automatically activate only if the window is modal. + // Non modal window should be activated by a user action. + // TODO(oshima): Non modal system window does not have an associated + // task ID, and as a result, it cannot be activated from client side. + // Fix this (b/65460424) and remove this if condition. + if (system_modal_) + wm::ActivateWindow(widget_->GetNativeWindow()); + } else if (widget_->IsActive()) { + wm::DeactivateWindow(widget_->GetNativeWindow()); + } + } + } + + UpdateSurfaceBounds(); + + // Show widget if needed. + if (pending_show_widget_) { + DCHECK(!widget_->IsClosed()); + DCHECK(!widget_->IsVisible()); + pending_show_widget_ = false; + widget_->Show(); + if (has_grab_) + StartCapture(); + + if (container_ == ash::kShellWindowId_SystemModalContainer) + UpdateSystemModal(); + } + + if (size_constraint_changed) + widget_->OnSizeConstraintsChanged(); +} + } // namespace exo
diff --git a/components/exo/shell_surface_base.h b/components/exo/shell_surface_base.h index e1be090017..baa6598 100644 --- a/components/exo/shell_surface_base.h +++ b/components/exo/shell_surface_base.h
@@ -345,6 +345,11 @@ virtual gfx::Rect GetWidgetBounds() const; virtual gfx::Point GetSurfaceOrigin() const; + virtual void OnPreWidgetCommit() = 0; + virtual void OnPostWidgetCommit() = 0; + + void CommitWidget(); + bool activatable_ = true; bool can_minimize_ = true; bool has_frame_colors_ = false;
diff --git a/components/pdf/renderer/pdf_accessibility_tree.cc b/components/pdf/renderer/pdf_accessibility_tree.cc index a3e42c65..0f791f39 100644 --- a/components/pdf/renderer/pdf_accessibility_tree.cc +++ b/components/pdf/renderer/pdf_accessibility_tree.cc
@@ -4,7 +4,6 @@ #include <algorithm> -#include "base/debug/crash_logging.h" #include "base/i18n/break_iterator.h" #include "base/memory/ptr_util.h" #include "base/strings/stringprintf.h" @@ -210,18 +209,8 @@ for (const auto& node : nodes_) update.nodes.push_back(*node); - if (!tree_.Unserialize(update)) { - static auto* ax_tree_error = base::debug::AllocateCrashKeyString( - "ax_tree_error", base::debug::CrashKeySize::Size32); - static auto* ax_tree_update = base::debug::AllocateCrashKeyString( - "ax_tree_update", base::debug::CrashKeySize::Size64); - // Temporarily log some additional crash keys so we can try to - // figure out why we're getting bad accessibility trees here. - // http://crbug.com/770886 - base::debug::SetCrashKeyString(ax_tree_error, tree_.error()); - base::debug::SetCrashKeyString(ax_tree_update, update.ToString()); + if (!tree_.Unserialize(update)) LOG(FATAL) << tree_.error(); - } UpdateAXTreeDataFromSelection();
diff --git a/components/previews/content/BUILD.gn b/components/previews/content/BUILD.gn index b76be3b..cda199d 100644 --- a/components/previews/content/BUILD.gn +++ b/components/previews/content/BUILD.gn
@@ -37,6 +37,7 @@ "hint_cache_unittest.cc", "previews_content_util_unittest.cc", "previews_decider_impl_unittest.cc", + "previews_hints_unittest.cc", "previews_optimization_guide_unittest.cc", "previews_ui_service_unittest.cc", ]
diff --git a/components/previews/content/previews_hints.cc b/components/previews/content/previews_hints.cc index 3177929..36241ea 100644 --- a/components/previews/content/previews_hints.cc +++ b/components/previews/content/previews_hints.cc
@@ -231,6 +231,22 @@ return hints; } +// static +const optimization_guide::proto::PageHint* PreviewsHints::FindPageHint( + const GURL& document_url, + const optimization_guide::proto::Hint& hint) { + std::string url = document_url.spec(); + for (const auto& page_hint : hint.page_hints()) { + // TODO(dougarnett): Support wildcards. https://crbug.com/870039 + if (!page_hint.page_pattern().empty() && + url.find(page_hint.page_pattern()) != std::string::npos) { + // Return the first matching page hint. + return &page_hint; + } + } + return nullptr; +} + void PreviewsHints::Initialize() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); if (!initial_hints_.empty()) { @@ -246,32 +262,58 @@ int* out_inflation_percent) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + if (!url.has_host()) + return false; + + // First check for being whitelisted at top level for host suffix. std::set<url_matcher::URLMatcherConditionSet::ID> matches = url_matcher_.MatchURL(url); // Only consider the first match in iteration order as it takes precedence - // if there are multiple matches. + // if there are multiple matches for the top-level whitelist. const auto& first_match = matches.begin(); - if (first_match == matches.end()) { - return false; - } - - const auto whitelist_iter = whitelist_.find(*first_match); - if (whitelist_iter == whitelist_.end()) { - return false; - } - - const auto& whitelisted_optimizations = whitelist_iter->second; - for (auto optimization_iter = whitelisted_optimizations.begin(); - optimization_iter != whitelisted_optimizations.end(); - ++optimization_iter) { - if (optimization_iter->first == type) { - *out_inflation_percent = optimization_iter->second; - return true; + if (first_match != matches.end()) { + const auto whitelist_iter = whitelist_.find(*first_match); + if (whitelist_iter != whitelist_.end()) { + const auto& whitelisted_optimizations = whitelist_iter->second; + for (auto optimization_iter = whitelisted_optimizations.begin(); + optimization_iter != whitelisted_optimizations.end(); + ++optimization_iter) { + if (optimization_iter->first == type) { + *out_inflation_percent = optimization_iter->second; + // Whitelisted on top level whitelist. + return true; + } + } } } - // TODO(dougarnett): Check the hint cache for whitelisted optmizations too. + if (!hint_cache_) + return false; + + // Now check HintCache for a loaded entry with a PageHint that matches |url| + // that whitelists the optimization. + std::string host = url.host(); + if (!hint_cache_->IsHintLoaded(host)) { + // TODO(dougarnett): Add UMA histogram counts for both cases of HasHint(). + return false; + } + + const optimization_guide::proto::Hint* hint = hint_cache_->GetHint(host); + const optimization_guide::proto::PageHint* matched_page_hint = + FindPageHint(url, *hint); + if (!matched_page_hint) { + return false; + } + + for (const auto& optimization : + matched_page_hint->whitelisted_optimizations()) { + if (ConvertProtoOptimizationTypeToPreviewsOptimizationType( + optimization.optimization_type()) == type) { + *out_inflation_percent = optimization.inflation_percent(); + return true; + } + } return false; }
diff --git a/components/previews/content/previews_hints.h b/components/previews/content/previews_hints.h index 4aa4fca08..a562465 100644 --- a/components/previews/content/previews_hints.h +++ b/components/previews/content/previews_hints.h
@@ -35,12 +35,19 @@ const optimization_guide::proto::Configuration& config, const optimization_guide::ComponentInfo& info); + // Returns the matching PageHint for |document_url| if found in |hint|. + // TODO(dougarnett): Consider moving to some hint_util file. + static const optimization_guide::proto::PageHint* FindPageHint( + const GURL& document_url, + const optimization_guide::proto::Hint& hint); + void Initialize(); // Whether the URL is whitelisted for the given previews type. If so, // |out_inflation_percent| will be populated if meta data available for it. - // Note: this is top-level whitelist check which does not include checking - // within PageHints. + // This first checks the top-level whitelist and, if not whitelisted there, + // it will check the HintCache for having a loaded, matching PageHint that + // whitelists it. bool IsWhitelisted(const GURL& url, PreviewsType type, int* out_inflation_percent);
diff --git a/components/previews/content/previews_hints_unittest.cc b/components/previews/content/previews_hints_unittest.cc new file mode 100644 index 0000000..a10778a --- /dev/null +++ b/components/previews/content/previews_hints_unittest.cc
@@ -0,0 +1,55 @@ +// Copyright 2018 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 "components/previews/content/previews_hints.h" + +#include "components/optimization_guide/proto/hints.pb.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "url/gurl.h" + +namespace previews { + +// NOTE: most of the PreviewsHints tests are still included in the tests for +// PreviewsOptimizationGuide. + +TEST(PreviewsHintsTest, FindPageHintForSubstringPagePattern) { + optimization_guide::proto::Hint hint1; + + // Page hint for "/one/" + optimization_guide::proto::PageHint* page_hint1 = hint1.add_page_hints(); + page_hint1->set_page_pattern("/one/"); + + // Page hint for "two" + optimization_guide::proto::PageHint* page_hint2 = hint1.add_page_hints(); + page_hint2->set_page_pattern("two"); + + // Page hint for "three.jpg" + optimization_guide::proto::PageHint* page_hint3 = hint1.add_page_hints(); + page_hint3->set_page_pattern("three.jpg"); + + EXPECT_EQ(nullptr, PreviewsHints::FindPageHint(GURL(""), hint1)); + EXPECT_EQ(nullptr, + PreviewsHints::FindPageHint(GURL("https://www.foo.org/"), hint1)); + EXPECT_EQ(nullptr, PreviewsHints::FindPageHint( + GURL("https://www.foo.org/one"), hint1)); + + EXPECT_EQ(page_hint1, PreviewsHints::FindPageHint( + GURL("https://www.foo.org/one/"), hint1)); + EXPECT_EQ(page_hint1, PreviewsHints::FindPageHint( + GURL("https://www.foo.org/one/two"), hint1)); + EXPECT_EQ(page_hint1, + PreviewsHints::FindPageHint( + GURL("https://www.foo.org/one/two/three.jpg"), hint1)); + + EXPECT_EQ(page_hint2, + PreviewsHints::FindPageHint( + GURL("https://www.foo.org/onetwo/three.jpg"), hint1)); + EXPECT_EQ(page_hint2, + PreviewsHints::FindPageHint(GURL("https://one.two.org"), hint1)); + + EXPECT_EQ(page_hint3, PreviewsHints::FindPageHint( + GURL("https://www.foo.org/bar/three.jpg"), hint1)); +} + +} // namespace previews
diff --git a/components/previews/content/previews_optimization_guide.cc b/components/previews/content/previews_optimization_guide.cc index a23fa01..8f11fe0 100644 --- a/components/previews/content/previews_optimization_guide.cc +++ b/components/previews/content/previews_optimization_guide.cc
@@ -55,30 +55,27 @@ const GURL& document_url, const optimization_guide::proto::Hint& loaded_hint) const { DCHECK(io_task_runner_->BelongsToCurrentThread()); - std::string url = document_url.spec(); + + const optimization_guide::proto::PageHint* matched_page_hint = + PreviewsHints::FindPageHint(document_url, loaded_hint); + if (!matched_page_hint) + return; + + // Retrieve the resource patterns to be blocked from the page hint. std::vector<std::string> resource_patterns_to_block; - for (const auto& page_hint : loaded_hint.page_hints()) { - // TODO(dougarnett): Support wildcards. crbug.com/870039 - if (!page_hint.page_pattern().empty() && - url.find(page_hint.page_pattern()) != std::string::npos) { - // Matched the page pattern so now check for resource loading - // optimization. - for (const auto& optimization : page_hint.whitelisted_optimizations()) { - if (optimization.optimization_type() == - optimization_guide::proto::RESOURCE_LOADING) { - for (const auto& resource_loading_hint : - optimization.resource_loading_hints()) { - if (!resource_loading_hint.resource_pattern().empty() && - resource_loading_hint.loading_optimization_type() == - optimization_guide::proto::LOADING_BLOCK_RESOURCE) { - resource_patterns_to_block.push_back( - resource_loading_hint.resource_pattern()); - } - } + for (const auto& optimization : + matched_page_hint->whitelisted_optimizations()) { + if (optimization.optimization_type() == + optimization_guide::proto::RESOURCE_LOADING) { + for (const auto& resource_loading_hint : + optimization.resource_loading_hints()) { + if (!resource_loading_hint.resource_pattern().empty() && + resource_loading_hint.loading_optimization_type() == + optimization_guide::proto::LOADING_BLOCK_RESOURCE) { + resource_patterns_to_block.push_back( + resource_loading_hint.resource_pattern()); } } - // Only use this first matching page hint. - break; } } if (!resource_patterns_to_block.empty()) {
diff --git a/components/previews/content/previews_optimization_guide_unittest.cc b/components/previews/content/previews_optimization_guide_unittest.cc index d4ae7856..8cc67b3e 100644 --- a/components/previews/content/previews_optimization_guide_unittest.cc +++ b/components/previews/content/previews_optimization_guide_unittest.cc
@@ -660,6 +660,19 @@ loaded_hints_document_gurl()); EXPECT_EQ(1ul, loaded_hints_resource_patterns().size()); EXPECT_EQ("news_cruft.js", loaded_hints_resource_patterns().front()); + + // Verify whitelisting from loaded page hints. + EXPECT_TRUE(guide()->IsWhitelisted( + *CreateRequestWithURL( + GURL("https://www.somedomain.org/news/weather/raininginseattle")), + PreviewsType::RESOURCE_LOADING_HINTS)); + EXPECT_TRUE(guide()->IsWhitelisted( + *CreateRequestWithURL( + GURL("https://www.somedomain.org/football/seahawksrebuildingyear")), + PreviewsType::RESOURCE_LOADING_HINTS)); + EXPECT_FALSE(guide()->IsWhitelisted( + *CreateRequestWithURL(GURL("https://www.somedomain.org/unhinted")), + PreviewsType::RESOURCE_LOADING_HINTS)); } TEST_F(PreviewsOptimizationGuideTest, @@ -674,6 +687,13 @@ EXPECT_FALSE(guide()->MaybeLoadOptimizationHints( *CreateRequestWithURL(GURL("https://www.somedomain.org")), base::DoNothing())); + + RunUntilIdle(); + + EXPECT_FALSE(guide()->IsWhitelisted( + *CreateRequestWithURL( + GURL("https://www.somedomain.org/news/weather/raininginseattle")), + PreviewsType::RESOURCE_LOADING_HINTS)); } TEST_F(PreviewsOptimizationGuideTest, RemoveObserverCalledAtDestruction) {
diff --git a/components/previews/core/previews_experiments.cc b/components/previews/core/previews_experiments.cc index 4bf36cc..2836b2ee 100644 --- a/components/previews/core/previews_experiments.cc +++ b/components/previews/core/previews_experiments.cc
@@ -129,6 +129,12 @@ "offline_preview_freshness_duration_in_days", 7)); } +base::TimeDelta LitePagePreviewsSingleBypassDuration() { + return base::TimeDelta::FromSeconds(base::GetFieldTrialParamByFeatureAsInt( + features::kLitePageServerPreviews, "single_bypass_duration_in_seconds", + 60 * 5)); +} + GURL GetLitePagePreviewsDomainURL() { std::string variable_host_str = GetFieldTrialParamValueByFeature( features::kLitePageServerPreviews, "previews_host");
diff --git a/components/previews/core/previews_experiments.h b/components/previews/core/previews_experiments.h index 60bff1e..b457db0c 100644 --- a/components/previews/core/previews_experiments.h +++ b/components/previews/core/previews_experiments.h
@@ -92,6 +92,9 @@ // The host for Lite Page server previews. GURL GetLitePagePreviewsDomainURL(); +// The duration of a single bypass for Lite Page Server Previews. +base::TimeDelta LitePagePreviewsSingleBypassDuration(); + // The threshold of EffectiveConnectionType above which preview |type| will be // triggered. net::EffectiveConnectionType GetECTThresholdForPreview(
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn index f5dc926..861499f 100644 --- a/content/browser/BUILD.gn +++ b/content/browser/BUILD.gn
@@ -2468,7 +2468,10 @@ # See comment at the top of //content/BUILD.gn for how this works. group("for_content_tests") { - visibility = [ "//content/test/*" ] + visibility = [ + "//content/test/*", + "//content/public/test/*", + ] if (!is_component_build) { public_deps = [ ":browser",
diff --git a/content/browser/accessibility/browser_accessibility_manager.cc b/content/browser/accessibility/browser_accessibility_manager.cc index 119e113..2b1ec4e 100644 --- a/content/browser/accessibility/browser_accessibility_manager.cc +++ b/content/browser/accessibility/browser_accessibility_manager.cc
@@ -500,11 +500,16 @@ if (focus->GetRole() == ax::mojom::Role::kPopUpButton) { BrowserAccessibility* child = focus->InternalGetChild(0); - if (child && child->GetRole() == ax::mojom::Role::kMenuListPopup) { + if (child && child->GetRole() == ax::mojom::Role::kMenuListPopup && + !child->GetData().HasState(ax::mojom::State::kInvisible)) { // The active descendant is found on the menu list popup, i.e. on the // actual list and not on the button that opens it. // If there is no active descendant, focus should stay on the button so // that Windows screen readers would enable their virtual cursor. + // Do not expose an activedescendant in a hidden/collapsed list, as + // screen readers expect the focus event to go to the button itself. + // Note that the AX hierarchy in this case is strange -- the active + // option is the only visible option, and is inside an invisible list. if (child->GetIntAttribute(ax::mojom::IntAttribute::kActivedescendantId, &active_descendant_id)) { active_descendant = child->manager()->GetFromID(active_descendant_id); @@ -512,7 +517,8 @@ } } - if (active_descendant) + if (active_descendant && + !active_descendant->GetData().HasState(ax::mojom::State::kInvisible)) return active_descendant; return focus;
diff --git a/content/browser/accessibility/dump_accessibility_events_browsertest.cc b/content/browser/accessibility/dump_accessibility_events_browsertest.cc index c88e6cca..3d3fd4a 100644 --- a/content/browser/accessibility/dump_accessibility_events_browsertest.cc +++ b/content/browser/accessibility/dump_accessibility_events_browsertest.cc
@@ -359,6 +359,11 @@ RunEventTest(FILE_PATH_LITERAL("menulist-collapse.html")); } +IN_PROC_BROWSER_TEST_F(DumpAccessibilityEventsTest, + AccessibilityEventsMenuListCollapseNext) { + RunEventTest(FILE_PATH_LITERAL("menulist-collapse-next.html")); +} + // https://crbug.com/719030 IN_PROC_BROWSER_TEST_F(DumpAccessibilityEventsTest, DISABLED_AccessibilityEventsMenuListExpand) {
diff --git a/content/browser/frame_host/navigation_handle_impl.cc b/content/browser/frame_host/navigation_handle_impl.cc index 201f23b..836668c 100644 --- a/content/browser/frame_host/navigation_handle_impl.cc +++ b/content/browser/frame_host/navigation_handle_impl.cc
@@ -6,8 +6,10 @@ #include <iterator> +#include "base/bind.h" #include "base/logging.h" #include "base/metrics/histogram_macros.h" +#include "base/time/time.h" #include "content/browser/appcache/appcache_navigation_handle.h" #include "content/browser/appcache/appcache_service_impl.h" #include "content/browser/child_process_security_policy_impl.h" @@ -25,6 +27,7 @@ #include "content/browser/frame_host/origin_policy_throttle.h" #include "content/browser/frame_host/webui_navigation_throttle.h" #include "content/browser/loader/resource_dispatcher_host_impl.h" +#include "content/browser/renderer_host/render_widget_host_impl.h" #include "content/browser/service_worker/service_worker_context_wrapper.h" #include "content/browser/service_worker/service_worker_navigation_handle.h" #include "content/common/child_process_host_impl.h" @@ -46,6 +49,15 @@ namespace { +// Default timeout for the READY_TO_COMMIT -> COMMIT transition. +// Chosen based on the Navigation.ReadyToCommitUntilCommit UMA. +constexpr base::TimeDelta kDefaultCommitTimeout = + base::TimeDelta::FromSeconds(10); + +// Timeout for the READY_TO_COMMIT -> COMMIT transition. +// Overrideable via SetCommitTimeoutForTesting. +base::TimeDelta g_commit_timeout = kDefaultCommitTimeout; + // Use this to get a new unique ID for a NavigationHandle during construction. // The returned ID is guaranteed to be nonzero (zero is the "no ID" indicator). int64_t CreateUniqueHandleID() { @@ -822,6 +834,7 @@ render_frame_host_ = render_frame_host; state_ = READY_TO_COMMIT; ready_to_commit_time_ = base::TimeTicks::Now(); + RestartCommitTimeout(); // Record metrics for the time it takes to get to this state from the // beginning of the navigation. @@ -897,6 +910,8 @@ "DidCommitNavigation"); state_ = DID_COMMIT; } + commit_timeout_timer_.Stop(); + GetRenderFrameHost()->GetRenderWidgetHost()->RendererIsResponsive(); // Record metrics for the time it took to commit the navigation if it was to // another document without error. @@ -1381,4 +1396,31 @@ return throttles_[next_index_ - 1].get(); } +void NavigationHandleImpl::RestartCommitTimeout() { + commit_timeout_timer_.Stop(); + if (state_ >= DID_COMMIT) + return; + + commit_timeout_timer_.Start( + FROM_HERE, g_commit_timeout, + base::BindRepeating(&NavigationHandleImpl::OnCommitTimeout, + weak_factory_.GetWeakPtr())); +} + +void NavigationHandleImpl::OnCommitTimeout() { + DCHECK_EQ(READY_TO_COMMIT, state_); + GetRenderFrameHost()->GetRenderWidgetHost()->RendererIsUnresponsive( + base::BindRepeating(&NavigationHandleImpl::RestartCommitTimeout, + weak_factory_.GetWeakPtr())); +} + +// static +void NavigationHandleImpl::SetCommitTimeoutForTesting( + const base::TimeDelta& timeout) { + if (timeout.is_zero()) + g_commit_timeout = kDefaultCommitTimeout; + else + g_commit_timeout = timeout; +} + } // namespace content
diff --git a/content/browser/frame_host/navigation_handle_impl.h b/content/browser/frame_host/navigation_handle_impl.h index fe477a94..29e2978 100644 --- a/content/browser/frame_host/navigation_handle_impl.h +++ b/content/browser/frame_host/navigation_handle_impl.h
@@ -18,6 +18,8 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/optional.h" +#include "base/time/time.h" +#include "base/timer/timer.h" #include "content/browser/frame_host/frame_tree_node.h" #include "content/browser/frame_host/render_frame_host_impl.h" #include "content/common/content_export.h" @@ -377,6 +379,10 @@ return GetDeferringThrottle(); } + // Sets the READY_TO_COMMIT -> DID_COMMIT timeout. Resets the timeout to the + // default value if |timeout| is zero. + static void SetCommitTimeoutForTesting(const base::TimeDelta& timeout); + private: friend class NavigationHandleImplTest; @@ -440,6 +446,12 @@ // nullptr; NavigationThrottle* GetDeferringThrottle() const; + // Called if READY_TO_COMMIT -> COMMIT state transition takes an unusually + // long time. + void OnCommitTimeout(); + + void RestartCommitTimeout(); + // See NavigationHandle for a description of those member variables. GURL url_; scoped_refptr<SiteInstance> starting_site_instance_; @@ -495,6 +507,9 @@ // The time this naviagtion was ready to commit. base::TimeTicks ready_to_commit_time_; + // Timer for detecting an unexpectedly long time to commit a navigation. + base::OneShotTimer commit_timeout_timer_; + // The unique id of the corresponding NavigationEntry. int pending_nav_entry_id_;
diff --git a/content/browser/gpu/gpu_process_host.cc b/content/browser/gpu/gpu_process_host.cc index a7524d5..e6e0973 100644 --- a/content/browser/gpu/gpu_process_host.cc +++ b/content/browser/gpu/gpu_process_host.cc
@@ -655,14 +655,6 @@ std::move(interface_pipe)); } -void GpuProcessHost::TerminateGpuProcess(const std::string& message) { - // At the moment, this path is only used by Ozone/Wayland. Once others start - // to use this, start to distinguish the origin of termination. By default, - // it's unknown. - termination_origin_ = GpuTerminationOrigin::kOzoneWaylandProxy; - process_->TerminateOnBadMessageReceived(message); -} - // static GpuProcessHost* GpuProcessHost::FromID(int host_id) { DCHECK_CURRENTLY_ON(BrowserThread::IO); @@ -800,9 +792,6 @@ info.exit_code); break; case base::TERMINATION_STATUS_PROCESS_WAS_KILLED: - UMA_HISTOGRAM_ENUMERATION("GPU.GPUProcessTerminationOrigin", - termination_origin_, - GpuTerminationOrigin::kMax); message = "You killed the GPU process! Why?"; break; #if defined(OS_CHROMEOS) @@ -838,31 +827,24 @@ // possible to ensure the latter always has a valid device. crbug.com/608839 // When running with mus, the OzonePlatform may not have been created yet. So // defer the callback until OzonePlatform instance is created. - bool using_mojo = true; -#if defined(OS_CHROMEOS) - using_mojo = features::IsOzoneDrmMojo(); -#endif - if (using_mojo) { + if (features::IsOzoneDrmMojo()) { // TODO(rjkroege): Remove the legacy IPC code paths when no longer // necessary. https://crbug.com/806092 auto interface_binder = base::BindRepeating(&GpuProcessHost::BindInterface, weak_ptr_factory_.GetWeakPtr()); - auto terminate_cb = base::BindOnce(&GpuProcessHost::TerminateGpuProcess, - weak_ptr_factory_.GetWeakPtr()); auto io_callback = base::BindOnce( [](const base::RepeatingCallback<void(const std::string&, mojo::ScopedMessagePipeHandle)>& interface_binder, - base::OnceCallback<void(const std::string&)> terminate_cb, ui::OzonePlatform* platform) { DCHECK_CURRENTLY_ON(BrowserThread::IO); platform->GetGpuPlatformSupportHost()->OnGpuServiceLaunched( BrowserThread::GetTaskRunnerForThread(BrowserThread::UI), BrowserThread::GetTaskRunnerForThread(BrowserThread::IO), - interface_binder, std::move(terminate_cb)); + interface_binder); }, - interface_binder, std::move(terminate_cb)); + interface_binder); OzoneRegisterStartupCallbackHelper(std::move(io_callback)); } else {
diff --git a/content/browser/gpu/gpu_process_host.h b/content/browser/gpu/gpu_process_host.h index 324152f..7187e92b 100644 --- a/content/browser/gpu/gpu_process_host.h +++ b/content/browser/gpu/gpu_process_host.h
@@ -123,7 +123,6 @@ void BindInterface(const std::string& interface_name, mojo::ScopedMessagePipeHandle interface_pipe); - void TerminateGpuProcess(const std::string& message); // Get the GPU process host for the GPU process with the given ID. Returns // null if the process no longer exists. @@ -188,12 +187,6 @@ enum GpuInitializationStatus { UNKNOWN, SUCCESS, FAILURE }; - enum class GpuTerminationOrigin { - kUnknownOrigin = 0, - kOzoneWaylandProxy = 1, - kMax = 2, - }; - static bool ValidateHost(GpuProcessHost* host); // Increments |crash_count| by one. Before incrementing |crash_count|, for @@ -301,9 +294,6 @@ GpuInitializationStatus status_; - GpuTerminationOrigin termination_origin_ = - GpuTerminationOrigin::kUnknownOrigin; - // Time Init started. Used to log total GPU process startup time to UMA. base::TimeTicks init_start_time_;
diff --git a/content/browser/indexed_db/scopes/disjoint_range_lock_manager.cc b/content/browser/indexed_db/scopes/disjoint_range_lock_manager.cc index be075a7..19daa4f 100644 --- a/content/browser/indexed_db/scopes/disjoint_range_lock_manager.cc +++ b/content/browser/indexed_db/scopes/disjoint_range_lock_manager.cc
@@ -10,13 +10,14 @@ DisjointRangeLockManager::LockRequest::LockRequest(LockType type, LockAquiredCallback callback) : requested_type(type), callback(std::move(callback)) {} -DisjointRangeLockManager::LockRequest::LockRequest(LockRequest&&) = default; +DisjointRangeLockManager::LockRequest::LockRequest(LockRequest&&) noexcept = + default; DisjointRangeLockManager::LockRequest::~LockRequest() = default; DisjointRangeLockManager::Lock::Lock() = default; -DisjointRangeLockManager::Lock::Lock(Lock&&) = default; +DisjointRangeLockManager::Lock::Lock(Lock&&) noexcept = default; DisjointRangeLockManager::Lock::~Lock() = default; DisjointRangeLockManager::Lock& DisjointRangeLockManager::Lock::operator=( - DisjointRangeLockManager::Lock&&) = default; + DisjointRangeLockManager::Lock&&) noexcept = default; DisjointRangeLockManager::DisjointRangeLockManager( int level_count,
diff --git a/content/browser/indexed_db/scopes/scopes_lock_manager.cc b/content/browser/indexed_db/scopes/scopes_lock_manager.cc index 98a3580..1b68739 100644 --- a/content/browser/indexed_db/scopes/scopes_lock_manager.cc +++ b/content/browser/indexed_db/scopes/scopes_lock_manager.cc
@@ -12,7 +12,7 @@ : begin(std::move(begin)), end(std::move(end)) {} ScopesLockManager::ScopeLock::ScopeLock() = default; -ScopesLockManager::ScopeLock::ScopeLock(ScopeLock&& other) { +ScopesLockManager::ScopeLock::ScopeLock(ScopeLock&& other) noexcept { DCHECK(!this->is_locked_) << "Cannot move a lock onto an active lock."; this->is_locked_ = other.is_locked_; this->range_ = std::move(other.range_); @@ -29,7 +29,7 @@ closure_runner_(std::move(closure)) {} ScopesLockManager::ScopeLock& ScopesLockManager::ScopeLock::operator=( - ScopesLockManager::ScopeLock&& other) { + ScopesLockManager::ScopeLock&& other) noexcept { DCHECK(!this->is_locked_); this->is_locked_ = other.is_locked_; this->range_ = std::move(other.range_);
diff --git a/content/browser/media/capture/web_contents_audio_input_stream_unittest.cc b/content/browser/media/capture/web_contents_audio_input_stream_unittest.cc index 4ca7a1b..f27817f8 100644 --- a/content/browser/media/capture/web_contents_audio_input_stream_unittest.cc +++ b/content/browser/media/capture/web_contents_audio_input_stream_unittest.cc
@@ -473,7 +473,7 @@ // TODO(https://crbug.com/872340): Test appears to have timing-dependent flake. TEST_P(WebContentsAudioInputStreamTest, - DISABLE_MirroringNothingWithTargetChange) { + DISABLED_MirroringNothingWithTargetChange) { RUN_ON_AUDIO_THREAD(Open); RUN_ON_AUDIO_THREAD(Start); RUN_ON_AUDIO_THREAD(ChangeMirroringTarget);
diff --git a/content/browser/net/quota_policy_cookie_store_unittest.cc b/content/browser/net/quota_policy_cookie_store_unittest.cc index b4ba8759..e5189b1 100644 --- a/content/browser/net/quota_policy_cookie_store_unittest.cc +++ b/content/browser/net/quota_policy_cookie_store_unittest.cc
@@ -15,6 +15,7 @@ #include "base/time/time.h" #include "content/public/test/test_browser_thread_bundle.h" #include "net/cookies/cookie_util.h" +#include "net/log/net_log_with_source.h" #include "net/ssl/ssl_client_cert_type.h" #include "net/test/cert_test_util.h" #include "net/test/test_data_directory.h" @@ -50,7 +51,8 @@ void Load(CanonicalCookieVector* cookies) { EXPECT_FALSE(loaded_event_.IsSignaled()); store_->Load(base::Bind(&QuotaPolicyCookieStoreTest::OnLoaded, - base::Unretained(this))); + base::Unretained(this)), + net::NetLogWithSource()); loaded_event_.Wait(); cookies->swap(cookies_); }
diff --git a/content/browser/renderer_host/pepper/pepper_tcp_socket_message_filter.cc b/content/browser/renderer_host/pepper/pepper_tcp_socket_message_filter.cc index 8f7b4d57..80a05ab2 100644 --- a/content/browser/renderer_host/pepper/pepper_tcp_socket_message_filter.cc +++ b/content/browser/renderer_host/pepper/pepper_tcp_socket_message_filter.cc
@@ -33,8 +33,6 @@ #include "net/socket/ssl_client_socket.h" #include "net/socket/tcp_client_socket.h" #include "net/traffic_annotation/network_traffic_annotation.h" -#include "net/url_request/url_request_context.h" -#include "net/url_request/url_request_context_getter.h" #include "ppapi/host/dispatch_host_message.h" #include "ppapi/host/error_conversion.h" #include "ppapi/host/ppapi_host.h" @@ -70,6 +68,7 @@ external_plugin_(host->external_plugin()), render_process_id_(0), render_frame_id_(0), + binding_(this), host_(host), factory_(factory), instance_(instance), @@ -107,6 +106,7 @@ external_plugin_(host->external_plugin()), render_process_id_(0), render_frame_id_(0), + binding_(this), host_(host), factory_(nullptr), instance_(instance), @@ -214,6 +214,20 @@ host_ = nullptr; } +void PepperTCPSocketMessageFilter::OnComplete( + int result, + const base::Optional<net::AddressList>& resolved_addresses) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + binding_.Close(); + + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + base::BindOnce(&PepperTCPSocketMessageFilter::OnResolveCompleted, this, + result, std::move(resolved_addresses))); + + Release(); // Balances AddRef in OnMsgConnect. +} + int32_t PepperTCPSocketMessageFilter::OnMsgBind( const ppapi::host::HostMessageContext* context, const PP_NetAddress_Private& net_addr) { @@ -267,13 +281,24 @@ if (!render_process_host) return PP_ERROR_FAILED; auto* storage_partition = render_process_host->GetStoragePartition(); + // Grab a reference to this class to ensure that it's fully alive if a + // connection error occurs (i.e. ref count is higher than 0 and there's no + // task from ResourceMessageFilterDeleteTraits to delete this object on the IO + // thread pending). Balanced in OnComplete(); + AddRef(); + + network::mojom::ResolveHostClientPtr client_ptr; + binding_.Bind(mojo::MakeRequest(&client_ptr)); + binding_.set_connection_error_handler( + base::BindOnce(&PepperTCPSocketMessageFilter::OnComplete, + base::Unretained(this), net::ERR_FAILED, base::nullopt)); + storage_partition->GetNetworkContext()->ResolveHost( + net::HostPortPair(host, port), nullptr, std::move(client_ptr)); BrowserThread::PostTask( BrowserThread::IO, FROM_HERE, - base::BindOnce( - &PepperTCPSocketMessageFilter::DoConnect, this, - context->MakeReplyMessageContext(), host, port, - base::WrapRefCounted(storage_partition->GetURLRequestContext()))); + base::BindOnce(&PepperTCPSocketMessageFilter::HostResolvingStarted, this, + context->MakeReplyMessageContext())); return PP_OK_COMPLETIONPENDING; } @@ -614,27 +639,12 @@ state_.DoTransition(TCPSocketState::BIND, false); } -void PepperTCPSocketMessageFilter::DoConnect( - const ppapi::host::ReplyMessageContext& context, - const std::string& host, - uint16_t port, - scoped_refptr<net::URLRequestContextGetter> url_request_context_getter) { +void PepperTCPSocketMessageFilter::HostResolvingStarted( + const ppapi::host::ReplyMessageContext& context) { DCHECK_CURRENTLY_ON(BrowserThread::IO); - if (!state_.IsValidTransition(TCPSocketState::CONNECT)) { - SendConnectError(context, PP_ERROR_FAILED); - return; - } - - auto* url_request_context = - url_request_context_getter->GetURLRequestContext(); - if (!url_request_context) { - SendConnectError(context, PP_ERROR_FAILED); - return; - } - - net::HostResolver* host_resolver = url_request_context->host_resolver(); - if (!host_resolver) { + NOTREACHED() << "This shouldn't be reached since the renderer only tries " + << "to connect once."; SendConnectError(context, PP_ERROR_FAILED); return; } @@ -642,15 +652,7 @@ state_.SetPendingTransition(TCPSocketState::CONNECT); address_index_ = 0; address_list_.clear(); - net::HostResolver::RequestInfo request_info(net::HostPortPair(host, port)); - - int net_result = host_resolver->Resolve( - request_info, net::DEFAULT_PRIORITY, &address_list_, - base::BindOnce(&PepperTCPSocketMessageFilter::OnResolveCompleted, - base::Unretained(this), context), - &request_, net::NetLogWithSource()); - if (net_result != net::ERR_IO_PENDING) - OnResolveCompleted(context, net_result); + host_resolve_context_ = context; } void PepperTCPSocketMessageFilter::DoConnectWithNetAddress( @@ -772,9 +774,14 @@ } void PepperTCPSocketMessageFilter::OnResolveCompleted( - const ppapi::host::ReplyMessageContext& context, - int net_result) { + int net_result, + const base::Optional<net::AddressList>& resolved_addresses) { DCHECK_CURRENTLY_ON(BrowserThread::IO); + if (!host_resolve_context_.is_valid()) + return; + + ppapi::host::ReplyMessageContext context = host_resolve_context_; + host_resolve_context_ = ppapi::host::ReplyMessageContext(); if (!state_.IsPending(TCPSocketState::CONNECT)) { DCHECK(state_.state() == TCPSocketState::CLOSED); @@ -788,6 +795,7 @@ return; } + address_list_ = resolved_addresses.value(); StartConnect(context); }
diff --git a/content/browser/renderer_host/pepper/pepper_tcp_socket_message_filter.h b/content/browser/renderer_host/pepper/pepper_tcp_socket_message_filter.h index fec0b7c..633df8f 100644 --- a/content/browser/renderer_host/pepper/pepper_tcp_socket_message_filter.h +++ b/content/browser/renderer_host/pepper/pepper_tcp_socket_message_filter.h
@@ -19,6 +19,7 @@ #include "content/browser/renderer_host/pepper/browser_ppapi_host_impl.h" #include "content/browser/renderer_host/pepper/ssl_context_helper.h" #include "content/common/content_export.h" +#include "mojo/public/cpp/bindings/binding.h" #include "net/base/address_list.h" #include "net/base/ip_endpoint.h" #include "net/dns/host_resolver.h" @@ -28,6 +29,7 @@ #include "ppapi/c/private/ppb_net_address_private.h" #include "ppapi/host/resource_message_filter.h" #include "ppapi/shared_impl/ppb_tcp_socket_shared.h" +#include "services/network/public/mojom/network_context.mojom.h" #if defined(OS_CHROMEOS) #include "chromeos/network/firewall_hole.h" @@ -38,7 +40,6 @@ class DrainableIOBuffer; class IOBuffer; class SSLClientSocket; -class URLRequestContextGetter; } namespace ppapi { @@ -56,7 +57,8 @@ class CONTENT_EXPORT PepperTCPSocketMessageFilter : public ppapi::host::ResourceMessageFilter, - public BrowserPpapiHostImpl::InstanceObserver { + public BrowserPpapiHostImpl::InstanceObserver, + public network::mojom::ResolveHostClient { public: PepperTCPSocketMessageFilter(ContentBrowserPepperHostFactory* factory, BrowserPpapiHostImpl* host, @@ -91,6 +93,11 @@ void OnThrottleStateChanged(bool is_throttled) override; void OnHostDestroyed() override; + // network::mojom::ResolveHostClient overrides. + void OnComplete( + int result, + const base::Optional<net::AddressList>& resolved_addresses) override; + int32_t OnMsgBind(const ppapi::host::HostMessageContext* context, const PP_NetAddress_Private& net_addr); int32_t OnMsgConnect(const ppapi::host::HostMessageContext* context, @@ -119,19 +126,16 @@ void DoBind(const ppapi::host::ReplyMessageContext& context, const PP_NetAddress_Private& net_addr); - void DoConnect( - const ppapi::host::ReplyMessageContext& context, - const std::string& host, - uint16_t port, - scoped_refptr<net::URLRequestContextGetter> url_request_context_getter); + void HostResolvingStarted(const ppapi::host::ReplyMessageContext& context); void DoConnectWithNetAddress(const ppapi::host::ReplyMessageContext& context, const PP_NetAddress_Private& net_addr); void DoWrite(const ppapi::host::ReplyMessageContext& context); void DoListen(const ppapi::host::ReplyMessageContext& context, int32_t backlog); - void OnResolveCompleted(const ppapi::host::ReplyMessageContext& context, - int net_result); + void OnResolveCompleted( + int net_result, + const base::Optional<net::AddressList>& resolved_addresses); void StartConnect(const ppapi::host::ReplyMessageContext& context); void OnConnectCompleted(const ppapi::host::ReplyMessageContext& context, @@ -198,6 +202,10 @@ int render_process_id_; int render_frame_id_; + // A reference to |this| must always be taken while |binding_| is bound to + // ensure that if the error callback is called the object is alive. + mojo::Binding<network::mojom::ResolveHostClient> binding_; + // The following fields are used only on the IO thread. // Non-owning ptr. BrowserPpapiHostImpl* host_; @@ -237,6 +245,7 @@ net::AddressList address_list_; // Where we are in the above list. size_t address_index_; + ppapi::host::ReplyMessageContext host_resolve_context_; // Non-null unless an SSL connection is requested. std::unique_ptr<net::TCPSocket> socket_;
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc index c63ea22..7bc55c57 100644 --- a/content/browser/renderer_host/render_process_host_impl.cc +++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -3546,8 +3546,8 @@ case CheckOriginLockResult::HAS_WRONG_LOCK: return false; case CheckOriginLockResult::NO_LOCK: - if (!host->IsUnused() && SiteInstanceImpl::ShouldLockToOrigin( - browser_context, host, site_url)) { + if (!host->IsUnused() && + SiteInstanceImpl::ShouldLockToOrigin(browser_context, site_url)) { // If this process has been used to host any other content, it cannot // be reused if the destination site requires a dedicated process and // should use a process locked to just that site.
diff --git a/content/browser/renderer_host/render_widget_host_impl.cc b/content/browser/renderer_host/render_widget_host_impl.cc index 6d46c37..774d72f 100644 --- a/content/browser/renderer_host/render_widget_host_impl.cc +++ b/content/browser/renderer_host/render_widget_host_impl.cc
@@ -408,8 +408,8 @@ const auto* command_line = base::CommandLine::ForCurrentProcess(); if (!command_line->HasSwitch(switches::kDisableHangMonitor)) { input_event_ack_timeout_.reset(new TimeoutMonitor( - base::Bind(&RenderWidgetHostImpl::RendererIsUnresponsive, - weak_factory_.GetWeakPtr()))); + base::BindRepeating(&RenderWidgetHostImpl::OnInputEventAckTimeout, + weak_factory_.GetWeakPtr()))); } if (!command_line->HasSwitch(switches::kDisableNewContentRenderingTimeout)) { @@ -2086,18 +2086,24 @@ } } -void RenderWidgetHostImpl::RendererIsUnresponsive() { +void RenderWidgetHostImpl::OnInputEventAckTimeout() { + RendererIsUnresponsive(base::BindRepeating( + &RenderWidgetHostImpl::RestartInputEventAckTimeoutIfNecessary, + weak_factory_.GetWeakPtr())); +} + +void RenderWidgetHostImpl::RendererIsUnresponsive( + base::RepeatingClosure restart_hang_monitor_timeout) { NotificationService::current()->Notify( NOTIFICATION_RENDER_WIDGET_HOST_HANG, Source<RenderWidgetHost>(this), NotificationService::NoDetails()); is_unresponsive_ = true; - if (delegate_) - delegate_->RendererUnresponsive( - this, base::BindRepeating( - &RenderWidgetHostImpl::RestartInputEventAckTimeoutIfNecessary, - weak_factory_.GetWeakPtr())); + if (delegate_) { + delegate_->RendererUnresponsive(this, + std::move(restart_hang_monitor_timeout)); + } // Do not add code after this since the Delegate may delete this // RenderWidgetHostImpl in RendererUnresponsive.
diff --git a/content/browser/renderer_host/render_widget_host_impl.h b/content/browser/renderer_host/render_widget_host_impl.h index 0d347cb..f475ee2b 100644 --- a/content/browser/renderer_host/render_widget_host_impl.h +++ b/content/browser/renderer_host/render_widget_host_impl.h
@@ -717,6 +717,17 @@ void GetContentRenderingTimeoutFrom(RenderWidgetHostImpl* other); + // Called on delayed response from the renderer by either + // 1) |hang_monitor_timeout_| (slow to ack input events) or + // 2) NavigationHandle::OnCommitTimeout (slow to commit). + void RendererIsUnresponsive( + base::RepeatingClosure restart_hang_monitor_timeout); + + // Called if we know the renderer is responsive. When we currently think the + // renderer is unresponsive, this will clear that state and call + // NotifyRendererResponsive. + void RendererIsResponsive(); + protected: // --------------------------------------------------------------------------- // The following method is overridden by RenderViewHost to send upwards to @@ -794,18 +805,10 @@ // destructor is called as well. void Destroy(bool also_delete); - // Called by |input_event_ack_timeout_| on delayed response from the renderer. - void RendererIsUnresponsive(); - // Called by |new_content_rendering_timeout_| if a renderer has loaded new // content but failed to produce a compositor frame in a defined time. void ClearDisplayedGraphics(); - // Called if we know the renderer is responsive. When we currently think the - // renderer is unresponsive, this will clear that state and call - // NotifyRendererResponsive. - void RendererIsResponsive(); - // IPC message handlers void OnRenderProcessGone(int status, int error_code); void OnClose(); @@ -888,6 +891,10 @@ // was noticed because of input event ack timeout. void RestartInputEventAckTimeoutIfNecessary(); + // Called by |input_event_ack_timeout_| when an input event timed out without + // getting an ack from the renderer. + void OnInputEventAckTimeout(); + void SetupInputRouter(); // Start intercepting system keyboard events.
diff --git a/content/browser/resolve_proxy_msg_helper.cc b/content/browser/resolve_proxy_msg_helper.cc index 22a2b63..41a3408 100644 --- a/content/browser/resolve_proxy_msg_helper.cc +++ b/content/browser/resolve_proxy_msg_helper.cc
@@ -125,7 +125,7 @@ : url(url), reply_msg(reply_msg) {} ResolveProxyMsgHelper::PendingRequest::PendingRequest( - PendingRequest&& pending_request) = default; + PendingRequest&& pending_request) noexcept = default; ResolveProxyMsgHelper::PendingRequest::~PendingRequest() noexcept = default;
diff --git a/content/browser/site_instance_impl.cc b/content/browser/site_instance_impl.cc index 4385285..1ae8fc8e 100644 --- a/content/browser/site_instance_impl.cc +++ b/content/browser/site_instance_impl.cc
@@ -540,11 +540,10 @@ // static bool SiteInstanceImpl::ShouldLockToOrigin(BrowserContext* browser_context, - RenderProcessHost* host, GURL site_url) { // Don't lock to origin in --single-process mode, since this mode puts // cross-site pages into the same process. - if (host->run_renderer_in_process()) + if (RenderProcessHost::run_renderer_in_process()) return false; if (!DoesSiteRequireDedicatedProcess(browser_context, site_url)) @@ -607,7 +606,7 @@ ChildProcessSecurityPolicyImpl* policy = ChildProcessSecurityPolicyImpl::GetInstance(); auto lock_state = policy->CheckOriginLock(process_->GetID(), site_); - if (ShouldLockToOrigin(GetBrowserContext(), process_, site_)) { + if (ShouldLockToOrigin(GetBrowserContext(), site_)) { // Sanity check that this won't try to assign an origin lock to a <webview> // process, which can't be locked. CHECK(!process_->IsForGuestsOnly());
diff --git a/content/browser/site_instance_impl.h b/content/browser/site_instance_impl.h index f2fa8e1..f917e5ac 100644 --- a/content/browser/site_instance_impl.h +++ b/content/browser/site_instance_impl.h
@@ -203,18 +203,17 @@ static bool DoesSiteRequireDedicatedProcess(BrowserContext* browser_context, const GURL& url); - // Returns true if a process |host| can be locked to a site |site_url|. - // Returning true here also implies that |site_url| requires a dedicated - // process. However, the converse does not hold: this might still return - // false for certain special cases where an origin lock can't be applied even - // when |site_url| requires a dedicated process (e.g., with + // Returns true if a process can be locked to a site |site_url|. Returning + // true here also implies that |site_url| requires a dedicated process. + // However, the converse does not hold: this might still return false for + // certain special cases where an origin lock can't be applied even when + // |site_url| requires a dedicated process (e.g., with // --site-per-process). Examples of those cases include <webview> guests, // WebUI, single-process mode, or extensions where a process is currently // allowed to be reused for different extensions. Most of these special // cases should eventually be removed, and this function should become // equivalent to DoesSiteRequireDedicatedProcess(). static bool ShouldLockToOrigin(BrowserContext* browser_context, - RenderProcessHost* host, GURL site_url); private:
diff --git a/content/browser/site_per_process_browsertest.cc b/content/browser/site_per_process_browsertest.cc index 6483bee..02d3e59a 100644 --- a/content/browser/site_per_process_browsertest.cc +++ b/content/browser/site_per_process_browsertest.cc
@@ -251,7 +251,7 @@ NotificationSource source_; NotificationDetails details_; - scoped_refptr<MessageLoopRunner> message_loop_runner_; + base::RunLoop run_loop_; DISALLOW_COPY_AND_ASSIGN(RedirectNotificationObserver); }; @@ -272,8 +272,7 @@ return; running_ = true; - message_loop_runner_ = new MessageLoopRunner; - message_loop_runner_->Run(); + run_loop_.Run(); EXPECT_TRUE(seen_); } @@ -288,7 +287,7 @@ if (!running_) return; - message_loop_runner_->Quit(); + run_loop_.Quit(); running_ = false; } @@ -301,8 +300,7 @@ int expected_frame_count) : WebContentsObserver(web_contents), expected_frame_count_(expected_frame_count), - frames_created_(0), - message_loop_runner_(new MessageLoopRunner) {} + frames_created_(0) {} ~RenderFrameHostCreatedObserver() override; @@ -320,8 +318,8 @@ // The number of RenderFrameHosts that have been created. int frames_created_; - // The MessageLoopRunner used to spin the message loop. - scoped_refptr<MessageLoopRunner> message_loop_runner_; + // The RunLoop used to spin the message loop. + base::RunLoop run_loop_; DISALLOW_COPY_AND_ASSIGN(RenderFrameHostCreatedObserver); }; @@ -330,14 +328,14 @@ } void RenderFrameHostCreatedObserver::Wait() { - message_loop_runner_->Run(); + run_loop_.Run(); } void RenderFrameHostCreatedObserver::RenderFrameCreated( RenderFrameHost* render_frame_host) { frames_created_++; if (frames_created_ == expected_frame_count_) { - message_loop_runner_->Quit(); + run_loop_.Quit(); } } @@ -7215,22 +7213,23 @@ // Helper class to wait for a ShutdownRequest message to arrive. class ShutdownObserver : public RenderProcessHostObserver { public: - ShutdownObserver() : message_loop_runner_(new MessageLoopRunner) {} + ShutdownObserver() = default; void RenderProcessShutdownRequested(RenderProcessHost* host) override { has_received_shutdown_request_ = true; - message_loop_runner_->Quit(); + run_loop_.Quit(); } - void Wait() { message_loop_runner_->Run(); } + void Wait() { run_loop_.Run(); } bool has_received_shutdown_request() { return has_received_shutdown_request_; } private: - scoped_refptr<MessageLoopRunner> message_loop_runner_; + base::RunLoop run_loop_; bool has_received_shutdown_request_ = false; + DISALLOW_COPY_AND_ASSIGN(ShutdownObserver); }; @@ -7753,8 +7752,7 @@ public: PendingWidgetMessageFilter() : BrowserMessageFilter(kMessageClasses, arraysize(kMessageClasses)), - routing_id_(MSG_ROUTING_NONE), - message_loop_runner_(new MessageLoopRunner) {} + routing_id_(MSG_ROUTING_NONE) {} bool OnMessageReceived(const IPC::Message& message) override { bool handled = true; @@ -7766,9 +7764,7 @@ return handled; } - void Wait() { - message_loop_runner_->Run(); - } + void Wait() { run_loop_.Run(); } int routing_id() { return routing_id_; } @@ -7794,11 +7790,11 @@ void OnReceivedRoutingIDOnUI(int widget_routing_id) { routing_id_ = widget_routing_id; - message_loop_runner_->Quit(); + run_loop_.Quit(); } int routing_id_; - scoped_refptr<MessageLoopRunner> message_loop_runner_; + base::RunLoop run_loop_; DISALLOW_COPY_AND_ASSIGN(PendingWidgetMessageFilter); }; @@ -9667,7 +9663,6 @@ public: SetIsInertMessageFilter() : content::BrowserMessageFilter(FrameMsgStart), - message_loop_runner_(new content::MessageLoopRunner), msg_received_(false) {} bool OnMessageReceived(const IPC::Message& message) override { @@ -9679,7 +9674,7 @@ bool is_inert() const { return is_inert_; } - void Wait() { message_loop_runner_->Run(); } + void Wait() { run_loop_.Run(); } private: ~SetIsInertMessageFilter() override {} @@ -9694,10 +9689,10 @@ is_inert_ = is_inert; if (!msg_received_) { msg_received_ = true; - message_loop_runner_->Quit(); + run_loop_.Quit(); } } - scoped_refptr<content::MessageLoopRunner> message_loop_runner_; + base::RunLoop run_loop_; bool msg_received_; bool is_inert_; DISALLOW_COPY_AND_ASSIGN(SetIsInertMessageFilter); @@ -12869,13 +12864,12 @@ // |web_contents|. class SameDocumentCommitObserver : public WebContentsObserver { public: - SameDocumentCommitObserver(WebContents* web_contents) - : WebContentsObserver(web_contents), - message_loop_runner_(new MessageLoopRunner) { + explicit SameDocumentCommitObserver(WebContents* web_contents) + : WebContentsObserver(web_contents) { EXPECT_TRUE(web_contents); } - void Wait() { message_loop_runner_->Run(); } + void Wait() { run_loop_.Run(); } const GURL& last_committed_url() { return last_committed_url_; } @@ -12883,12 +12877,12 @@ void DidFinishNavigation(NavigationHandle* navigation_handle) override { if (navigation_handle->IsSameDocument()) { last_committed_url_ = navigation_handle->GetURL(); - message_loop_runner_->Quit(); + run_loop_.Quit(); } } GURL last_committed_url_; - scoped_refptr<MessageLoopRunner> message_loop_runner_; + base::RunLoop run_loop_; DISALLOW_COPY_AND_ASSIGN(SameDocumentCommitObserver); }; @@ -13126,6 +13120,83 @@ EXPECT_TRUE(b_process_observer.did_exit_normally()); } +// This observer waits until WebContentsObserver::OnRendererUnresponsive +// notification. +class UnresponsiveRendererObserver : public WebContentsObserver { + public: + explicit UnresponsiveRendererObserver(WebContents* web_contents) + : WebContentsObserver(web_contents) {} + + ~UnresponsiveRendererObserver() override {} + + RenderProcessHost* Wait() { + if (!captured_render_process_host_) + run_loop_.Run(); + return captured_render_process_host_; + } + + private: + void OnRendererUnresponsive(RenderProcessHost* render_process_host) override { + captured_render_process_host_ = render_process_host; + run_loop_.Quit(); + } + + RenderProcessHost* captured_render_process_host_ = nullptr; + base::RunLoop run_loop_; + + DISALLOW_COPY_AND_ASSIGN(UnresponsiveRendererObserver); +}; + +IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, + CommitTimeoutForHungRenderer) { + // Navigate first tab to a.com. + GURL url(embedded_test_server()->GetURL("a.com", "/title1.html")); + EXPECT_TRUE(NavigateToURL(shell(), url)); + RenderProcessHost* a_process = + shell()->web_contents()->GetMainFrame()->GetProcess(); + + // Use window.open to open b.com in a second tab. Using a renderer-initiated + // navigation is important to leave a.com and b.com SiteInstances in the same + // BrowsingInstance (so the b.com -> a.com navigation in the next test step + // will reuse the process associated with the first a.com tab). + const char* kWindowOpenScript = R"( + var anchor = document.createElement("a"); + anchor.href = "/cross-site/b.com/title2.html"; + anchor.target = "_blank"; + document.body.appendChild(anchor); + anchor.click(); )"; + WebContentsAddedObserver new_window_observer; + EXPECT_TRUE(ExecuteScript(shell()->web_contents(), kWindowOpenScript)); + WebContents* new_window = new_window_observer.GetWebContents(); + EXPECT_TRUE(WaitForLoadStop(new_window)); + RenderProcessHost* b_process = new_window->GetMainFrame()->GetProcess(); + EXPECT_NE(a_process, b_process); + + // Hang the first tab's renderer. + const char* kHungScript = "setTimeout(function() { for (;;) {}; }, 0);"; + EXPECT_TRUE(ExecuteScript(shell()->web_contents(), kHungScript)); + + // Attempt to navigate the second tab to a.com. This will attempt to reuse + // the hung process. + NavigationHandleImpl::SetCommitTimeoutForTesting( + base::TimeDelta::FromMilliseconds(100)); + const char* kNavigationScript = R"( + var anchor = document.createElement("a"); + anchor.href = "/cross-site/a.com/title3.html"; + document.body.appendChild(anchor); + anchor.click(); )"; + UnresponsiveRendererObserver unresponsive_renderer_observer(new_window); + EXPECT_TRUE(ExecuteScript(new_window, kNavigationScript)); + + // Verify that we will be notified about the unresponsive renderer. Before + // changes in https://crrev.com/c/1089797, the test would hang here forever. + RenderProcessHost* hung_process = unresponsive_renderer_observer.Wait(); + EXPECT_EQ(hung_process, a_process); + + // Reset the timeout. + NavigationHandleImpl::SetCommitTimeoutForTesting(base::TimeDelta()); +} + // Tests that an inner WebContents will reattach to its outer WebContents after // a navigation that causes a process swap. IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, ProcessSwapOnInnerContents) {
diff --git a/content/browser/tracing/background_tracing_manager_impl.cc b/content/browser/tracing/background_tracing_manager_impl.cc index 4f88229..e41c3b37 100644 --- a/content/browser/tracing/background_tracing_manager_impl.cc +++ b/content/browser/tracing/background_tracing_manager_impl.cc
@@ -654,7 +654,7 @@ return "blink.console,v8"; case BackgroundTracingConfigImpl::CategoryPreset::BENCHMARK_NAVIGATION: return "benchmark,toplevel,ipc,base,browser,navigation,omnibox," - "disabled-by-default-system_stats"; + "safe_browsing,disabled-by-default-system_stats"; case BackgroundTracingConfigImpl::CategoryPreset::BLINK_STYLE: return "blink_style"; case BackgroundTracingConfigImpl::CategoryPreset::CATEGORY_PRESET_UNSET:
diff --git a/content/browser/web_contents/web_contents_android.h b/content/browser/web_contents/web_contents_android.h index c6c0026..f27570f4 100644 --- a/content/browser/web_contents/web_contents_android.h +++ b/content/browser/web_contents/web_contents_android.h
@@ -253,9 +253,9 @@ int bottom, int right); - private: RenderWidgetHostViewAndroid* GetRenderWidgetHostViewAndroid(); + private: void OnFinishGetContentBitmap(const base::android::JavaRef<jobject>& obj, const base::android::JavaRef<jobject>& callback, const std::string& path,
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc index 3d34c9a..4a52b5a 100644 --- a/content/browser/web_contents/web_contents_impl.cc +++ b/content/browser/web_contents/web_contents_impl.cc
@@ -2683,20 +2683,17 @@ params.target_url, raw_new_contents); } - if (opener) { - for (auto& observer : observers_) { - observer.DidOpenRequestedURL(raw_new_contents, opener, params.target_url, - params.referrer, params.disposition, - ui::PAGE_TRANSITION_LINK, - false, // started_from_context_menu - true); // renderer_initiated - } + for (auto& observer : observers_) { + observer.DidOpenRequestedURL(raw_new_contents, opener, params.target_url, + params.referrer, params.disposition, + ui::PAGE_TRANSITION_LINK, + false, // started_from_context_menu + true); // renderer_initiated } // Any new WebContents opened while this WebContents is in fullscreen can be // used to confuse the user, so drop fullscreen. - if (IsFullscreenForCurrentTab()) - ExitFullscreen(true); + ForSecurityDropFullscreen(); if (params.opener_suppressed) { // When the opener is suppressed, the original renderer cannot access the @@ -4366,8 +4363,7 @@ // Any new WebContents opened while this WebContents is in fullscreen can be // used to confuse the user, so drop fullscreen. - if (IsFullscreenForCurrentTab()) - ExitFullscreen(true); + ForSecurityDropFullscreen(); // We intentionally don't share the SiteInstance with the original frame so // that view source has a consistent process model and always ends up in a new @@ -5052,6 +5048,12 @@ if (showing_context_menu_) return; + // If the WebContents is not visible, don't show the context menu. This can + // happen if the renderer takes a while to return the right-click event back + // to the browser process and in the meantime the user switches tabs. + if (GetVisibility() != Visibility::VISIBLE) + return; + ContextMenuParams context_menu_params(params); // Allow WebContentsDelegates to handle the context menu operation first. if (delegate_ && delegate_->HandleContextMenu(context_menu_params)) @@ -5078,8 +5080,7 @@ // Running a dialog causes an exit to webpage-initiated fullscreen. // http://crbug.com/728276 - if (IsFullscreenForCurrentTab()) - ExitFullscreen(true); + ForSecurityDropFullscreen(); auto callback = base::BindOnce(&WebContentsImpl::OnDialogClosed, base::Unretained(this), @@ -5148,8 +5149,7 @@ // Running a dialog causes an exit to webpage-initiated fullscreen. // http://crbug.com/728276 - if (IsFullscreenForCurrentTab()) - ExitFullscreen(true); + ForSecurityDropFullscreen(); RenderFrameHostImpl* rfhi = static_cast<RenderFrameHostImpl*>(render_frame_host); @@ -5731,6 +5731,15 @@ } } +void WebContentsImpl::ForSecurityDropFullscreen() { + WebContentsImpl* web_contents = this; + while (web_contents) { + if (web_contents->IsFullscreenForCurrentTab()) + web_contents->ExitFullscreen(true); + web_contents = web_contents->GetOuterWebContents(); + } +} + void WebContentsImpl::SetAsFocusedWebContentsIfNecessary() { // Only change focus if we are not currently focused. WebContentsImpl* old_contents = GetFocusedWebContents(); @@ -5798,8 +5807,7 @@ void WebContentsImpl::DidCallFocus() { // Any explicit focusing of another window while this WebContents is in // fullscreen can be used to confuse the user, so drop fullscreen. - if (IsFullscreenForCurrentTab()) - ExitFullscreen(true); + ForSecurityDropFullscreen(); } RenderFrameHost* WebContentsImpl::GetFocusedFrameIncludingInnerWebContents() {
diff --git a/content/browser/web_contents/web_contents_impl.h b/content/browser/web_contents/web_contents_impl.h index 8857de3..de0e8b1 100644 --- a/content/browser/web_contents/web_contents_impl.h +++ b/content/browser/web_contents/web_contents_impl.h
@@ -923,6 +923,11 @@ // |IsFullscreen| must return |true| when this method is called. bool IsPictureInPictureAllowedForFullscreenVideo() const; + // The WebContents is trying to take some action that would cause user + // confusion if taken while in fullscreen. If this WebContents or any outer + // WebContents is in fullscreen, drop it. + void ForSecurityDropFullscreen(); + // When inner or outer WebContents are present, become the focused // WebContentsImpl. This will activate this content's main frame RenderWidget // and indirectly all its subframe widgets. GetFocusedRenderWidgetHost will @@ -1014,6 +1019,8 @@ FRIEND_TEST_ALL_PREFIXES(WebContentsImplBrowserTest, DialogsFromJavaScriptEndFullscreen); FRIEND_TEST_ALL_PREFIXES(WebContentsImplBrowserTest, + DialogsFromJavaScriptEndFullscreenEvenInInnerWC); + FRIEND_TEST_ALL_PREFIXES(WebContentsImplBrowserTest, PopupsFromJavaScriptEndFullscreen); FRIEND_TEST_ALL_PREFIXES(WebContentsImplBrowserTest, FocusFromJavaScriptEndsFullscreen);
diff --git a/content/browser/web_contents/web_contents_impl_browsertest.cc b/content/browser/web_contents/web_contents_impl_browsertest.cc index a26ee97..367e29c 100644 --- a/content/browser/web_contents/web_contents_impl_browsertest.cc +++ b/content/browser/web_contents/web_contents_impl_browsertest.cc
@@ -1558,8 +1558,10 @@ void ExitFullscreenModeForTab(WebContents*) override { is_fullscreen_ = false; - if (waiting_for_ == kFullscreenExit) + if (waiting_for_ == kFullscreenExit) { + waiting_for_ = kNothing; run_loop_->Quit(); + } } bool IsFullscreenForTabOrPending( @@ -1575,8 +1577,10 @@ bool* was_blocked) override { popup_ = std::move(new_contents); - if (waiting_for_ == kNewContents) + if (waiting_for_ == kNewContents) { + waiting_for_ = kNothing; run_loop_->Quit(); + } } // JavaScriptDialogManager @@ -1591,8 +1595,10 @@ last_message_ = base::UTF16ToUTF8(message_text); *did_suppress_message = true; - if (waiting_for_ == kDialog) + if (waiting_for_ == kDialog) { + waiting_for_ = kNothing; run_loop_->Quit(); + } } void RunBeforeUnloadDialog(WebContents* web_contents, @@ -1601,8 +1607,10 @@ DialogClosedCallback callback) override { std::move(callback).Run(true, base::string16()); - if (waiting_for_ == kDialog) + if (waiting_for_ == kDialog) { + waiting_for_ = kNothing; run_loop_->Quit(); + } } bool HandleJavaScriptDialog(WebContents* web_contents, @@ -1615,7 +1623,12 @@ bool reset_state) override {} private: - enum { kDialog, kNewContents, kFullscreenExit } waiting_for_; + enum { + kNothing, + kDialog, + kNewContents, + kFullscreenExit + } waiting_for_ = kNothing; std::string last_message_; @@ -2133,6 +2146,51 @@ } IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest, + DialogsFromJavaScriptEndFullscreenEvenInInnerWC) { + WebContentsImpl* top_contents = + static_cast<WebContentsImpl*>(shell()->web_contents()); + TestWCDelegateForDialogsAndFullscreen top_test_delegate; + top_contents->SetDelegate(&top_test_delegate); + + GURL url("about:blank"); + EXPECT_TRUE(NavigateToURL(shell(), url)); + + FrameTreeNode* root = top_contents->GetFrameTree()->root(); + ASSERT_EQ(0U, root->child_count()); + + std::string script = + "var iframe = document.createElement('iframe');" + "document.body.appendChild(iframe);"; + EXPECT_TRUE(content::ExecuteScript(root->current_frame_host(), script)); + EXPECT_TRUE(WaitForLoadStop(shell()->web_contents())); + + ASSERT_EQ(1U, root->child_count()); + RenderFrameHost* frame = root->child_at(0)->current_frame_host(); + ASSERT_NE(nullptr, frame); + + WebContentsImpl* inner_contents = + static_cast<WebContentsImpl*>(CreateAndAttachInnerContents(frame)); + TestWCDelegateForDialogsAndFullscreen inner_test_delegate; + inner_contents->SetDelegate(&inner_test_delegate); + + // A dialog from the inner WebContents should make the outer contents lose + // fullscreen. + top_contents->EnterFullscreenMode(url, blink::WebFullscreenOptions()); + EXPECT_TRUE(top_contents->IsFullscreenForCurrentTab()); + script = "alert('hi')"; + inner_test_delegate.WillWaitForDialog(); + EXPECT_TRUE(content::ExecuteScript(inner_contents, script)); + inner_test_delegate.Wait(); + EXPECT_FALSE(top_contents->IsFullscreenForCurrentTab()); + + inner_contents->SetDelegate(nullptr); + inner_contents->SetJavaScriptDialogManagerForTesting(nullptr); + + top_contents->SetDelegate(nullptr); + top_contents->SetJavaScriptDialogManagerForTesting(nullptr); +} + +IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest, PopupsFromJavaScriptEndFullscreen) { WebContentsImpl* wc = static_cast<WebContentsImpl*>(shell()->web_contents()); TestWCDelegateForDialogsAndFullscreen test_delegate;
diff --git a/content/browser/web_package/signed_exchange_handler.cc b/content/browser/web_package/signed_exchange_handler.cc index b068987c..a148b07 100644 --- a/content/browser/web_package/signed_exchange_handler.cc +++ b/content/browser/web_package/signed_exchange_handler.cc
@@ -322,7 +322,7 @@ int result = cert_verifier->Verify( net::CertVerifier::RequestParams( unverified_cert_chain_->cert(), envelope_->request_url().host(), - config.GetCertVerifyFlags(), unverified_cert_chain_->ocsp(), + 0 /* cert_verify_flags */, unverified_cert_chain_->ocsp(), net::CertificateList()), net::SSLConfigService::GetCRLSet().get(), &cert_verify_result_, base::BindRepeating(&SignedExchangeHandler::OnCertVerifyComplete,
diff --git a/content/browser/web_package/signed_exchange_handler_unittest.cc b/content/browser/web_package/signed_exchange_handler_unittest.cc index d41021f..fb6b81b 100644 --- a/content/browser/web_package/signed_exchange_handler_unittest.cc +++ b/content/browser/web_package/signed_exchange_handler_unittest.cc
@@ -124,6 +124,7 @@ net::CertVerifyResult* verify_result, std::unique_ptr<net::CertVerifier::Request>* out_req, const net::NetLogWithSource& net_log)); + MOCK_METHOD1(SetConfig, void(const net::CertVerifier::Config& config)); }; class MockCTVerifier : public net::CTVerifier {
diff --git a/content/common/plugin_list.cc b/content/common/plugin_list.cc index bc35065..2dbe9f6 100644 --- a/content/common/plugin_list.cc +++ b/content/common/plugin_list.cc
@@ -27,6 +27,45 @@ base::LazyInstance<PluginList>::DestructorAtExit g_singleton = LAZY_INSTANCE_INITIALIZER; +// Returns true if the plugin supports |mime_type|. |mime_type| should be all +// lower case. +bool SupportsType(const WebPluginInfo& plugin, + const std::string& mime_type, + bool allow_wildcard) { + // Webkit will ask for a plugin to handle empty mime types. + if (mime_type.empty()) + return false; + + for (size_t i = 0; i < plugin.mime_types.size(); ++i) { + const WebPluginMimeType& mime_info = plugin.mime_types[i]; + if (net::MatchesMimeType(mime_info.mime_type, mime_type)) { + if (!allow_wildcard && mime_info.mime_type == "*") + continue; + return true; + } + } + return false; +} + +// Returns true if the given plugin supports a given file extension. +// |extension| should be all lower case. |actual_mime_type| will be set to the +// MIME type if found. The MIME type which corresponds to the extension is +// optionally returned back. +bool SupportsExtension(const WebPluginInfo& plugin, + const std::string& extension, + std::string* actual_mime_type) { + for (size_t i = 0; i < plugin.mime_types.size(); ++i) { + const WebPluginMimeType& mime_type = plugin.mime_types[i]; + for (size_t j = 0; j < mime_type.file_extensions.size(); ++j) { + if (mime_type.file_extensions[j] == extension) { + *actual_mime_type = mime_type.mime_type; + return true; + } + } + } + return false; +} + } // namespace // static @@ -256,40 +295,6 @@ } } -bool PluginList::SupportsType(const WebPluginInfo& plugin, - const std::string& mime_type, - bool allow_wildcard) { - // Webkit will ask for a plugin to handle empty mime types. - if (mime_type.empty()) - return false; - - for (size_t i = 0; i < plugin.mime_types.size(); ++i) { - const WebPluginMimeType& mime_info = plugin.mime_types[i]; - if (net::MatchesMimeType(mime_info.mime_type, mime_type)) { - if (!allow_wildcard && mime_info.mime_type == "*") - continue; - return true; - } - } - return false; -} - -bool PluginList::SupportsExtension(const WebPluginInfo& plugin, - const std::string& extension, - std::string* actual_mime_type) { - for (size_t i = 0; i < plugin.mime_types.size(); ++i) { - const WebPluginMimeType& mime_type = plugin.mime_types[i]; - for (size_t j = 0; j < mime_type.file_extensions.size(); ++j) { - if (mime_type.file_extensions[j] == extension) { - if (actual_mime_type) - *actual_mime_type = mime_type.mime_type; - return true; - } - } - } - return false; -} - void PluginList::RemoveExtraPluginPathLocked( const base::FilePath& plugin_path) { lock_.AssertAcquired();
diff --git a/content/common/plugin_list.h b/content/common/plugin_list.h index 59aa05d..35ff2d0 100644 --- a/content/common/plugin_list.h +++ b/content/common/plugin_list.h
@@ -41,12 +41,6 @@ // Gets the one instance of the PluginList. static PluginList* Singleton(); - // Returns true if the plugin supports |mime_type|. |mime_type| should be all - // lower case. - static bool SupportsType(const WebPluginInfo& plugin, - const std::string& mime_type, - bool allow_wildcard); - // Cause the plugin list to refresh next time they are accessed, regardless // of whether they are already loaded. void RefreshPlugins(); @@ -66,12 +60,6 @@ // Gets a list of all the registered internal plugins. void GetInternalPlugins(std::vector<WebPluginInfo>* plugins); - // Creates a WebPluginInfo structure given a plugin's path. On success - // returns true, with the information being put into "info". - // Returns false if the library couldn't be found, or if it's not a plugin. - bool ReadPluginInfo(const base::FilePath& filename, - WebPluginInfo* info); - // Get all the plugins synchronously, loading them if necessary. void GetPlugins(std::vector<WebPluginInfo>* plugins); @@ -98,11 +86,20 @@ std::vector<WebPluginInfo>* info, std::vector<std::string>* actual_mime_types); - // Load a specific plugin with full path. Return true iff loading the plugin - // was successful. - bool LoadPluginIntoPluginList(const base::FilePath& filename, - std::vector<WebPluginInfo>* plugins, - WebPluginInfo* plugin_info); + void set_will_load_plugins_callback(const base::Closure& callback); + + private: + enum LoadingState { + LOADING_STATE_NEEDS_REFRESH, + LOADING_STATE_REFRESHING, + LOADING_STATE_UP_TO_DATE, + }; + + friend class PluginListTest; + friend struct base::LazyInstanceTraitsBase<PluginList>; + + PluginList(); + ~PluginList(); // The following functions are used to support probing for WebPluginInfo // using a different instance of this class. @@ -120,37 +117,24 @@ // Clears the internal list of Plugins and copies them from the vector. void SetPlugins(const std::vector<WebPluginInfo>& plugins); - void set_will_load_plugins_callback(const base::Closure& callback); - - virtual ~PluginList(); - - private: - enum LoadingState { - LOADING_STATE_NEEDS_REFRESH, - LOADING_STATE_REFRESHING, - LOADING_STATE_UP_TO_DATE, - }; - - friend class PluginListTest; - friend struct base::LazyInstanceTraitsBase<PluginList>; - - PluginList(); - // Load all plugins from the default plugins directory. void LoadPlugins(); - // Returns true if the given plugin supports a given file extension. - // |extension| should be all lower case. If |mime_type| is not NULL, it will - // be set to the MIME type if found. The MIME type which corresponds to the - // extension is optionally returned back. - bool SupportsExtension(const WebPluginInfo& plugin, - const std::string& extension, - std::string* actual_mime_type); - // Removes |plugin_path| from the list of extra plugin paths. Should only be // called while holding |lock_|. void RemoveExtraPluginPathLocked(const base::FilePath& plugin_path); + // Creates a WebPluginInfo structure given a plugin's path. On success + // returns true, with the information being put into "info". + // Returns false if the library couldn't be found, or if it's not a plugin. + bool ReadPluginInfo(const base::FilePath& filename, WebPluginInfo* info); + + // Load a specific plugin with full path. Return true iff loading the plugin + // was successful. + bool LoadPluginIntoPluginList(const base::FilePath& filename, + std::vector<WebPluginInfo>* plugins, + WebPluginInfo* plugin_info); + // // Internals //
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/ContentViewScrollingTest.java b/content/public/android/javatests/src/org/chromium/content/browser/ContentViewScrollingTest.java index 1740be3..e6b15b20 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/ContentViewScrollingTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/ContentViewScrollingTest.java
@@ -160,6 +160,7 @@ mActivityTestRule.launchContentShellWithUrl(LARGE_PAGE); mActivityTestRule.waitForActiveShellToBeDoneLoading(); mCoordinates = mActivityTestRule.getRenderCoordinates(); + mActivityTestRule.reportAllFrameSubmissions(true); waitForViewportInitialization(); Assert.assertEquals(0, mCoordinates.getScrollXPixInt());
diff --git a/content/public/app/mojo/content_gpu_manifest.json b/content/public/app/mojo/content_gpu_manifest.json index f56ca6cc..1335cff 100644 --- a/content/public/app/mojo/content_gpu_manifest.json +++ b/content/public/app/mojo/content_gpu_manifest.json
@@ -14,7 +14,6 @@ "service_manager.mojom.ServiceFactory", "ui.ozone.mojom.DeviceCursor", "ui.ozone.mojom.DrmDevice", - "ui.ozone.mojom.WaylandConnectionClient", "viz.mojom.CompositingModeReporter", "viz.mojom.VizMain" ],
diff --git a/content/public/test/android/BUILD.gn b/content/public/test/android/BUILD.gn index baaa804d..6e550af 100644 --- a/content/public/test/android/BUILD.gn +++ b/content/public/test/android/BUILD.gn
@@ -53,6 +53,7 @@ "javatests/src/org/chromium/content/browser/test/util/TestWebContentsObserver.java", "javatests/src/org/chromium/content/browser/test/util/TouchCommon.java", "javatests/src/org/chromium/content/browser/test/util/UiUtils.java", + "javatests/src/org/chromium/content/browser/test/util/WebContentsUtils.java", ] } @@ -62,19 +63,29 @@ sources = [ "javatests/src/org/chromium/content/browser/test/InterstitialPageDelegateAndroid.java", "javatests/src/org/chromium/content/browser/test/util/DOMUtils.java", + "javatests/src/org/chromium/content/browser/test/util/WebContentsUtils.java", ] } static_library("content_native_test_support") { testonly = true + + # See comment at the top of //content/BUILD.gn for why this is disabled in + # component builds. + if (is_component_build) { + check_includes = false + } + sources = [ "dom_utils.cc", "interstitial_page_delegate_android.cc", "interstitial_page_delegate_android.h", + "web_contents_utils.cc", ] deps = [ ":content_test_jni", "//base", + "//content/browser:for_content_tests", "//content/public/browser", "//device/gamepad", "//media/midi",
diff --git a/content/public/test/android/javatests/src/org/chromium/content/browser/test/util/WebContentsUtils.java b/content/public/test/android/javatests/src/org/chromium/content/browser/test/util/WebContentsUtils.java new file mode 100644 index 0000000..b81bc848 --- /dev/null +++ b/content/public/test/android/javatests/src/org/chromium/content/browser/test/util/WebContentsUtils.java
@@ -0,0 +1,27 @@ +// Copyright 2018 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. + +package org.chromium.content.browser.test.util; + +import org.chromium.base.annotations.JNINamespace; +import org.chromium.content_public.browser.WebContents; + +/** + * Collection of test-only WebContents utilities. + */ +@JNINamespace("content") +public class WebContentsUtils { + /** + * Reports all frame submissions to the browser process, even those that do not impact Browser + * UI. + * @param webContents The WebContents for which to report all frame submissions. + * @param enabled Whether to report all frame submissions. + */ + public static void reportAllFrameSubmissions(final WebContents webContents, boolean enabled) { + nativeReportAllFrameSubmissions(webContents, enabled); + } + + private static native void nativeReportAllFrameSubmissions( + WebContents webContents, boolean enabled); +}
diff --git a/content/public/test/android/web_contents_utils.cc b/content/public/test/android/web_contents_utils.cc new file mode 100644 index 0000000..a3dd16d --- /dev/null +++ b/content/public/test/android/web_contents_utils.cc
@@ -0,0 +1,31 @@ +// Copyright 2018 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 "base/android/jni_android.h" +#include "base/android/scoped_java_ref.h" +#include "content/browser/renderer_host/render_widget_host_impl.h" +#include "content/public/browser/render_frame_metadata_provider.h" +#include "content/public/browser/render_view_host.h" +#include "content/public/browser/web_contents.h" +#include "jni/WebContentsUtils_jni.h" + +using base::android::JavaParamRef; + +namespace content { + +// Reports all frame submissions to the browser process, even those that do not +// impact Browser UI. +void JNI_WebContentsUtils_ReportAllFrameSubmissions( + JNIEnv* env, + const JavaParamRef<jclass>& clazz, + const JavaParamRef<jobject>& jweb_contents, + jboolean enabled) { + WebContents* web_contents = WebContents::FromJavaWebContents(jweb_contents); + RenderFrameMetadataProvider* provider = + RenderWidgetHostImpl::From(web_contents->GetRenderViewHost()->GetWidget()) + ->render_frame_metadata_provider(); + provider->ReportAllFrameSubmissionsForTesting(enabled); +} + +} // namespace content
diff --git a/content/public/test/network_service_test_helper.cc b/content/public/test/network_service_test_helper.cc index 0f890e9..812c837 100644 --- a/content/public/test/network_service_test_helper.cc +++ b/content/public/test/network_service_test_helper.cc
@@ -26,6 +26,7 @@ #include "net/test/embedded_test_server/embedded_test_server.h" #include "net/test/spawned_test_server/spawned_test_server.h" #include "net/test/test_data_directory.h" +#include "services/network/host_resolver.h" #include "services/network/network_context.h" #include "services/network/network_service.h" #include "services/network/public/cpp/features.h" @@ -38,6 +39,13 @@ #endif namespace content { +namespace { +void CrashResolveHost(const std::string& host_to_crash, + const std::string& host) { + if (host_to_crash == host) + base::Process::TerminateCurrentProcessImmediately(1); +} +} // namespace class NetworkServiceTestHelper::NetworkServiceTestImpl : public network::mojom::NetworkServiceTest, @@ -125,6 +133,11 @@ std::move(callback).Run(); } + void CrashOnResolveHost(const std::string& host) override { + network::HostResolver::SetResolveHostCallbackForTesting( + base::BindRepeating(CrashResolveHost, host)); + } + void BindRequest(network::mojom::NetworkServiceTestRequest request) { bindings_.AddBinding(this, std::move(request)); if (!registered_as_destruction_observer_) {
diff --git a/content/renderer/media/gpu/gpu_video_accelerator_factories_impl.cc b/content/renderer/media/gpu/gpu_video_accelerator_factories_impl.cc index c787c1a3e..fa1ed7e3 100644 --- a/content/renderer/media/gpu/gpu_video_accelerator_factories_impl.cc +++ b/content/renderer/media/gpu/gpu_video_accelerator_factories_impl.cc
@@ -110,10 +110,8 @@ void GpuVideoAcceleratorFactoriesImpl::BindContextToTaskRunner() { DCHECK(task_runner_->BelongsToCurrentThread()); DCHECK(context_provider_); - if (context_provider_->BindToCurrentThread() != - gpu::ContextResult::kSuccess) { + if (context_provider_->BindToCurrentThread() != gpu::ContextResult::kSuccess) SetContextProviderLost(); - } } bool GpuVideoAcceleratorFactoriesImpl::CheckContextLost() { @@ -309,7 +307,8 @@ } media::GpuVideoAcceleratorFactories::OutputFormat -GpuVideoAcceleratorFactoriesImpl::VideoFrameOutputFormat(size_t bit_depth) { +GpuVideoAcceleratorFactoriesImpl::VideoFrameOutputFormat( + media::VideoPixelFormat pixel_format) { DCHECK(task_runner_->BelongsToCurrentThread()); if (CheckContextLost()) return media::GpuVideoAcceleratorFactories::OutputFormat::UNDEFINED; @@ -319,10 +318,12 @@ // any hardware acceleration here, so this was never an issue, but SwiftShader // revealed this issue. See https://crbug.com/859946 if (gpu_channel_host_->gpu_info().gl_renderer.find("SwiftShader") != - std::string::npos) + std::string::npos) { return media::GpuVideoAcceleratorFactories::OutputFormat::UNDEFINED; + } #endif auto capabilities = context_provider_->ContextCapabilities(); + const size_t bit_depth = media::BitDepth(pixel_format); if (bit_depth > 8) { // If high bit depth rendering is enabled, bail here, otherwise try and use // XR30 storage, and if not and we support RG textures, use those, albeit at
diff --git a/content/renderer/media/gpu/gpu_video_accelerator_factories_impl.h b/content/renderer/media/gpu/gpu_video_accelerator_factories_impl.h index 6a438e9..1320dc4 100644 --- a/content/renderer/media/gpu/gpu_video_accelerator_factories_impl.h +++ b/content/renderer/media/gpu/gpu_video_accelerator_factories_impl.h
@@ -90,7 +90,8 @@ bool ShouldUseGpuMemoryBuffersForVideoFrames( bool for_media_stream) const override; unsigned ImageTextureTarget(gfx::BufferFormat format) override; - OutputFormat VideoFrameOutputFormat(size_t bit_depth) override; + OutputFormat VideoFrameOutputFormat( + media::VideoPixelFormat pixel_format) override; // Called on the media thread. Returns the GLES2Interface unless the // ContextProvider has been lost, in which case it returns null.
diff --git a/content/shell/android/BUILD.gn b/content/shell/android/BUILD.gn index f71d26c..2033406 100644 --- a/content/shell/android/BUILD.gn +++ b/content/shell/android/BUILD.gn
@@ -79,6 +79,7 @@ "//base:base_java", "//components/embedder_support/android:content_view_java", "//components/embedder_support/android:view_java", + "//components/viz/service:service_java", "//content/public/android:content_java", "//media/base/android:media_java", "//media/capture/video/android:capture_java",
diff --git a/content/shell/android/javatests/src/org/chromium/content_shell_apk/ContentShellActivityTestRule.java b/content/shell/android/javatests/src/org/chromium/content_shell_apk/ContentShellActivityTestRule.java index 144ef04..47fc072 100644 --- a/content/shell/android/javatests/src/org/chromium/content_shell_apk/ContentShellActivityTestRule.java +++ b/content/shell/android/javatests/src/org/chromium/content_shell_apk/ContentShellActivityTestRule.java
@@ -28,6 +28,7 @@ import org.chromium.content.browser.test.util.Criteria; import org.chromium.content.browser.test.util.CriteriaHelper; import org.chromium.content.browser.test.util.TestCallbackHelperContainer; +import org.chromium.content.browser.test.util.WebContentsUtils; import org.chromium.content.browser.webcontents.WebContentsImpl; import org.chromium.content_public.browser.JavascriptInjector; import org.chromium.content_public.browser.LoadUrlParams; @@ -184,6 +185,15 @@ } } + /** + * Updates RenderCoordinates with all frame submissions, even those with no UI-visible change. + */ + public void reportAllFrameSubmissions(boolean enabled) { + final WebContents webContents = getWebContents(); + ThreadUtils.runOnUiThreadBlocking( + () -> { WebContentsUtils.reportAllFrameSubmissions(webContents, enabled); }); + } + public JavascriptInjector getJavascriptInjector() { return JavascriptInjector.fromWebContents(getWebContents()); }
diff --git a/content/shell/test_runner/pixel_dump.cc b/content/shell/test_runner/pixel_dump.cc index f5aeff05..c398c0645 100644 --- a/content/shell/test_runner/pixel_dump.cc +++ b/content/shell/test_runner/pixel_dump.cc
@@ -192,11 +192,9 @@ &sequence_number_before); web_frame->CopyImageAt(blink::WebPoint(x, y)); uint64_t sequence_number_after = 0; - clipboard->GetSequenceNumber(ui::CLIPBOARD_TYPE_COPY_PASTE, - &sequence_number_after); - if (sequence_number_before == sequence_number_after) { - std::move(callback).Run(SkBitmap()); - return; + while (sequence_number_before == sequence_number_after) { + clipboard->GetSequenceNumber(ui::CLIPBOARD_TYPE_COPY_PASTE, + &sequence_number_after); } SkBitmap bitmap;
diff --git a/content/test/data/accessibility/event/menulist-collapse-expected-win.txt b/content/test/data/accessibility/event/menulist-collapse-expected-win.txt index 811a31f0..29c89ff3 100644 --- a/content/test/data/accessibility/event/menulist-collapse-expected-win.txt +++ b/content/test/data/accessibility/event/menulist-collapse-expected-win.txt
@@ -1,2 +1,2 @@ -EVENT_OBJECT_STATECHANGE on <option> role=ROLE_SYSTEM_LISTITEM name="Apple" FOCUSED,INVISIBLE,FOCUSABLE,SELECTABLE 1 of 3 -EVENT_OBJECT_VALUECHANGE on <select> role=ROLE_SYSTEM_COMBOBOX COLLAPSED,FOCUSABLE,HASPOPUP \ No newline at end of file +EVENT_OBJECT_STATECHANGE on <option> role=ROLE_SYSTEM_LISTITEM name="Apple" INVISIBLE,FOCUSABLE,SELECTABLE 1 of 3 +EVENT_OBJECT_VALUECHANGE on <select> role=ROLE_SYSTEM_COMBOBOX FOCUSED,COLLAPSED,FOCUSABLE,HASPOPUP \ No newline at end of file
diff --git a/content/test/data/accessibility/event/menulist-collapse-next-expected-mac.txt b/content/test/data/accessibility/event/menulist-collapse-next-expected-mac.txt new file mode 100644 index 0000000..6f03e73c --- /dev/null +++ b/content/test/data/accessibility/event/menulist-collapse-next-expected-mac.txt
@@ -0,0 +1 @@ +AXValueChanged on AXPopUpButton AXValue="Orange"
diff --git a/content/test/data/accessibility/event/menulist-collapse-next-expected-win.txt b/content/test/data/accessibility/event/menulist-collapse-next-expected-win.txt new file mode 100644 index 0000000..7623a2f --- /dev/null +++ b/content/test/data/accessibility/event/menulist-collapse-next-expected-win.txt
@@ -0,0 +1,4 @@ +EVENT_OBJECT_SELECTION on <option> role=ROLE_SYSTEM_LISTITEM name="Orange" SELECTED,FOCUSABLE,SELECTABLE 2 of 3 +EVENT_OBJECT_STATECHANGE on <option> role=ROLE_SYSTEM_LISTITEM name="Apple" INVISIBLE,FOCUSABLE,SELECTABLE 1 of 3 +EVENT_OBJECT_STATECHANGE on <option> role=ROLE_SYSTEM_LISTITEM name="Orange" SELECTED,FOCUSABLE,SELECTABLE 2 of 3 +EVENT_OBJECT_VALUECHANGE on <select> role=ROLE_SYSTEM_COMBOBOX value="Orange" FOCUSED,COLLAPSED,FOCUSABLE,HASPOPUP \ No newline at end of file
diff --git a/content/test/data/accessibility/event/menulist-collapse-next.html b/content/test/data/accessibility/event/menulist-collapse-next.html new file mode 100644 index 0000000..0d985ed --- /dev/null +++ b/content/test/data/accessibility/event/menulist-collapse-next.html
@@ -0,0 +1,16 @@ +<!DOCTYPE html> +<html> +<body> +<select> + <option selected>Apple</option> + <option>Orange</option> + <option>Banana</option> +</select> +<script> + document.querySelector('select').focus(); + function go() { + document.querySelector('select').selectedIndex = 1; + } +</script> +</body> +</html>
diff --git a/content/test/data/accessibility/event/menulist-focus-expected-mac.txt b/content/test/data/accessibility/event/menulist-focus-expected-mac.txt index ed71f2f6..b1cdd1c 100644 --- a/content/test/data/accessibility/event/menulist-focus-expected-mac.txt +++ b/content/test/data/accessibility/event/menulist-focus-expected-mac.txt
@@ -1 +1 @@ -AXFocusedUIElementChanged on AXPopUpButton AXValue="Apple" \ No newline at end of file +AXFocusedUIElementChanged on AXPopUpButton AXValue="Apple"
diff --git a/content/test/data/accessibility/event/menulist-focus-expected-win.txt b/content/test/data/accessibility/event/menulist-focus-expected-win.txt index 094112d..b7ae895 100644 --- a/content/test/data/accessibility/event/menulist-focus-expected-win.txt +++ b/content/test/data/accessibility/event/menulist-focus-expected-win.txt
@@ -1 +1 @@ -EVENT_OBJECT_FOCUS on <select> role=ROLE_SYSTEM_COMBOBOX value="Apple" FOCUSED,COLLAPSED,FOCUSABLE,HASPOPUP \ No newline at end of file +EVENT_OBJECT_FOCUS on <select> role=ROLE_SYSTEM_COMBOBOX value="Apple" FOCUSED,COLLAPSED,FOCUSABLE,HASPOPUP
diff --git a/device/vr/oculus/oculus_device.cc b/device/vr/oculus/oculus_device.cc index 25cea45..6f55e66 100644 --- a/device/vr/oculus/oculus_device.cc +++ b/device/vr/oculus/oculus_device.cc
@@ -178,6 +178,8 @@ base::BindOnce(&OculusDevice::OnPresentingControllerMojoConnectionError, base::Unretained(this))); + session->display_info = display_info_.Clone(); + std::move(callback).Run(std::move(session), std::move(session_controller)); }
diff --git a/device/vr/oculus/oculus_device.h b/device/vr/oculus/oculus_device.h index d60ae9c..6449d9e 100644 --- a/device/vr/oculus/oculus_device.h +++ b/device/vr/oculus/oculus_device.h
@@ -55,7 +55,6 @@ void StopOvrSession(); std::unique_ptr<OculusRenderLoop> render_loop_; - mojom::VRDisplayInfoPtr display_info_; ovrSession session_ = nullptr; scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_;
diff --git a/device/vr/openvr/openvr_device.cc b/device/vr/openvr/openvr_device.cc index 28b5a88..08ddb345 100644 --- a/device/vr/openvr/openvr_device.cc +++ b/device/vr/openvr/openvr_device.cc
@@ -237,6 +237,8 @@ base::BindOnce(&OpenVRDevice::OnPresentingControllerMojoConnectionError, base::Unretained(this))); + session->display_info = display_info_.Clone(); + std::move(callback).Run(std::move(session), std::move(session_controller)); }
diff --git a/device/vr/openvr/openvr_device.h b/device/vr/openvr/openvr_device.h index 61a7e618..6a87388 100644 --- a/device/vr/openvr/openvr_device.h +++ b/device/vr/openvr/openvr_device.h
@@ -59,7 +59,6 @@ void OnPresentationEnded(); std::unique_ptr<OpenVRRenderLoop> render_loop_; - mojom::VRDisplayInfoPtr display_info_; std::unique_ptr<OpenVRWrapper> openvr_; scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_;
diff --git a/device/vr/public/mojom/isolated_xr_service.mojom b/device/vr/public/mojom/isolated_xr_service.mojom index 9666ddcd..035c4a16 100644 --- a/device/vr/public/mojom/isolated_xr_service.mojom +++ b/device/vr/public/mojom/isolated_xr_service.mojom
@@ -8,7 +8,7 @@ const string kVrIsolatedServiceName = "xr_device_service"; -// The XRSessionController lives in the vr device service, and corresponds to +// The XRSessionController lives in the xr runtime service, and corresponds to // a set of the XRSession bindings. The client is the browser process, which // will pause or stop sessions depending events/state such as focus or other // tabs requesting immersive sessions. @@ -20,7 +20,7 @@ SetFrameDataRestricted(bool restricted); }; -// The XRRuntimeEventListener lives in the vr device service, and allows the +// The XRRuntimeEventListener lives in the xr runtime service, and allows the // browser to listen to state changes about a device. interface XRRuntimeEventListener { // A device has changed its display information. @@ -110,7 +110,7 @@ // OpenVR and Oculus APIs can't run in the browser process, but the gamepad // polling happens there. This interface allows gamepad polling to request // data from out-of-process gamepad providers, at the cost of some extra IPC -// latency. IsolatedXRGamepadProvider is currently implemented in the XRDevice +// latency. IsolatedXRGamepadProvider is currently implemented in the XRRuntime // process, and consumed by the gamepad polling thread in the browser process. // It will move to live in a separate XRInput process in the future. interface IsolatedXRGamepadProvider { @@ -126,7 +126,7 @@ // data. IsolatedXRGamepadProviderFactory allows GamepadDataFetchers to acquire // new IsolatedXRGamepadProviders when needed. // IsolatedXRGamepadProvider is consumed in the browser process. It is -// currently implemented in the XRDevice process, but will move to a separate +// currently implemented in the XRRuntime process, but will move to a separate // XRInput process. interface IsolatedXRGamepadProviderFactory { // Get the IsolatedXRGamepadProvider for a specific XR runtime API (Oculus, or
diff --git a/device/vr/public/mojom/vr_service.mojom b/device/vr/public/mojom/vr_service.mojom index 21786c06..8dda10d 100644 --- a/device/vr/public/mojom/vr_service.mojom +++ b/device/vr/public/mojom/vr_service.mojom
@@ -60,8 +60,18 @@ // apropriate based on the session creation options. (for example, an immersive // session ought to have a XRPresentationConnection to submit the frames to the // immersive enviroment). +// The XRSessionClient request must be fulfilled for the session to get +// information about the device it is connected to, such as focus and blur +// events, changes to view or stage parameters, or exit present calls initiated +// by the device. struct XRSession { XRFrameDataProvider data_provider; + // TODO(http://crbug.com/842025) Move where the client_request gets set to the + // device process then mark this as non-optional. + XRSessionClient&? client_request; + // TODO(http://crbug.com/842025) Move the information that is sent in display + // info to more sensible places so that this doesn't need to be sent here. + VRDisplayInfo display_info; XRPresentationConnection? submit_frame_sink; XREnviromentIntegrationProvider? enviroment_provider; }; @@ -251,35 +261,45 @@ UNMOUNTED = 3 }; -// TODO(shaobo.yan@intel.com) : Add comments to describe these interfaces about -// how to use and where they live. +// Interface for requesting XRDevice interfaces and registering for +// notifications that the XRDevice has changed interface VRService { - // TODO(shaobo.yan@intel.com, https://crbug.com/701027): Use a factory - // function which takes a VRServiceClient so we will never have a - // half-initialized VRService. - SetClient(VRServiceClient client) => (); - // Inform the service that the page is listening for vrdisplayactivate events. - // TODO(mthiesse): Move SetListeningForActivate onto VRDisplay. - SetListeningForActivate(bool listening); + // Returns the XRDevice interface which is used for creating XRSessions. This + // is not expected to be called once per renderer, unless the returned + // XRDevice is destroyed, then it might be called again to get another one. + RequestDevice() => (XRDevice? device); + // Optionally supply a VRServiceClient to listen for changes to the XRDevice. + // The last provided listener will have events called on it. + SetClient(VRServiceClient client); + + // WebVR 1.1 functionality compatibility method. To stop listening pass a null + // client. + SetListeningForActivate(VRDisplayClient? client); }; +// The interface for the renderer to listen to top level XR events, events that +// can be listened to and triggered without the renderer calling requestDevice. interface VRServiceClient { - OnDisplayConnected(XRDevice device, VRDisplayClient& request, - VRDisplayInfo display_info); + // Signals changes to the available physical device runtimes. + OnDeviceChanged(); }; -// Provides a communication channel from the renderer to the browser-side host -// of a (device/) VrDisplayImpl. +// Supplies XRSessions and session support information. Implemented in the +// browser process, consumed in the renderer process. interface XRDevice { - // Request to initialize a session in the browser process. The return value - // indicates if the session was successfully initialized or not. - // TODO(https://crbug.com/842025): Refactor VR device interfaces to better - // reflect WebXR. + // Request to initialize a session in the browser process. If successful, the + // XRSession struct with the requisite interfaces will be returned. RequestSession( XRSessionOptions options, bool triggered_by_displayactive) => (XRSession? session); SupportsSession(XRSessionOptions options) => (bool supports_session); + // WebVR 1.1 functionality compatibility method. Returns VRDisplayInfo for an + // immersive session if immersive is supported. If (and only if) immersive is + // not supported, will return a nullptr. This call might cause device specific + // UI to appear. + GetImmersiveVRDisplayInfo() => (VRDisplayInfo? info); + ExitPresent(); }; @@ -381,11 +401,22 @@ OnSubmitFrameGpuFence(gfx.mojom.GpuFenceHandle gpu_fence_handle); }; -interface VRDisplayClient { +// Functions for pushing device information to the sessions. +interface XRSessionClient { OnChanged(VRDisplayInfo display); OnExitPresent(); OnBlur(); OnFocus(); +}; + +// Backwards compatibility events for WebVR 1.1. These are expected to not be +// used for WebXR. +interface VRDisplayClient { + // Inform the renderer that a headset has sent a signal indicating that the + // user has put it on. Returns an indicator of whether or not the page + // actually started a WebVR 1.1 presentation. OnActivate(VRDisplayEventReason reason) => (bool will_not_present); + // Inform the renderer that a headset has sent a signal indicating that the + // user stopped using a headset. OnDeactivate(VRDisplayEventReason reason); };
diff --git a/device/vr/test/fake_vr_display_impl_client.h b/device/vr/test/fake_vr_display_impl_client.h index 2fb565c..818bafd 100644 --- a/device/vr/test/fake_vr_display_impl_client.h +++ b/device/vr/test/fake_vr_display_impl_client.h
@@ -12,16 +12,19 @@ namespace device { class FakeVRServiceClient; -class FakeVRDisplayImplClient : public mojom::VRDisplayClient { +class FakeVRDisplayImplClient : public mojom::VRDisplayClient, + public mojom::XRSessionClient { public: FakeVRDisplayImplClient(mojom::VRDisplayClientRequest request); ~FakeVRDisplayImplClient() override; void SetServiceClient(FakeVRServiceClient* service_client); + // mojom::XRSessionClient overrides void OnChanged(mojom::VRDisplayInfoPtr display) override; void OnExitPresent() override {} void OnBlur() override {} void OnFocus() override {} + // mojom::VRDisplayClient overrides void OnActivate(mojom::VRDisplayEventReason reason, OnActivateCallback callback) override {} void OnDeactivate(mojom::VRDisplayEventReason reason) override {}
diff --git a/device/vr/test/fake_vr_service_client.cc b/device/vr/test/fake_vr_service_client.cc index 0fcb1dd..e5a45ac 100644 --- a/device/vr/test/fake_vr_service_client.cc +++ b/device/vr/test/fake_vr_service_client.cc
@@ -12,18 +12,6 @@ FakeVRServiceClient::~FakeVRServiceClient() {} -void FakeVRServiceClient::OnDisplayConnected( - mojom::XRDevicePtr device, - mojom::VRDisplayClientRequest request, - mojom::VRDisplayInfoPtr displayInfo) { - displays_.push_back(std::move(displayInfo)); - auto display_client = - std::make_unique<FakeVRDisplayImplClient>(std::move(request)); - display_client->SetServiceClient(this); - - display_clients_.push_back(std::move(display_client)); -} - void FakeVRServiceClient::SetLastDeviceId(mojom::XRDeviceId id) { last_device_id_ = id; }
diff --git a/device/vr/test/fake_vr_service_client.h b/device/vr/test/fake_vr_service_client.h index c0905ee..e7ee410c 100644 --- a/device/vr/test/fake_vr_service_client.h +++ b/device/vr/test/fake_vr_service_client.h
@@ -19,9 +19,7 @@ FakeVRServiceClient(mojom::VRServiceClientRequest request); ~FakeVRServiceClient() override; - void OnDisplayConnected(mojom::XRDevicePtr device, - mojom::VRDisplayClientRequest request, - mojom::VRDisplayInfoPtr displayInfo) override; + void OnDeviceChanged() override{}; void SetLastDeviceId(mojom::XRDeviceId id); bool CheckDeviceId(mojom::XRDeviceId id);
diff --git a/device/vr/vr_device_base.cc b/device/vr/vr_device_base.cc index 87e4b8e..14cce08 100644 --- a/device/vr/vr_device_base.cc +++ b/device/vr/vr_device_base.cc
@@ -124,6 +124,9 @@ // TODO(offenwanger) Not all session will want the enviroment provider. This // should be refactored so it's only passed when it's requested. session->enviroment_provider = enviroment_provider.PassInterface(); + if (display_info_) { + session->display_info = display_info_.Clone(); + } std::move(callback).Run(std::move(session), std::move(controller)); }
diff --git a/device/vr/vr_device_base.h b/device/vr/vr_device_base.h index 93ec057..b6bac22 100644 --- a/device/vr/vr_device_base.h +++ b/device/vr/vr_device_base.h
@@ -77,6 +77,7 @@ void ReturnNonImmersiveSession( mojom::XRRuntime::RequestSessionCallback callback); + mojom::VRDisplayInfoPtr display_info_; std::vector<std::unique_ptr<VRDisplayImpl>> magic_window_sessions_; private: @@ -87,8 +88,6 @@ mojom::XRRuntimeEventListenerPtr listener_; - mojom::VRDisplayInfoPtr display_info_; - bool presenting_ = false; device::mojom::XRDeviceId id_;
diff --git a/docs/speed/diagnostic_metrics.md b/docs/speed/diagnostic_metrics.md index 47d3043..f1d9d13 100644 --- a/docs/speed/diagnostic_metrics.md +++ b/docs/speed/diagnostic_metrics.md
@@ -59,8 +59,6 @@ Some diagnostic metrics correlate with the higher level metric, but aren’t related in any precise way. For example, the top level FMP metric measures wall clock time. We could add a CPU time equivalent as a diagnostic metric, which is likely to have lower noise. In cases like this, we expect there to exist some monotonic function which approximately maps from the top level metric to the diagnostic metric, but this relationship could be quite rough. -Slicing diagnostics are implemented in telemetry via [Related Histogram Maps](https://cs.chromium.org/chromium/src/third_party/catapult/tracing/tracing/value/diagnostics/related_histogram_map.html?q=RelatedHistogramMap&sq=package:chromium&l=16). - ## Composing Diagnostics Many metrics will have multiple sets of diagnostics. For example, this set of FMP diagnostics involves Slicing, Summation, and Proxy Diagnostics.
diff --git a/google_apis/gcm/tools/mcs_probe.cc b/google_apis/gcm/tools/mcs_probe.cc index 26800cf..1f9a4a7 100644 --- a/google_apis/gcm/tools/mcs_probe.cc +++ b/google_apis/gcm/tools/mcs_probe.cc
@@ -152,6 +152,7 @@ const net::NetLogWithSource& net_log) override { return net::OK; } + void SetConfig(const Config& config) override {} }; class MCSProbeAuthPreferences : public net::HttpAuthPreferences {
diff --git a/ios/chrome/app/strings/ios_strings.grd b/ios/chrome/app/strings/ios_strings.grd index 8cf2fc1..9193f5a 100644 --- a/ios/chrome/app/strings/ios_strings.grd +++ b/ios/chrome/app/strings/ios_strings.grd
@@ -1641,10 +1641,10 @@ No Open Tabs </message> <message name="IDS_IOS_TAB_GRID_INCOGNITO_TABS_EMPTY_STATE_BODY" desc="Text body shown in the Incognito Tabs page when the grid is empty, explaining that the user can open a new tab. [iOS only]"> - Open a tab to browse the web privately. + To browse the web privately, add a new tab. </message> <message name="IDS_IOS_TAB_GRID_REGULAR_TABS_EMPTY_STATE_BODY" desc="Text body shown in the Regular Tabs page (as opposed to the Incognito Tabs page) when the grid is empty, explaining that the user can open a new tab. [iOS only]"> - Open a tab to browse the web. + To browse the web, add a new tab. </message> <message name="IDS_IOS_TAB_GRID_CREATE_NEW_INCOGNITO_TAB" desc="The accessibility label for the button that creates new incognito tabs. [iOS only]"> Create new incognito tab.
diff --git a/ios/chrome/browser/about_flags.mm b/ios/chrome/browser/about_flags.mm index 8ccbe65..28413c5 100644 --- a/ios/chrome/browser/about_flags.mm +++ b/ios/chrome/browser/about_flags.mm
@@ -166,9 +166,6 @@ {"web-payments-native-apps", flag_descriptions::kWebPaymentsNativeAppsName, flag_descriptions::kWebPaymentsNativeAppsDescription, flags_ui::kOsIos, FEATURE_VALUE_TYPE(payments::features::kWebPaymentsNativeApps)}, - {"ios-captive-portal", flag_descriptions::kCaptivePortalName, - flag_descriptions::kCaptivePortalDescription, flags_ui::kOsIos, - FEATURE_VALUE_TYPE(kCaptivePortalFeature)}, {"ios-captive-portal-metrics", flag_descriptions::kCaptivePortalMetricsName, flag_descriptions::kCaptivePortalMetricsDescription, flags_ui::kOsIos, FEATURE_VALUE_TYPE(kCaptivePortalMetrics)}, @@ -351,6 +348,10 @@ flag_descriptions::kAutofillCacheQueryResponsesDescription, flags_ui::kOsIos, FEATURE_VALUE_TYPE(autofill::features::kAutofillCacheQueryResponses)}, + {"autofill-enable-company-name", + flag_descriptions::kAutofillEnableCompanyNameName, + flag_descriptions::kAutofillEnableCompanyNameDescription, flags_ui::kOsIos, + FEATURE_VALUE_TYPE(autofill::features::kAutofillEnableCompanyName)}, {"autofill-manual-fallback", flag_descriptions::kAutofillManualFallbackName, flag_descriptions::kAutofillManualFallbackDescription, flags_ui::kOsIos, FEATURE_VALUE_TYPE(autofill::features::kAutofillManualFallback)},
diff --git a/ios/chrome/browser/find_in_page/find_tab_helper.h b/ios/chrome/browser/find_in_page/find_tab_helper.h index 839d2db..4c8aa98 100644 --- a/ios/chrome/browser/find_in_page/find_tab_helper.h +++ b/ios/chrome/browser/find_in_page/find_tab_helper.h
@@ -17,6 +17,11 @@ typedef void (^FindInPageCompletionBlock)(FindInPageModel*); +// Names for Find In Page UMA actions (Find, FindNext, FindPrevious). +extern const char kFindActionName[]; +extern const char kFindNextActionName[]; +extern const char kFindPreviousActionName[]; + // Adds support for the "Find in page" feature. class FindTabHelper : public web::WebStateObserver, public web::WebStateUserData<FindTabHelper> {
diff --git a/ios/chrome/browser/find_in_page/find_tab_helper.mm b/ios/chrome/browser/find_in_page/find_tab_helper.mm index dae0cc87e..0732b065 100644 --- a/ios/chrome/browser/find_in_page/find_tab_helper.mm +++ b/ios/chrome/browser/find_in_page/find_tab_helper.mm
@@ -5,6 +5,8 @@ #import "ios/chrome/browser/find_in_page/find_tab_helper.h" #include "base/memory/ptr_util.h" +#include "base/metrics/user_metrics.h" +#include "base/metrics/user_metrics_action.h" #import "ios/chrome/browser/find_in_page/find_in_page_controller.h" #import "ios/chrome/browser/find_in_page/find_in_page_model.h" @@ -12,6 +14,10 @@ #error "This file requires ARC support." #endif +const char kFindActionName[] = "Find"; +const char kFindNextActionName[] = "FindNext"; +const char kFindPreviousActionName[] = "FindPrevious"; + DEFINE_WEB_STATE_USER_DATA_KEY(FindTabHelper); FindTabHelper::FindTabHelper(web::WebState* web_state) { @@ -23,6 +29,7 @@ void FindTabHelper::StartFinding(NSString* search_term, FindInPageCompletionBlock completion) { + base::RecordAction(base::UserMetricsAction(kFindActionName)); [controller_ findStringInPage:search_term completionHandler:^{ FindInPageModel* model = controller_.findInPageModel; @@ -35,11 +42,13 @@ FindInPageModel* model = controller_.findInPageModel; if (direction == FORWARD) { + base::RecordAction(base::UserMetricsAction(kFindNextActionName)); [controller_ findNextStringInPageWithCompletionHandler:^{ completion(model); }]; } else if (direction == REVERSE) { + base::RecordAction(base::UserMetricsAction(kFindPreviousActionName)); [controller_ findPreviousStringInPageWithCompletionHandler:^{ completion(model); }];
diff --git a/ios/chrome/browser/find_in_page/find_tab_helper_unittest.mm b/ios/chrome/browser/find_in_page/find_tab_helper_unittest.mm index 811c13d..cd61085b 100644 --- a/ios/chrome/browser/find_in_page/find_tab_helper_unittest.mm +++ b/ios/chrome/browser/find_in_page/find_tab_helper_unittest.mm
@@ -7,6 +7,7 @@ #include "base/macros.h" #include "base/run_loop.h" #import "base/test/ios/wait_util.h" +#include "base/test/metrics/user_action_tester.h" #import "ios/chrome/browser/find_in_page/find_in_page_model.h" #import "ios/chrome/browser/web/chrome_web_test.h" #import "ios/web/public/test/fakes/test_web_state.h" @@ -59,6 +60,8 @@ LoadHtml(html); } + base::UserActionTester user_action_tester_; + private: DISALLOW_COPY_AND_ASSIGN(FindTabHelperTest); }; @@ -81,21 +84,25 @@ }; // Search for "Test string" and verify that there are five matches. + ASSERT_EQ(0, user_action_tester_.GetActionCount(kFindActionName)); helper->StartFinding(@"Test string", ^(FindInPageModel* model) { EXPECT_EQ(5U, model.matches); EXPECT_EQ(1U, model.currentIndex); completion_handler_block_was_called = YES; }); base::test::ios::WaitUntilCondition(wait_block); + EXPECT_EQ(1, user_action_tester_.GetActionCount(kFindActionName)); // Search forward in the page for additional matches and verify that // |currentIndex| is updated. + ASSERT_EQ(0, user_action_tester_.GetActionCount(kFindNextActionName)); helper->ContinueFinding(FindTabHelper::FORWARD, ^(FindInPageModel* model) { EXPECT_EQ(5U, model.matches); EXPECT_EQ(2U, model.currentIndex); completion_handler_block_was_called = YES; }); base::test::ios::WaitUntilCondition(wait_block); + EXPECT_EQ(1, user_action_tester_.GetActionCount(kFindNextActionName)); helper->ContinueFinding(FindTabHelper::FORWARD, ^(FindInPageModel* model) { EXPECT_EQ(5U, model.matches); @@ -103,15 +110,18 @@ completion_handler_block_was_called = YES; }); base::test::ios::WaitUntilCondition(wait_block); + EXPECT_EQ(2, user_action_tester_.GetActionCount(kFindNextActionName)); // Search backwards in the page for previous matches and verify that // |currentIndex| is updated. + ASSERT_EQ(0, user_action_tester_.GetActionCount(kFindPreviousActionName)); helper->ContinueFinding(FindTabHelper::REVERSE, ^(FindInPageModel* model) { EXPECT_EQ(5U, model.matches); EXPECT_EQ(2U, model.currentIndex); completion_handler_block_was_called = YES; }); base::test::ios::WaitUntilCondition(wait_block); + EXPECT_EQ(1, user_action_tester_.GetActionCount(kFindPreviousActionName)); // Stop finding and verify that the completion block was called properly. helper->StopFinding(^{ @@ -138,30 +148,36 @@ }; // Search for "Test string". + ASSERT_EQ(0, user_action_tester_.GetActionCount(kFindActionName)); helper->StartFinding(@"Test string", ^(FindInPageModel* model) { EXPECT_EQ(2U, model.matches); EXPECT_EQ(1U, model.currentIndex); completion_handler_block_was_called = YES; }); base::test::ios::WaitUntilCondition(wait_block); + EXPECT_EQ(1, user_action_tester_.GetActionCount(kFindActionName)); // Search backwards in the page and verify that |currentIndex| wraps around to // the last match. + ASSERT_EQ(0, user_action_tester_.GetActionCount(kFindPreviousActionName)); helper->ContinueFinding(FindTabHelper::REVERSE, ^(FindInPageModel* model) { EXPECT_EQ(2U, model.matches); EXPECT_EQ(2U, model.currentIndex); completion_handler_block_was_called = YES; }); base::test::ios::WaitUntilCondition(wait_block); + EXPECT_EQ(1, user_action_tester_.GetActionCount(kFindPreviousActionName)); // Search forward in the page and verify that |currentIndex| wraps around to // the first match. + ASSERT_EQ(0, user_action_tester_.GetActionCount(kFindNextActionName)); helper->ContinueFinding(FindTabHelper::FORWARD, ^(FindInPageModel* model) { EXPECT_EQ(2U, model.matches); EXPECT_EQ(1U, model.currentIndex); completion_handler_block_was_called = YES; }); base::test::ios::WaitUntilCondition(wait_block); + EXPECT_EQ(1, user_action_tester_.GetActionCount(kFindNextActionName)); } // Tests that the FindInPageModel returned by GetFindResults() is updated to @@ -183,10 +199,12 @@ }; // Search for "Test string". + ASSERT_EQ(0, user_action_tester_.GetActionCount(kFindActionName)); helper->StartFinding(@"Test string", ^(FindInPageModel* model) { completion_handler_block_was_called = YES; }); base::test::ios::WaitUntilCondition(wait_block); + EXPECT_EQ(1, user_action_tester_.GetActionCount(kFindActionName)); { FindInPageModel* model = helper->GetFindResult(); EXPECT_EQ(2U, model.matches); @@ -195,10 +213,12 @@ // Search forward in the page and verify that |currentIndex| wraps around to // the first match. + ASSERT_EQ(0, user_action_tester_.GetActionCount(kFindNextActionName)); helper->ContinueFinding(FindTabHelper::FORWARD, ^(FindInPageModel* model) { completion_handler_block_was_called = YES; }); base::test::ios::WaitUntilCondition(wait_block); + EXPECT_EQ(1, user_action_tester_.GetActionCount(kFindNextActionName)); { FindInPageModel* model = helper->GetFindResult(); EXPECT_EQ(2U, model.matches);
diff --git a/ios/chrome/browser/ios_chrome_flag_descriptions.cc b/ios/chrome/browser/ios_chrome_flag_descriptions.cc index 7280142..363a99f1 100644 --- a/ios/chrome/browser/ios_chrome_flag_descriptions.cc +++ b/ios/chrome/browser/ios_chrome_flag_descriptions.cc
@@ -17,6 +17,11 @@ "When enabled, autofill will cache the responses it receives from the " "crowd-sourced field type prediction server."; +const char kAutofillEnableCompanyNameName[] = + "Enable Autofill Company Name field"; +const char kAutofillEnableCompanyNameDescription[] = + "When enabled, Company Name fields will be auto filled"; + const char kAutofillCreditCardUploadName[] = "Offers uploading Autofilled credit cards"; const char kAutofillCreditCardUploadDescription[] = @@ -111,11 +116,6 @@ const char kBrowserTaskSchedulerDescription[] = "Enables redirection of some task posting APIs to the task scheduler."; -const char kCaptivePortalName[] = "Captive Portal"; -const char kCaptivePortalDescription[] = - "When enabled, the Captive Portal landing page will be displayed if it is " - "detected that the user is connected to a Captive Portal network."; - const char kCaptivePortalMetricsName[] = "Captive Portal Metrics"; const char kCaptivePortalMetricsDescription[] = "When enabled, some network issues will trigger a test to check if a "
diff --git a/ios/chrome/browser/ios_chrome_flag_descriptions.h b/ios/chrome/browser/ios_chrome_flag_descriptions.h index 2c1ce33..186edab2 100644 --- a/ios/chrome/browser/ios_chrome_flag_descriptions.h +++ b/ios/chrome/browser/ios_chrome_flag_descriptions.h
@@ -11,6 +11,10 @@ extern const char kAutofillCacheQueryResponsesName[]; extern const char kAutofillCacheQueryResponsesDescription[]; +// Title and description for the flag to control deprecating company name. +extern const char kAutofillEnableCompanyNameName[]; +extern const char kAutofillEnableCompanyNameDescription[]; + // Title and description for the flag to control upstreaming credit cards. extern const char kAutofillCreditCardUploadName[]; extern const char kAutofillCreditCardUploadDescription[]; @@ -88,10 +92,6 @@ extern const char kBrowserTaskScheduler[]; extern const char kBrowserTaskSchedulerDescription[]; -// Title and description for the flag to enable Captive Portal Login. -extern const char kCaptivePortalName[]; -extern const char kCaptivePortalDescription[]; - // Title and description for the flag to enable Captive Portal metrics logging. extern const char kCaptivePortalMetricsName[]; extern const char kCaptivePortalMetricsDescription[];
diff --git a/ios/chrome/browser/ssl/captive_portal_features.cc b/ios/chrome/browser/ssl/captive_portal_features.cc index 7c50019..e9209ef6 100644 --- a/ios/chrome/browser/ssl/captive_portal_features.cc +++ b/ios/chrome/browser/ssl/captive_portal_features.cc
@@ -4,8 +4,5 @@ #include "ios/chrome/browser/ssl/captive_portal_features.h" -const base::Feature kCaptivePortalFeature{"CaptivePortalFeature", - base::FEATURE_ENABLED_BY_DEFAULT}; - const base::Feature kCaptivePortalMetrics{"CaptivePortalMetrics", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/ios/chrome/browser/ssl/captive_portal_features.h b/ios/chrome/browser/ssl/captive_portal_features.h index 0466eb5..ca06f80a 100644 --- a/ios/chrome/browser/ssl/captive_portal_features.h +++ b/ios/chrome/browser/ssl/captive_portal_features.h
@@ -7,9 +7,6 @@ #include "base/feature_list.h" -// Used to control the state of the Captive Portal Login feature. -extern const base::Feature kCaptivePortalFeature; - // Used to control the state of logging Captive Portal Metrics. extern const base::Feature kCaptivePortalMetrics;
diff --git a/ios/chrome/browser/ssl/ios_ssl_error_handler.h b/ios/chrome/browser/ssl/ios_ssl_error_handler.h index 83b8fa9..245a6d7 100644 --- a/ios/chrome/browser/ssl/ios_ssl_error_handler.h +++ b/ios/chrome/browser/ssl/ios_ssl_error_handler.h
@@ -66,9 +66,6 @@ // Displays a Captive Portal interstitial. The |landing_url| is the web page // which allows the user to complete their connection to the network. void ShowCaptivePortalInterstitial(const GURL& landing_url); - // Detects the current Captive Portal state and records the result with - // |LogCaptivePortalResult|. - static void RecordCaptivePortalState(web::WebState* web_state); // Records a metric to classify if SSL errors are due to a Captive Portal // state. static void LogCaptivePortalResult(
diff --git a/ios/chrome/browser/ssl/ios_ssl_error_handler.mm b/ios/chrome/browser/ssl/ios_ssl_error_handler.mm index b799d5b..3a40f8f2 100644 --- a/ios/chrome/browser/ssl/ios_ssl_error_handler.mm +++ b/ios/chrome/browser/ssl/ios_ssl_error_handler.mm
@@ -71,14 +71,6 @@ weak_factory_(this) {} void IOSSSLErrorHandler::StartHandlingError() { - if (!base::FeatureList::IsEnabled(kCaptivePortalFeature)) { - IOSSSLErrorHandler::RecordCaptivePortalState(web_state_); - - // Display an SSL interstitial. - ShowSSLInterstitial(); - return; - } - CaptivePortalDetectorTabHelper* tab_helper = CaptivePortalDetectorTabHelper::FromWebState(web_state_); // TODO(crbug.com/760873): replace test with DCHECK when this method is only @@ -152,24 +144,6 @@ } // static -void IOSSSLErrorHandler::RecordCaptivePortalState(web::WebState* web_state) { - CaptivePortalDetectorTabHelper* tab_helper = - CaptivePortalDetectorTabHelper::FromWebState(web_state); - - // TODO(crbug.com/760873): replace test with DCHECK when this method is only - // called on WebStates attached to tabs. - if (!tab_helper) { - return; - } - tab_helper->detector()->DetectCaptivePortal( - GURL(CaptivePortalDetector::kDefaultURL), - base::BindRepeating(^(const CaptivePortalDetector::Results& results) { - IOSSSLErrorHandler::LogCaptivePortalResult(results.result); - }), - NO_TRAFFIC_ANNOTATION_YET); -} - -// static void IOSSSLErrorHandler::LogCaptivePortalResult( captive_portal::CaptivePortalResult result) { CaptivePortalStatus status;
diff --git a/ios/chrome/browser/ssl/ios_ssl_error_handler_unittest.mm b/ios/chrome/browser/ssl/ios_ssl_error_handler_unittest.mm index 76aa811..fffd333 100644 --- a/ios/chrome/browser/ssl/ios_ssl_error_handler_unittest.mm +++ b/ios/chrome/browser/ssl/ios_ssl_error_handler_unittest.mm
@@ -5,13 +5,14 @@ #include "ios/chrome/browser/ssl/ios_ssl_error_handler.h" #include "base/bind.h" -#include "base/test/scoped_feature_list.h" +#include "base/run_loop.h" +#import "base/test/ios/wait_util.h" #include "ios/chrome/browser/browser_state/test_chrome_browser_state.h" #import "ios/chrome/browser/ssl/captive_portal_detector_tab_helper.h" -#include "ios/chrome/browser/ssl/captive_portal_features.h" #include "ios/web/public/interstitials/web_interstitial.h" #import "ios/web/public/test/web_test_with_web_state.h" #import "ios/web/public/web_state/web_state.h" +#include "net/http/http_status_code.h" #include "net/ssl/ssl_info.h" #include "net/test/cert_test_util.h" #include "net/test/test_data_directory.h" @@ -22,6 +23,9 @@ #error "This file requires ARC support." #endif +using base::test::ios::kWaitForUIElementTimeout; +using base::test::ios::WaitUntilConditionOrTimeout; + namespace { const char kTestCertFileName[] = "ok_cert.pem"; const char kTestHostName[] = "https://chromium.test/"; @@ -38,6 +42,10 @@ // web::WebTestWithWebState overrides: void SetUp() override { web::WebTestWithWebState::SetUp(); + + test_loader_factory_.AddResponse("http://www.gstatic.com/generate_204", "", + net::HTTP_NO_CONTENT); + id captive_portal_detector_tab_helper_delegate = [OCMockObject mockForProtocol:@protocol(CaptivePortalDetectorTabHelperDelegate)]; // Use a testing URLLoaderFactory so that these tests don't attempt to make @@ -54,6 +62,19 @@ } web::BrowserState* GetBrowserState() override { return browser_state_.get(); } + // Waits for and returns true if an interstitial is displayed. Returns false + // otherwise. + WARN_UNUSED_RESULT bool WaitForInterstitialDisplayed() { + // Required in order for CaptivePortalDetector to receive simulated network + // response from |test_loader_factory_|. + base::RunLoop().RunUntilIdle(); + + // Wait for the interstitial to be displayed. + return WaitUntilConditionOrTimeout(kWaitForUIElementTimeout, ^{ + return web_state()->IsShowingWebInterstitial(); + }); + } + // Returns certificate for testing. scoped_refptr<net::X509Certificate> cert() { return cert_; } @@ -66,9 +87,6 @@ // Tests non-overridable error handling. TEST_F(IOSSSLErrorHandlerTest, NonOverridable) { - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitAndDisableFeature(kCaptivePortalFeature); - net::SSLInfo ssl_info; ssl_info.cert = cert(); GURL url(kTestHostName); @@ -80,8 +98,7 @@ do_not_proceed_callback_called = true; })); - // Make sure that interstitial is displayed. - EXPECT_TRUE(web_state()->IsShowingWebInterstitial()); + EXPECT_TRUE(WaitForInterstitialDisplayed()); web::WebInterstitial* interstitial = web_state()->GetWebInterstitial(); EXPECT_TRUE(interstitial); @@ -93,9 +110,6 @@ // Tests proceed with overridable error. // Flaky: http://crbug.com/660343. TEST_F(IOSSSLErrorHandlerTest, DISABLED_OverridableProceed) { - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitAndDisableFeature(kCaptivePortalFeature); - net::SSLInfo ssl_info; ssl_info.cert = cert(); GURL url(kTestHostName); @@ -107,8 +121,7 @@ proceed_callback_called = true; })); - // Make sure that interstitial is displayed. - EXPECT_TRUE(web_state()->IsShowingWebInterstitial()); + EXPECT_TRUE(WaitForInterstitialDisplayed()); web::WebInterstitial* interstitial = web_state()->GetWebInterstitial(); EXPECT_TRUE(interstitial); @@ -119,9 +132,6 @@ // Tests do not proceed with overridable error. TEST_F(IOSSSLErrorHandlerTest, OverridableDontProceed) { - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitAndDisableFeature(kCaptivePortalFeature); - net::SSLInfo ssl_info; ssl_info.cert = cert(); GURL url(kTestHostName); @@ -133,8 +143,7 @@ do_not_proceed_callback_called = true; })); - // Make sure that interstitial is displayed. - EXPECT_TRUE(web_state()->IsShowingWebInterstitial()); + EXPECT_TRUE(WaitForInterstitialDisplayed()); web::WebInterstitial* interstitial = web_state()->GetWebInterstitial(); EXPECT_TRUE(interstitial);
diff --git a/ios/chrome/browser/ui/tab_grid/BUILD.gn b/ios/chrome/browser/ui/tab_grid/BUILD.gn index f8996cb..7444676 100644 --- a/ios/chrome/browser/ui/tab_grid/BUILD.gn +++ b/ios/chrome/browser/ui/tab_grid/BUILD.gn
@@ -133,6 +133,7 @@ "//base/test:test_support", "//ios/chrome/app/strings", "//ios/chrome/browser/ui:ui_util", + "//ios/chrome/browser/ui/ntp/recent_tabs", "//ios/chrome/browser/ui/tools_menu/public", "//ios/chrome/test/app:test_support", "//ios/chrome/test/earl_grey:test_support", @@ -150,7 +151,9 @@ deps = [ ":egtest_support", + "//ios/chrome/browser/ui/tab_grid:tab_grid_ui", "//ios/chrome/test/earl_grey:test_support", + "//ios/web/public/test/http_server", ] libs = [ "XCTest.framework" ] }
diff --git a/ios/chrome/browser/ui/tab_grid/tab_grid_constants.h b/ios/chrome/browser/ui/tab_grid/tab_grid_constants.h index 5071e6da..24d6b7f 100644 --- a/ios/chrome/browser/ui/tab_grid/tab_grid_constants.h +++ b/ios/chrome/browser/ui/tab_grid/tab_grid_constants.h
@@ -16,6 +16,7 @@ extern NSString* const kTabGridUndoCloseAllButtonIdentifier; extern NSString* const kTabGridIncognitoTabsEmptyStateIdentifier; extern NSString* const kTabGridRegularTabsEmptyStateIdentifier; +extern NSString* const kTabGridScrollViewIdentifier; // All kxxxColor constants are RGB values stored in a Hex integer. These will be // converted into UIColors using the UIColorFromRGB() function, from
diff --git a/ios/chrome/browser/ui/tab_grid/tab_grid_constants.mm b/ios/chrome/browser/ui/tab_grid/tab_grid_constants.mm index 7657b97..6059f423 100644 --- a/ios/chrome/browser/ui/tab_grid/tab_grid_constants.mm +++ b/ios/chrome/browser/ui/tab_grid/tab_grid_constants.mm
@@ -24,6 +24,7 @@ @"TabGridIncognitoTabsEmptyStateIdentifier"; NSString* const kTabGridRegularTabsEmptyStateIdentifier = @"TabGridRegularTabsEmptyStateIdentifier"; +NSString* const kTabGridScrollViewIdentifier = @"kTabGridScrollViewIdentifier"; // The color of the text buttons in the toolbars. const int kTabGridToolbarTextButtonColor = 0xFFFFFF;
diff --git a/ios/chrome/browser/ui/tab_grid/tab_grid_egtest.mm b/ios/chrome/browser/ui/tab_grid/tab_grid_egtest.mm index 3e2ed1b..0561c2e 100644 --- a/ios/chrome/browser/ui/tab_grid/tab_grid_egtest.mm +++ b/ios/chrome/browser/ui/tab_grid/tab_grid_egtest.mm
@@ -2,20 +2,61 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "base/strings/stringprintf.h" +#import "ios/chrome/browser/ui/tab_grid/tab_grid_constants.h" #import "ios/chrome/browser/ui/tab_grid/tab_grid_egtest_util.h" #import "ios/chrome/test/earl_grey/chrome_earl_grey.h" +#import "ios/chrome/test/earl_grey/chrome_earl_grey_ui.h" #import "ios/chrome/test/earl_grey/chrome_matchers.h" #import "ios/chrome/test/earl_grey/chrome_test_case.h" +#import "ios/web/public/test/http_server/http_server.h" +#import "ios/web/public/test/http_server/http_server_util.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." #endif -@interface TabGridTestCase : ChromeTestCase +namespace { +char kURL1[] = "http://firstURL"; +char kURL2[] = "http://secondURL"; +char kURL3[] = "http://thirdURL"; +char kTitle1[] = "Page 1"; +char kTitle2[] = "Page 2"; +char kResponse1[] = "Test Page 1 content"; +char kResponse2[] = "Test Page 2 content"; +char kResponse3[] = "Test Page 3 content"; +} // namespace + +@interface TabGridTestCase : ChromeTestCase { + GURL _URL1; + GURL _URL2; + GURL _URL3; +} @end @implementation TabGridTestCase +// Set up called once for the class. ++ (void)setUp { + [super setUp]; + std::map<GURL, std::string> responses; + const char kPageFormat[] = "<head><title>%s</title></head><body>%s</body>"; + responses[web::test::HttpServer::MakeUrl(kURL1)] = + base::StringPrintf(kPageFormat, kTitle1, kResponse1); + responses[web::test::HttpServer::MakeUrl(kURL2)] = + base::StringPrintf(kPageFormat, kTitle2, kResponse2); + // Page 3 does not have <title> tag, so URL will be its title. + responses[web::test::HttpServer::MakeUrl(kURL3)] = kResponse3; + web::test::SetUpSimpleHttpServer(responses); +} + +- (void)setUp { + [super setUp]; + _URL1 = web::test::HttpServer::MakeUrl(kURL1); + _URL2 = web::test::HttpServer::MakeUrl(kURL2); + _URL3 = web::test::HttpServer::MakeUrl(kURL3); +} + // Tests entering and leaving the tab grid. - (void)testEnteringAndLeavingTabGrid { [[EarlGrey selectElementWithMatcher:chrome_test_util::ShowTabsButton()] @@ -98,4 +139,37 @@ assertWithMatcher:grey_sufficientlyVisible()]; } +- (void)loadTestURLs { + [ChromeEarlGrey loadURL:_URL1]; + [ChromeEarlGrey waitForWebViewContainingText:kResponse1]; + + [ChromeEarlGrey loadURL:_URL2]; + [ChromeEarlGrey waitForWebViewContainingText:kResponse2]; + + [ChromeEarlGrey loadURL:_URL3]; + [ChromeEarlGrey waitForWebViewContainingText:kResponse3]; +} + +// Test that Clear Browsing Data can be successfully done from tab grid. +- (void)testClearBrowsingData { + // Load history + [self loadTestURLs]; + + [[EarlGrey selectElementWithMatcher:chrome_test_util::ShowTabsButton()] + performAction:grey_tap()]; + // Swipe over to Recent Tabs + [[EarlGrey selectElementWithMatcher:grey_accessibilityID( + kTabGridScrollViewIdentifier)] + performAction:[GREYActions + actionForSwipeFastInDirection:kGREYDirectionLeft]]; + + // Tap on "Show History" + // Undo is available after close all action. + [[EarlGrey + selectElementWithMatcher:chrome_test_util::TabGridSelectShowHistoryCell()] + performAction:grey_tap()]; + [ChromeEarlGreyUI openAndClearBrowsingDataFromHistory]; + [ChromeEarlGreyUI assertHistoryHasNoEntries]; +} + @end
diff --git a/ios/chrome/browser/ui/tab_grid/tab_grid_egtest_util.h b/ios/chrome/browser/ui/tab_grid/tab_grid_egtest_util.h index ea8e249..ba016fc 100644 --- a/ios/chrome/browser/ui/tab_grid/tab_grid_egtest_util.h +++ b/ios/chrome/browser/ui/tab_grid/tab_grid_egtest_util.h
@@ -23,6 +23,9 @@ // in the tab grid. id<GREYMatcher> TabGridUndoCloseAllButton(); +// Returns the GREYMatcher for the cell that opens History in Recent Tabs. +id<GREYMatcher> TabGridSelectShowHistoryCell(); + // Returns the GREYMatcher for the regular tabs empty state view. id<GREYMatcher> TabGridRegularTabsEmptyStateView();
diff --git a/ios/chrome/browser/ui/tab_grid/tab_grid_egtest_util.mm b/ios/chrome/browser/ui/tab_grid/tab_grid_egtest_util.mm index b5cc755..4476ddd 100644 --- a/ios/chrome/browser/ui/tab_grid/tab_grid_egtest_util.mm +++ b/ios/chrome/browser/ui/tab_grid/tab_grid_egtest_util.mm
@@ -6,6 +6,7 @@ #import <EarlGrey/EarlGrey.h> +#import "ios/chrome/browser/ui/ntp/recent_tabs/recent_tabs_constants.h" #import "ios/chrome/browser/ui/tab_grid/grid/grid_constants.h" #import "ios/chrome/browser/ui/tab_grid/tab_grid_constants.h" #import "ios/chrome/browser/ui/tools_menu/public/tools_menu_constants.h" @@ -51,6 +52,12 @@ grey_sufficientlyVisible(), nil); } +id<GREYMatcher> TabGridSelectShowHistoryCell() { + return grey_allOf(grey_accessibilityID( + kRecentTabsShowFullHistoryCellAccessibilityIdentifier), + grey_sufficientlyVisible(), nil); +} + id<GREYMatcher> TabGridRegularTabsEmptyStateView() { return grey_allOf( grey_accessibilityID(kTabGridRegularTabsEmptyStateIdentifier),
diff --git a/ios/chrome/browser/ui/tab_grid/tab_grid_view_controller.mm b/ios/chrome/browser/ui/tab_grid/tab_grid_view_controller.mm index c1e4d42..6eddaf2 100644 --- a/ios/chrome/browser/ui/tab_grid/tab_grid_view_controller.mm +++ b/ios/chrome/browser/ui/tab_grid/tab_grid_view_controller.mm
@@ -542,6 +542,7 @@ [self.view addSubview:scrollView]; self.scrollContentView = contentView; self.scrollView = scrollView; + self.scrollView.accessibilityIdentifier = kTabGridScrollViewIdentifier; NSArray* constraints = @[ [contentView.topAnchor constraintEqualToAnchor:scrollView.topAnchor], [contentView.bottomAnchor constraintEqualToAnchor:scrollView.bottomAnchor],
diff --git a/ios/net/cookies/cookie_store_ios_test_util.h b/ios/net/cookies/cookie_store_ios_test_util.h index 698202f..4c71e8a 100644 --- a/ios/net/cookies/cookie_store_ios_test_util.h +++ b/ios/net/cookies/cookie_store_ios_test_util.h
@@ -15,6 +15,7 @@ #include "net/cookies/cookie_change_dispatcher.h" #include "net/cookies/cookie_monster.h" #include "net/cookies/cookie_store.h" +#include "net/log/net_log_with_source.h" #include "url/gurl.h" namespace net { @@ -35,7 +36,8 @@ private: // net::CookieMonster::PersistentCookieStore implementation: - void Load(const LoadedCallback& loaded_callback) override; + void Load(const LoadedCallback& loaded_callback, + const NetLogWithSource& net_log) override; void LoadCookiesForKey(const std::string& key, const LoadedCallback& loaded_callback) override; void AddCookie(const net::CanonicalCookie& cc) override;
diff --git a/ios/net/cookies/cookie_store_ios_test_util.mm b/ios/net/cookies/cookie_store_ios_test_util.mm index 8edca9b3..7fca970 100644 --- a/ios/net/cookies/cookie_store_ios_test_util.mm +++ b/ios/net/cookies/cookie_store_ios_test_util.mm
@@ -68,7 +68,8 @@ #pragma mark - #pragma mark Private methods -void TestPersistentCookieStore::Load(const LoadedCallback& loaded_callback) { +void TestPersistentCookieStore::Load(const LoadedCallback& loaded_callback, + const NetLogWithSource& /* net_log */) { loaded_callback_ = loaded_callback; }
diff --git a/ipc/ipc_message_utils.cc b/ipc/ipc_message_utils.cc index a0614240..eb6023a 100644 --- a/ipc/ipc_message_utils.cc +++ b/ipc/ipc_message_utils.cc
@@ -891,16 +891,16 @@ #if defined(OS_WIN) base::win::ScopedHandle h = const_cast<param_type&>(p).PassPlatformHandle(); - HandleWin handle_win(h.Take()); + HandleWin handle_win(h.Get()); WriteParam(m, handle_win); #elif defined(OS_FUCHSIA) zx::handle h = const_cast<param_type&>(p).PassPlatformHandle(); - HandleFuchsia handle_fuchsia(h.release()); + HandleFuchsia handle_fuchsia(h.get()); WriteParam(m, handle_fuchsia); #elif defined(OS_MACOSX) && !defined(OS_IOS) base::mac::ScopedMachSendRight h = const_cast<param_type&>(p).PassPlatformHandle(); - MachPortMac mach_port_mac(h.release()); + MachPortMac mach_port_mac(h.get()); WriteParam(m, mach_port_mac); #elif defined(OS_ANDROID) m->WriteAttachment(new internal::PlatformFileAttachment(
diff --git a/media/base/android/java/src/org/chromium/media/MediaCodecBridge.java b/media/base/android/java/src/org/chromium/media/MediaCodecBridge.java index 2fe9c77..f6d37ea4 100644 --- a/media/base/android/java/src/org/chromium/media/MediaCodecBridge.java +++ b/media/base/android/java/src/org/chromium/media/MediaCodecBridge.java
@@ -214,6 +214,8 @@ @Override public void onError(MediaCodec codec, MediaCodec.CodecException e) { + // TODO(dalecurtis): We may want to drop transient errors here. + Log.e(TAG, "MediaCodec.onError: " + e.getDiagnosticInfo()); mMediaCodecBridge.onError(e); } @@ -287,7 +289,6 @@ } public synchronized void onError(MediaCodec.CodecException e) { - // TODO(dalecurtis): We may want to drop transient errors here. mPendingError = true; mPendingInputBuffers.clear(); mPendingOutputBuffers.clear(); @@ -478,6 +479,15 @@ @CalledByNative private ByteBuffer getInputBuffer(int index) { if (Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT) { + if (mUseAsyncApi) { + synchronized (this) { + // Prior to Android N, some versions of MediaCodec will + // crash internally if we call getInputBuffer() after an + // error has occurred. See https://crbug.com/610523 and + // https://crbug.com/873094. + if (mPendingError) return null; + } + } try { return mMediaCodec.getInputBuffer(index); } catch (IllegalStateException e) {
diff --git a/media/base/video_frame.cc b/media/base/video_frame.cc index 1bd40a8..0f757434 100644 --- a/media/base/video_frame.cc +++ b/media/base/video_frame.cc
@@ -937,43 +937,7 @@ } size_t VideoFrame::BitDepth() const { - switch (format()) { - case media::PIXEL_FORMAT_UNKNOWN: - NOTREACHED(); - FALLTHROUGH; - case media::PIXEL_FORMAT_I420: - case media::PIXEL_FORMAT_YV12: - case media::PIXEL_FORMAT_I422: - case media::PIXEL_FORMAT_I420A: - case media::PIXEL_FORMAT_I444: - case media::PIXEL_FORMAT_NV12: - case media::PIXEL_FORMAT_NV21: - case media::PIXEL_FORMAT_UYVY: - case media::PIXEL_FORMAT_YUY2: - case media::PIXEL_FORMAT_ARGB: - case media::PIXEL_FORMAT_XRGB: - case media::PIXEL_FORMAT_RGB24: - case media::PIXEL_FORMAT_RGB32: - case media::PIXEL_FORMAT_MJPEG: - case media::PIXEL_FORMAT_MT21: - return 8; - case media::PIXEL_FORMAT_YUV420P9: - case media::PIXEL_FORMAT_YUV422P9: - case media::PIXEL_FORMAT_YUV444P9: - return 9; - case media::PIXEL_FORMAT_YUV420P10: - case media::PIXEL_FORMAT_YUV422P10: - case media::PIXEL_FORMAT_YUV444P10: - return 10; - case media::PIXEL_FORMAT_YUV420P12: - case media::PIXEL_FORMAT_YUV422P12: - case media::PIXEL_FORMAT_YUV444P12: - return 12; - case media::PIXEL_FORMAT_Y16: - return 16; - } - NOTREACHED(); - return 0; + return ::media::BitDepth(format()); } // static
diff --git a/media/base/video_types.cc b/media/base/video_types.cc index 69afe553..78b614f 100644 --- a/media/base/video_types.cc +++ b/media/base/video_types.cc
@@ -136,4 +136,44 @@ return false; } +size_t BitDepth(VideoPixelFormat format) { + switch (format) { + case PIXEL_FORMAT_UNKNOWN: + NOTREACHED(); + FALLTHROUGH; + case PIXEL_FORMAT_I420: + case PIXEL_FORMAT_YV12: + case PIXEL_FORMAT_I422: + case PIXEL_FORMAT_I420A: + case PIXEL_FORMAT_I444: + case PIXEL_FORMAT_NV12: + case PIXEL_FORMAT_NV21: + case PIXEL_FORMAT_UYVY: + case PIXEL_FORMAT_YUY2: + case PIXEL_FORMAT_ARGB: + case PIXEL_FORMAT_XRGB: + case PIXEL_FORMAT_RGB24: + case PIXEL_FORMAT_RGB32: + case PIXEL_FORMAT_MJPEG: + case PIXEL_FORMAT_MT21: + return 8; + case PIXEL_FORMAT_YUV420P9: + case PIXEL_FORMAT_YUV422P9: + case PIXEL_FORMAT_YUV444P9: + return 9; + case PIXEL_FORMAT_YUV420P10: + case PIXEL_FORMAT_YUV422P10: + case PIXEL_FORMAT_YUV444P10: + return 10; + case PIXEL_FORMAT_YUV420P12: + case PIXEL_FORMAT_YUV422P12: + case PIXEL_FORMAT_YUV444P12: + return 12; + case PIXEL_FORMAT_Y16: + return 16; + } + NOTREACHED(); + return 0; +} + } // namespace media
diff --git a/media/base/video_types.h b/media/base/video_types.h index 5bfd8f5..0d31485 100644 --- a/media/base/video_types.h +++ b/media/base/video_types.h
@@ -93,6 +93,9 @@ // Returns true if |format| has no Alpha channel (hence is always opaque). MEDIA_EXPORT bool IsOpaque(VideoPixelFormat format); +// Returns the number of significant bits per channel. +MEDIA_EXPORT size_t BitDepth(VideoPixelFormat format); + } // namespace media #endif // MEDIA_BASE_VIDEO_TYPES_H_
diff --git a/media/video/gpu_memory_buffer_video_frame_pool.cc b/media/video/gpu_memory_buffer_video_frame_pool.cc index 5c88cc2..ff6c203 100644 --- a/media/video/gpu_memory_buffer_video_frame_pool.cc +++ b/media/video/gpu_memory_buffer_video_frame_pool.cc
@@ -555,11 +555,11 @@ const scoped_refptr<VideoFrame>& video_frame, FrameReadyCB frame_ready_cb) { DCHECK(media_task_runner_->BelongsToCurrentThread()); - // Lazily initialize output_format_ since VideoFrameOutputFormat() has to be + // Lazily initialize |output_format_| since VideoFrameOutputFormat() has to be // called on the media_thread while this object might be instantiated on any. + const VideoPixelFormat pixel_format = video_frame->format(); if (output_format_ == GpuVideoAcceleratorFactories::OutputFormat::UNDEFINED) { - output_format_ = - gpu_factories_->VideoFrameOutputFormat(video_frame->BitDepth()); + output_format_ = gpu_factories_->VideoFrameOutputFormat(pixel_format); } bool is_software_backed_video_frame = !video_frame->HasTextures(); @@ -570,7 +570,7 @@ bool passthrough = false; if (output_format_ == GpuVideoAcceleratorFactories::OutputFormat::UNDEFINED) passthrough = true; - switch (video_frame->format()) { + switch (pixel_format) { // Supported cases. case PIXEL_FORMAT_YV12: case PIXEL_FORMAT_I420: @@ -603,7 +603,7 @@ if (is_software_backed_video_frame) { UMA_HISTOGRAM_ENUMERATION( "Media.GpuMemoryBufferVideoFramePool.UnsupportedFormat", - video_frame->format(), PIXEL_FORMAT_MAX + 1); + pixel_format, PIXEL_FORMAT_MAX + 1); } passthrough = true; }
diff --git a/media/video/gpu_video_accelerator_factories.h b/media/video/gpu_video_accelerator_factories.h index 6c6f58c..f6794ef 100644 --- a/media/video/gpu_video_accelerator_factories.h +++ b/media/video/gpu_video_accelerator_factories.h
@@ -112,7 +112,8 @@ // Pixel format of the hardware video frames created when GpuMemoryBuffers // video frames are enabled. - virtual OutputFormat VideoFrameOutputFormat(size_t bit_depth) = 0; + virtual OutputFormat VideoFrameOutputFormat( + VideoPixelFormat pixel_format) = 0; // Returns a GL Context that can be used on the task runner associated with // the same instance of GpuVideoAcceleratorFactories.
diff --git a/media/video/mock_gpu_video_accelerator_factories.h b/media/video/mock_gpu_video_accelerator_factories.h index 41bb3941..068db25 100644 --- a/media/video/mock_gpu_video_accelerator_factories.h +++ b/media/video/mock_gpu_video_accelerator_factories.h
@@ -71,7 +71,7 @@ bool ShouldUseGpuMemoryBuffersForVideoFrames( bool for_media_stream) const override; unsigned ImageTextureTarget(gfx::BufferFormat format) override; - OutputFormat VideoFrameOutputFormat(size_t bit_depth) override { + OutputFormat VideoFrameOutputFormat(VideoPixelFormat pixel_format) override { return video_frame_output_format_; };
diff --git a/net/BUILD.gn b/net/BUILD.gn index 59a8968..326b22e 100644 --- a/net/BUILD.gn +++ b/net/BUILD.gn
@@ -399,6 +399,7 @@ if (!is_nacl) { sources += [ + "android/android_http_util.cc", "android/cellular_signal_strength.cc", "android/cellular_signal_strength.h", "android/cert_verify_result_android.cc", @@ -406,7 +407,6 @@ "android/gurl_utils.cc", "android/http_auth_negotiate_android.cc", "android/http_auth_negotiate_android.h", - "android/android_http_util.cc", "android/keystore.cc", "android/keystore.h", "android/legacy_openssl.h", @@ -2508,6 +2508,7 @@ "data/ssl/certificates/websocket_cacert.pem", "data/ssl/certificates/websocket_client_cert.p12", "data/ssl/certificates/wildcard.pem", + "data/ssl/certificates/www.ahrn.com.pem", "data/ssl/certificates/x509_verify_results.chain.pem", ] outputs = [
diff --git a/net/base/load_flags_list.h b/net/base/load_flags_list.h index fd80563..798863f 100644 --- a/net/base/load_flags_list.h +++ b/net/base/load_flags_list.h
@@ -37,9 +37,9 @@ // impact the HTTP request headers or use of the host cache. LOAD_FLAG(DISABLE_CACHE, 1 << 4) -// If present, causes certificate revocation checks to be skipped on secure -// connections. -LOAD_FLAG(DISABLE_CERT_REVOCATION_CHECKING, 1 << 5) +// If present, causes dependent network fetches (AIA, CRLs, OCSP) to be +// skipped on secure connections. +LOAD_FLAG(DISABLE_CERT_NETWORK_FETCHES, 1 << 5) // This load will not make any changes to cookies, including storing new // cookies or updating existing ones.
diff --git a/net/cert/caching_cert_verifier.cc b/net/cert/caching_cert_verifier.cc index d3c5787f..e1c3625 100644 --- a/net/cert/caching_cert_verifier.cc +++ b/net/cert/caching_cert_verifier.cc
@@ -23,6 +23,7 @@ CachingCertVerifier::CachingCertVerifier(std::unique_ptr<CertVerifier> verifier) : verifier_(std::move(verifier)), + config_id_(0u), cache_(kMaxCacheEntries), requests_(0u), cache_hits_(0u) { @@ -53,18 +54,24 @@ base::Time start_time = base::Time::Now(); CompletionOnceCallback caching_callback = base::BindOnce( - &CachingCertVerifier::OnRequestFinished, base::Unretained(this), params, - start_time, std::move(callback), verify_result); + &CachingCertVerifier::OnRequestFinished, base::Unretained(this), + config_id_, params, start_time, std::move(callback), verify_result); int result = verifier_->Verify(params, crl_set, verify_result, std::move(caching_callback), out_req, net_log); if (result != ERR_IO_PENDING) { // Synchronous completion; add directly to cache. - AddResultToCache(params, start_time, *verify_result, result); + AddResultToCache(config_id_, params, start_time, *verify_result, result); } return result; } +void CachingCertVerifier::SetConfig(const CertVerifier::Config& config) { + verifier_->SetConfig(config); + config_id_++; + ClearCache(); +} + CachingCertVerifier::CachedResult::CachedResult() : error(ERR_FAILED) {} CachingCertVerifier::CachedResult::~CachedResult() = default; @@ -112,22 +119,29 @@ now.verification_time < expiration.expiration_time; }; -void CachingCertVerifier::OnRequestFinished(const RequestParams& params, +void CachingCertVerifier::OnRequestFinished(uint32_t config_id, + const RequestParams& params, base::Time start_time, CompletionOnceCallback callback, CertVerifyResult* verify_result, int error) { - AddResultToCache(params, start_time, *verify_result, error); + AddResultToCache(config_id, params, start_time, *verify_result, error); // Now chain to the user's callback, which may delete |this|. std::move(callback).Run(error); } void CachingCertVerifier::AddResultToCache( + uint32_t config_id, const RequestParams& params, base::Time start_time, const CertVerifyResult& verify_result, int error) { + // If the configuration has changed since this verification was started, + // don't add it to the cache. + if (config_id != config_id_) + return; + // When caching, this uses the time that validation started as the // beginning of the validity, rather than the time that it ended (aka // base::Time::Now()), to account for the fact that during validation, @@ -161,6 +175,7 @@ } void CachingCertVerifier::OnCertDBChanged() { + config_id_++; ClearCache(); }
diff --git a/net/cert/caching_cert_verifier.h b/net/cert/caching_cert_verifier.h index 387229f..145c6eb 100644 --- a/net/cert/caching_cert_verifier.h +++ b/net/cert/caching_cert_verifier.h
@@ -49,6 +49,7 @@ CompletionOnceCallback callback, std::unique_ptr<Request>* out_req, const NetLogWithSource& net_log) override; + void SetConfig(const Config& config) override; private: FRIEND_TEST_ALL_PREFIXES(CachingCertVerifierTest, CacheHit); @@ -93,18 +94,21 @@ CacheExpirationFunctor>; // Handles completion of the request matching |params|, which started at - // |start_time|, completing. |verify_result| and |result| are added to the - // cache, and then |callback| (the original caller's callback) is invoked. - void OnRequestFinished(const RequestParams& params, + // |start_time| and with config |config_id|, completing. |verify_result| and + // |result| are added to the cache, and then |callback| (the original caller's + // callback) is invoked. + void OnRequestFinished(uint32_t config_id, + const RequestParams& params, base::Time start_time, CompletionOnceCallback callback, CertVerifyResult* verify_result, int error); // Adds |verify_result| and |error| to the cache for |params|, whose - // verification attempt began at |start_time|. See the implementation - // for more details about the necessity of |start_time|. - void AddResultToCache(const RequestParams& params, + // verification attempt began at |start_time| with config |config_id|. See the + // implementation for more details about the necessity of |start_time|. + void AddResultToCache(uint32_t config_id, + const RequestParams& params, base::Time start_time, const CertVerifyResult& verify_result, int error); @@ -120,6 +124,7 @@ std::unique_ptr<CertVerifier> verifier_; + uint32_t config_id_; CertVerificationCache cache_; uint64_t requests_;
diff --git a/net/cert/cert_verifier.cc b/net/cert/cert_verifier.cc index 89ba98a9..18ab114 100644 --- a/net/cert/cert_verifier.cc +++ b/net/cert/cert_verifier.cc
@@ -81,4 +81,18 @@ #endif } +bool operator==(const CertVerifier::Config& lhs, + const CertVerifier::Config& rhs) { + return std::tie( + lhs.enable_rev_checking, lhs.require_rev_checking_local_anchors, + lhs.enable_sha1_local_anchors, lhs.disable_symantec_enforcement) == + std::tie( + rhs.enable_rev_checking, rhs.require_rev_checking_local_anchors, + rhs.enable_sha1_local_anchors, rhs.disable_symantec_enforcement); +} +bool operator!=(const CertVerifier::Config& lhs, + const CertVerifier::Config& rhs) { + return !(lhs == rhs); +} + } // namespace net
diff --git a/net/cert/cert_verifier.h b/net/cert/cert_verifier.h index 7abc4071a..6fb008e8 100644 --- a/net/cert/cert_verifier.h +++ b/net/cert/cert_verifier.h
@@ -27,6 +27,26 @@ // CertVerifiers can handle multiple requests at a time. class NET_EXPORT CertVerifier { public: + struct Config { + // Enable online revocation checking via CRLs and OCSP for the certificate + // chain. Note that revocation checking is soft-fail. + bool enable_rev_checking = false; + + // Enable online revocation checking via CRLs and OCSP for the certificate + // chain if the constructed chain terminates in a locally-installed, + // non-public trust anchor. A revocation error, such as a failure to + // obtain fresh revocation information, is treated as a hard failure. + bool require_rev_checking_local_anchors = false; + + // Enable support for SHA-1 signatures if the constructed chain terminates + // in a locally-installed, non-public trust anchor. + bool enable_sha1_local_anchors = false; + + // Disable enforcement of the policies described at + // https://security.googleblog.com/2017/09/chromes-plan-to-distrust-symantec.html + bool disable_symantec_enforcement = false; + }; + class Request { public: Request() {} @@ -39,35 +59,16 @@ }; enum VerifyFlags { - // If set, enables online revocation checking via CRLs and OCSP for the - // certificate chain. - VERIFY_REV_CHECKING_ENABLED = 1 << 0, - - // 1 << 1 is reserved (used to be VERIFY_EV_CERT). - // 1 << 2 is reserved (used to be VERIY_CERT_IO_ENABLED). - // 1 << 3 is reserved (used to be VERIFY_REV_CHECKING_ENABLED_EV_ONLY). - - // If set, this is equivalent to VERIFY_REV_CHECKING_ENABLED, in that it - // enables online revocation checking via CRLs or OCSP, but only - // for certificates issued by non-public trust anchors. Failure to check - // revocation is treated as a hard failure. - // Note: If VERIFY_CERT_IO_ENABLE is not also supplied, certificates - // that chain to local trust anchors will likely fail - for example, due to - // lacking fresh cached revocation issue (Windows) or because OCSP stapling - // can only provide information for the leaf, and not for any - // intermediates. - VERIFY_REV_CHECKING_REQUIRED_LOCAL_ANCHORS = 1 << 4, - - // If set, certificates with SHA-1 signatures will be allowed, but only if - // they are issued by non-public trust anchors. - VERIFY_ENABLE_SHA1_LOCAL_ANCHORS = 1 << 5, - - // 1 << 6 is reserved (used to be - // VERIFY_ENABLE_COMMON_NAME_FALLBACK_LOCAL_ANCHORS). - - // If set, disables the policy enforcement described at - // https://security.googleblog.com/2017/09/chromes-plan-to-distrust-symantec.html - VERIFY_DISABLE_SYMANTEC_ENFORCEMENT = 1 << 7, + // If set, actively overrides the current CertVerifier::Config to disable + // dependent network fetches. This can be used to avoid triggering + // re-entrancy in the network stack. For example, fetching a PAC script + // over HTTPS may cause AIA, OCSP, or CRL fetches to block on retrieving + // the PAC script, while the PAC script fetch is waiting for those + // dependent fetches, creating a deadlock. When set, this flag prevents + // those fetches from being started (best effort). + // Note that cached information may still be used, if it can be accessed + // without accessing the network. + VERIFY_DISABLE_NETWORK_FETCHES = 1 << 0, }; // Parameters to verify |certificate| against the supplied @@ -158,11 +159,29 @@ std::unique_ptr<Request>* out_req, const NetLogWithSource& net_log) = 0; + // Sets the configuration for new certificate verifications to be |config|. + // Any in-progress verifications (i.e. those with outstanding Request + // handles) will continue using the old configuration. This may be called + // throughout the CertVerifier's lifetime in response to configuration + // changes from embedders. + // Note: As configuration changes will replace any existing configuration, + // this should only be called by the logical 'owner' of this CertVerifier. + // Callers should NOT attempt to change configuration for single calls, and + // should NOT attempt to change configuration for CertVerifiers they do not + // explicitly manage. + virtual void SetConfig(const Config& config) = 0; + // Creates a CertVerifier implementation that verifies certificates using - // the preferred underlying cryptographic libraries. + // the preferred underlying cryptographic libraries, using the specified + // configuration. static std::unique_ptr<CertVerifier> CreateDefault(); }; +NET_EXPORT bool operator==(const CertVerifier::Config& lhs, + const CertVerifier::Config& rhs); +NET_EXPORT bool operator!=(const CertVerifier::Config& lhs, + const CertVerifier::Config& rhs); + } // namespace net #endif // NET_CERT_CERT_VERIFIER_H_
diff --git a/net/cert/cert_verifier_unittest.cc b/net/cert/cert_verifier_unittest.cc index c61e996d..cccb12d 100644 --- a/net/cert/cert_verifier_unittest.cc +++ b/net/cert/cert_verifier_unittest.cc
@@ -86,9 +86,10 @@ { // The same certificate, chain, and host, but with different flags // are different validation keys. - CertVerifier::RequestParams(ok_cert, "www.example.test", - CertVerifier::VERIFY_REV_CHECKING_ENABLED, - std::string(), empty_list), + CertVerifier::RequestParams( + ok_cert, "www.example.test", + CertVerifier::VERIFY_DISABLE_NETWORK_FETCHES, std::string(), + empty_list), CertVerifier::RequestParams(ok_cert, "www.example.test", 0, std::string(), empty_list), false,
diff --git a/net/cert/cert_verify_proc.cc b/net/cert/cert_verify_proc.cc index 57cfa782..6177891b 100644 --- a/net/cert/cert_verify_proc.cc +++ b/net/cert/cert_verify_proc.cc
@@ -600,7 +600,7 @@ // allowed for that platform. See https://crbug.com/588789 bool current_sha1_issue = (verify_result->is_issued_by_known_root || - !(flags & CertVerifier::VERIFY_ENABLE_SHA1_LOCAL_ANCHORS)) && + !(flags & VERIFY_ENABLE_SHA1_LOCAL_ANCHORS)) && (verify_result->has_sha1_leaf || (verify_result->has_sha1 && !AreSHA1IntermediatesAllowed())); @@ -617,7 +617,7 @@ // Distrust Symantec-issued certificates, as described at // https://security.googleblog.com/2017/09/chromes-plan-to-distrust-symantec.html - if (!(flags & CertVerifier::VERIFY_DISABLE_SYMANTEC_ENFORCEMENT) && + if (!(flags & VERIFY_DISABLE_SYMANTEC_ENFORCEMENT) && IsLegacySymantecCert(verify_result->public_key_hashes)) { if (base::FeatureList::IsEnabled(kLegacySymantecPKIEnforcement) || IsUntrustedSymantecCert(*verify_result->verified_cert)) {
diff --git a/net/cert/cert_verify_proc.h b/net/cert/cert_verify_proc.h index 64b2bdd..c89c1379 100644 --- a/net/cert/cert_verify_proc.h +++ b/net/cert/cert_verify_proc.h
@@ -28,6 +28,31 @@ class NET_EXPORT CertVerifyProc : public base::RefCountedThreadSafe<CertVerifyProc> { public: + enum VerifyFlags { + // If set, enables online revocation checking via CRLs and OCSP for the + // certificate chain. + VERIFY_REV_CHECKING_ENABLED = 1 << 0, + + // If set, this is equivalent to VERIFY_REV_CHECKING_ENABLED, in that it + // enables online revocation checking via CRLs or OCSP, but only + // for certificates issued by non-public trust anchors. Failure to check + // revocation is treated as a hard failure. + // Note: If VERIFY_CERT_IO_ENABLE is not also supplied, certificates + // that chain to local trust anchors will likely fail - for example, due to + // lacking fresh cached revocation issue (Windows) or because OCSP stapling + // can only provide information for the leaf, and not for any + // intermediates. + VERIFY_REV_CHECKING_REQUIRED_LOCAL_ANCHORS = 1 << 1, + + // If set, certificates with SHA-1 signatures will be allowed, but only if + // they are issued by non-public trust anchors. + VERIFY_ENABLE_SHA1_LOCAL_ANCHORS = 1 << 2, + + // If set, disables the policy enforcement described at + // https://security.googleblog.com/2017/09/chromes-plan-to-distrust-symantec.html + VERIFY_DISABLE_SYMANTEC_ENFORCEMENT = 1 << 3, + }; + // Creates and returns the default CertVerifyProc. static scoped_refptr<CertVerifyProc> CreateDefault(); @@ -49,9 +74,6 @@ // based revocation checking is always enabled, regardless of this flag, if // |crl_set| is given. // - // If VERIFY_EV_CERT is set in |flags| too, EV certificate verification is - // performed. - // // |crl_set| points to an optional CRLSet structure which can be used to // avoid revocation checks over the network. //
diff --git a/net/cert/cert_verify_proc_builtin.cc b/net/cert/cert_verify_proc_builtin.cc index 62e84937..9345b47 100644 --- a/net/cert/cert_verify_proc_builtin.cc +++ b/net/cert/cert_verify_proc_builtin.cc
@@ -183,7 +183,7 @@ // Use hard-fail revocation checking for local trust anchors, if requested // by the load flag and the chain uses a non-public root. - if ((flags_ & CertVerifier::VERIFY_REV_CHECKING_REQUIRED_LOCAL_ANCHORS) && + if ((flags_ & CertVerifyProc::VERIFY_REV_CHECKING_REQUIRED_LOCAL_ANCHORS) && !certs.empty() && !ssl_trust_store_->IsKnownRoot(certs.back().get())) { RevocationPolicy policy; policy.check_revocation = true; @@ -214,7 +214,7 @@ } // Use soft-fail revocation checking for VERIFY_REV_CHECKING_ENABLED. - if (flags_ & CertVerifier::VERIFY_REV_CHECKING_ENABLED) { + if (flags_ & CertVerifyProc::VERIFY_REV_CHECKING_ENABLED) { RevocationPolicy policy; policy.check_revocation = true; policy.networking_allowed = true;
diff --git a/net/cert/cert_verify_proc_mac.cc b/net/cert/cert_verify_proc_mac.cc index 1257ac5..ae80b29 100644 --- a/net/cert/cert_verify_proc_mac.cc +++ b/net/cert/cert_verify_proc_mac.cc
@@ -182,7 +182,7 @@ // revocation checking policies and instead respect the application-level // revocation preference. status = x509_util::CreateRevocationPolicies( - (flags & CertVerifier::VERIFY_REV_CHECKING_ENABLED), local_policies); + (flags & CertVerifyProc::VERIFY_REV_CHECKING_ENABLED), local_policies); if (status) return status; @@ -546,7 +546,7 @@ // Note: For EV certificates, the Apple TP will handle setting these flags // as part of EV evaluation. - if (flags & CertVerifier::VERIFY_REV_CHECKING_ENABLED) { + if (flags & CertVerifyProc::VERIFY_REV_CHECKING_ENABLED) { // Require a positive result from an OCSP responder or a CRL (or both) // for every certificate in the chain. The Apple TP automatically // excludes the self-signed root from this requirement. If a certificate @@ -830,7 +830,7 @@ break; } - if (flags & CertVerifier::VERIFY_REV_CHECKING_ENABLED) + if (flags & CertVerifyProc::VERIFY_REV_CHECKING_ENABLED) verify_result->cert_status |= CERT_STATUS_REV_CHECKING_ENABLED; if (*completed_chain_crl_result == kCRLSetRevoked) @@ -908,7 +908,7 @@ weak_key_or_signature_algorithm = true; policy_fail_already_mapped = true; } else if (policy_failed && - (flags & CertVerifier::VERIFY_REV_CHECKING_ENABLED) && + (flags & CertVerifyProc::VERIFY_REV_CHECKING_ENABLED) && chain_info[index].StatusCodes[status_code_index] == CSSMERR_TP_VERIFY_ACTION_FAILED && base::mac::IsOS10_12()) { @@ -1013,17 +1013,17 @@ // EV policies check out and the verification succeeded. See if revocation // checking still needs to be done before it can be marked as EV. if (completed_chain_crl_result == kCRLSetUnknown && - !(flags & CertVerifier::VERIFY_REV_CHECKING_ENABLED)) { + !(flags & VERIFY_REV_CHECKING_ENABLED)) { // If this is an EV cert and it wasn't covered by CRLSets and revocation // checking wasn't already on, try again with revocation forced on. // // Restore the input state of |*verify_result|, so that the // re-verification starts with a clean slate. *verify_result = input_verify_result; - int tmp_rv = VerifyWithGivenFlags( - verify_result->verified_cert.get(), hostname, - flags | CertVerifier::VERIFY_REV_CHECKING_ENABLED, crl_set, - verify_result, &completed_chain_crl_result); + int tmp_rv = + VerifyWithGivenFlags(verify_result->verified_cert.get(), hostname, + flags | VERIFY_REV_CHECKING_ENABLED, crl_set, + verify_result, &completed_chain_crl_result); // If re-verification failed, return those results without setting EV // status. if (tmp_rv != OK)
diff --git a/net/cert/cert_verify_proc_nss.cc b/net/cert/cert_verify_proc_nss.cc index d98b304..9c11b054 100644 --- a/net/cert/cert_verify_proc_nss.cc +++ b/net/cert/cert_verify_proc_nss.cc
@@ -892,8 +892,7 @@ SECOidTag ev_policy_oid = SEC_OID_UNKNOWN; bool is_ev_candidate = IsEVCandidate(metadata, cert_handle, &ev_policy_oid); - bool check_revocation = - (flags & CertVerifier::VERIFY_REV_CHECKING_ENABLED); + bool check_revocation = (flags & VERIFY_REV_CHECKING_ENABLED); if (check_revocation) verify_result->cert_status |= CERT_STATUS_REV_CHECKING_ENABLED; @@ -917,8 +916,7 @@ } if (status == SECSuccess && - (flags & CertVerifier::VERIFY_REV_CHECKING_REQUIRED_LOCAL_ANCHORS) && - !known_root) { + (flags & VERIFY_REV_CHECKING_REQUIRED_LOCAL_ANCHORS) && !known_root) { // TODO(rsleevi): Optimize this by supplying the constructed chain to // libpkix via cvin. Omitting for now, due to lack of coverage in upstream // NSS tests for that feature.
diff --git a/net/cert/cert_verify_proc_unittest.cc b/net/cert/cert_verify_proc_unittest.cc index 5e3ad57..65785fa 100644 --- a/net/cert/cert_verify_proc_unittest.cc +++ b/net/cert/cert_verify_proc_unittest.cc
@@ -1208,7 +1208,7 @@ ASSERT_TRUE(cert_chain); CertVerifyResult verify_result; - int flags = CertVerifier::VERIFY_REV_CHECKING_ENABLED; + int flags = CertVerifyProc::VERIFY_REV_CHECKING_ENABLED; int error = Verify(cert_chain.get(), "mail.google.com", flags, NULL, CertificateList(), &verify_result); EXPECT_NE(OK, error); @@ -2002,7 +2002,7 @@ CertVerifyResult test_result_3; error = verify_proc->Verify(cert.get(), "127.0.0.1", std::string(), - CertVerifier::VERIFY_DISABLE_SYMANTEC_ENFORCEMENT, + CertVerifyProc::VERIFY_DISABLE_SYMANTEC_ENFORCEMENT, nullptr, CertificateList(), &test_result_3); EXPECT_THAT(error, IsOk()); EXPECT_FALSE(test_result_3.cert_status & CERT_STATUS_SYMANTEC_LEGACY); @@ -2062,7 +2062,7 @@ CertVerifyResult test_result_3; error = verify_proc->Verify(cert.get(), "127.0.0.1", std::string(), - CertVerifier::VERIFY_DISABLE_SYMANTEC_ENFORCEMENT, + CertVerifyProc::VERIFY_DISABLE_SYMANTEC_ENFORCEMENT, nullptr, CertificateList(), &test_result_3); EXPECT_THAT(error, IsOk()); EXPECT_FALSE(test_result_3.cert_status & CERT_STATUS_SYMANTEC_LEGACY); @@ -3221,7 +3221,7 @@ EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_SHA1_SIGNATURE_PRESENT); // ... unless VERIFY_ENABLE_SHA1_LOCAL_ANCHORS was supplied. - flags = CertVerifier::VERIFY_ENABLE_SHA1_LOCAL_ANCHORS; + flags = CertVerifyProc::VERIFY_ENABLE_SHA1_LOCAL_ANCHORS; verify_result.Reset(); error = verify_proc->Verify(cert.get(), "127.0.0.1", std::string(), flags, nullptr /* crl_set */, CertificateList(),
diff --git a/net/cert/cert_verify_proc_win.cc b/net/cert/cert_verify_proc_win.cc index 65f41ca1..272288d 100644 --- a/net/cert/cert_verify_proc_win.cc +++ b/net/cert/cert_verify_proc_win.cc
@@ -911,8 +911,7 @@ // Note: The root cert is also checked for revocation status, so that CRLSets // will cover revoked SPKIs. DWORD chain_flags = CERT_CHAIN_REVOCATION_CHECK_CHAIN; - bool rev_checking_enabled = - (flags & CertVerifier::VERIFY_REV_CHECKING_ENABLED); + bool rev_checking_enabled = (flags & VERIFY_REV_CHECKING_ENABLED); if (rev_checking_enabled) { verify_result->cert_status |= CERT_STATUS_REV_CHECKING_ENABLED; } else { @@ -1067,7 +1066,7 @@ CertVerifyResult temp_verify_result = *verify_result; GetCertChainInfo(chain_context, verify_result); if (!verify_result->is_issued_by_known_root && - (flags & CertVerifier::VERIFY_REV_CHECKING_REQUIRED_LOCAL_ANCHORS)) { + (flags & VERIFY_REV_CHECKING_REQUIRED_LOCAL_ANCHORS)) { *verify_result = temp_verify_result; rev_checking_enabled = true;
diff --git a/net/cert/mock_cert_verifier.h b/net/cert/mock_cert_verifier.h index 77b403a..db7bea5f 100644 --- a/net/cert/mock_cert_verifier.h +++ b/net/cert/mock_cert_verifier.h
@@ -33,6 +33,7 @@ CompletionOnceCallback callback, std::unique_ptr<Request>* out_req, const NetLogWithSource& net_log) override; + void SetConfig(const Config& config) override {} // Sets the default return value for Verify() for certificates/hosts that do // not have explicit results added via the AddResult*() methods.
diff --git a/net/cert/multi_threaded_cert_verifier.cc b/net/cert/multi_threaded_cert_verifier.cc index 7ebdf94..217d9046 100644 --- a/net/cert/multi_threaded_cert_verifier.cc +++ b/net/cert/multi_threaded_cert_verifier.cc
@@ -5,6 +5,7 @@ #include "net/cert/multi_threaded_cert_verifier.h" #include <algorithm> +#include <iterator> #include <utility> #include "base/bind.h" @@ -119,6 +120,21 @@ CertVerifyResult result; }; +int GetFlagsForConfig(const CertVerifier::Config& config) { + int flags = 0; + + if (config.enable_rev_checking) + flags |= CertVerifyProc::VERIFY_REV_CHECKING_ENABLED; + if (config.require_rev_checking_local_anchors) + flags |= CertVerifyProc::VERIFY_REV_CHECKING_REQUIRED_LOCAL_ANCHORS; + if (config.enable_sha1_local_anchors) + flags |= CertVerifyProc::VERIFY_ENABLE_SHA1_LOCAL_ANCHORS; + if (config.disable_symantec_enforcement) + flags |= CertVerifyProc::VERIFY_DISABLE_SYMANTEC_ENFORCEMENT; + + return flags; +} + } // namespace // Represents the output and result callback of a request. The @@ -225,15 +241,22 @@ // Posts a task to TaskScheduler to do the verification. Once the verification // has completed, it will call OnJobCompleted() on the origin thread. void Start(const scoped_refptr<CertVerifyProc>& verify_proc, + const CertVerifier::Config& config, + uint32_t config_id, const scoped_refptr<CRLSet>& crl_set) { + int flags = GetFlagsForConfig(config); + if (key_.flags() & CertVerifier::VERIFY_DISABLE_NETWORK_FETCHES) { + flags &= ~CertVerifyProc::VERIFY_REV_CHECKING_ENABLED; + flags &= ~CertVerifyProc::VERIFY_REV_CHECKING_REQUIRED_LOCAL_ANCHORS; + } base::PostTaskWithTraitsAndReplyWithResult( FROM_HERE, {base::MayBlock(), base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}, base::BindOnce(&DoVerifyOnWorkerThread, verify_proc, key_.certificate(), - key_.hostname(), key_.ocsp_response(), key_.flags(), - crl_set, key_.additional_trust_anchors()), + key_.hostname(), key_.ocsp_response(), flags, crl_set, + key_.additional_trust_anchors()), base::BindOnce(&CertVerifierJob::OnJobCompleted, - weak_ptr_factory_.GetWeakPtr(), crl_set)); + weak_ptr_factory_.GetWeakPtr(), config_id, crl_set)); } ~CertVerifierJob() { @@ -290,14 +313,16 @@ } } - void OnJobCompleted(scoped_refptr<CRLSet> crl_set, + void OnJobCompleted(uint32_t config_id, + scoped_refptr<CRLSet> crl_set, std::unique_ptr<ResultHelper> verify_result) { TRACE_EVENT0(kNetTracingCategory, "CertVerifierJob::OnJobCompleted"); std::unique_ptr<CertVerifierJob> keep_alive = cert_verifier_->RemoveJob(this); LogMetrics(*verify_result); - if (cert_verifier_->verify_complete_callback_) { + if (cert_verifier_->verify_complete_callback_ && + config_id == cert_verifier_->config_id_) { cert_verifier_->verify_complete_callback_.Run( key_, std::move(crl_set), net_log_, verify_result->error, verify_result->result, base::TimeTicks::Now() - start_time_, @@ -374,10 +399,10 @@ std::unique_ptr<CertVerifierJob> new_job = std::make_unique<CertVerifierJob>(params, net_log.net_log(), this); - new_job->Start(verify_proc_, crl_set); + new_job->Start(verify_proc_, config_, config_id_, crl_set); job = new_job.get(); - inflight_[job] = std::move(new_job); + joinable_[job] = std::move(new_job); if (requests_ == 1) job->set_is_first_job(true); @@ -389,6 +414,17 @@ return ERR_IO_PENDING; } +void MultiThreadedCertVerifier::SetConfig(const CertVerifier::Config& config) { + ++config_id_; + config_ = config; + + // In C++17, this would be a .merge() call to combine |joinable_| into + // |inflight_|. + inflight_.insert(std::make_move_iterator(joinable_.begin()), + std::make_move_iterator(joinable_.end())); + joinable_.clear(); +} + bool MultiThreadedCertVerifier::JobComparator::operator()( const CertVerifierJob* job1, const CertVerifierJob* job2) const { @@ -399,7 +435,8 @@ scoped_refptr<CertVerifyProc> verify_proc, VerifyCompleteCallback verify_complete_callback, bool should_record_histograms) - : requests_(0), + : config_id_(0), + requests_(0), inflight_joins_(0), verify_proc_(verify_proc), verify_complete_callback_(std::move(verify_complete_callback)), @@ -408,6 +445,16 @@ std::unique_ptr<CertVerifierJob> MultiThreadedCertVerifier::RemoveJob( CertVerifierJob* job) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + + // See if it's a job from the current generation. + auto joinable_it = joinable_.find(job); + if (joinable_it != joinable_.end()) { + std::unique_ptr<CertVerifierJob> job_ptr = std::move(joinable_it->second); + joinable_.erase(joinable_it); + return job_ptr; + } + + // Otherwise, find it and remove it from previous generations. auto it = inflight_.find(job); DCHECK(it != inflight_.end()); std::unique_ptr<CertVerifierJob> job_ptr = std::move(it->second); @@ -428,9 +475,9 @@ // The JobSet is kept in sorted order so items can be found using binary // search. - auto it = std::lower_bound(inflight_.begin(), inflight_.end(), key, + auto it = std::lower_bound(joinable_.begin(), joinable_.end(), key, JobToRequestParamsComparator()); - if (it != inflight_.end() && !(key < it->first->key())) + if (it != joinable_.end() && !(key < it->first->key())) return it->first; return nullptr; }
diff --git a/net/cert/multi_threaded_cert_verifier.h b/net/cert/multi_threaded_cert_verifier.h index 13c02e7..4ce98ca 100644 --- a/net/cert/multi_threaded_cert_verifier.h +++ b/net/cert/multi_threaded_cert_verifier.h
@@ -67,6 +67,7 @@ CompletionOnceCallback callback, std::unique_ptr<Request>* out_req, const NetLogWithSource& net_log) override; + void SetConfig(const CertVerifier::Config& config) override; private: struct JobToRequestParamsComparator; @@ -88,8 +89,8 @@ VerifyCompleteCallback verify_complete_callback, bool should_record_histograms); - // Returns an inflight job for |key|. If there is no such job then returns - // null. + // Returns an inflight job for |key|, if it can be joined. If there is no + // such job then returns null. CertVerifierJob* FindJob(const RequestParams& key); // Removes |job| from the inflight set, and passes ownership back to the @@ -100,13 +101,23 @@ uint64_t requests() const { return requests_; } uint64_t inflight_joins() const { return inflight_joins_; } - // inflight_ holds the jobs for which an active verification is taking place, - // mapping the job's raw pointer to an owned pointer. Would be a - // set<unique_ptr> but extraction of owned objects from a set of owned types - // doesn't come until C++17. + // |joinable_| holds the jobs for which an active verification is taking + // place and can be joined by new requests (e.g. the config is the same), + // mapping the job's raw pointer to an owned pointer. + // TODO(rsleevi): Once C++17 is supported, switch this to be a std::set<>, + // which supports extracting owned objects from the set. + std::map<CertVerifierJob*, std::unique_ptr<CertVerifierJob>, JobComparator> + joinable_; + + // |inflight_| contains all jobs that are still undergoing active + // verification, but which can no longer be joined - such as due to the + // underlying configuration changing. std::map<CertVerifierJob*, std::unique_ptr<CertVerifierJob>, JobComparator> inflight_; + uint32_t config_id_; + Config config_; + uint64_t requests_; uint64_t inflight_joins_;
diff --git a/net/cert/multi_threaded_cert_verifier_unittest.cc b/net/cert/multi_threaded_cert_verifier_unittest.cc index 74508e6..36dc29c 100644 --- a/net/cert/multi_threaded_cert_verifier_unittest.cc +++ b/net/cert/multi_threaded_cert_verifier_unittest.cc
@@ -25,6 +25,9 @@ using net::test::IsError; using net::test::IsOk; +using testing::_; +using testing::DoAll; +using testing::Return; namespace net { @@ -36,36 +39,53 @@ class MockCertVerifyProc : public CertVerifyProc { public: - MockCertVerifyProc() = default; + MOCK_METHOD7(VerifyInternal, + int(X509Certificate*, + const std::string&, + const std::string&, + int, + CRLSet*, + const CertificateList&, + CertVerifyResult*)); + MOCK_CONST_METHOD0(SupportsAdditionalTrustAnchors, bool()); private: ~MockCertVerifyProc() override = default; - - // CertVerifyProc implementation - bool SupportsAdditionalTrustAnchors() const override { return false; } - - int VerifyInternal(X509Certificate* cert, - const std::string& hostname, - const std::string& ocsp_response, - int flags, - CRLSet* crl_set, - const CertificateList& additional_trust_anchors, - CertVerifyResult* verify_result) override { - verify_result->Reset(); - verify_result->verified_cert = cert; - verify_result->cert_status = CERT_STATUS_COMMON_NAME_INVALID; - return ERR_CERT_COMMON_NAME_INVALID; - } }; +ACTION(SetCertVerifyResult) { + X509Certificate* cert = arg0; + CertVerifyResult* result = arg6; + result->Reset(); + result->verified_cert = cert; + result->cert_status = CERT_STATUS_COMMON_NAME_INVALID; +} + +ACTION(SetCertVerifyRevokedResult) { + X509Certificate* cert = arg0; + CertVerifyResult* result = arg6; + result->Reset(); + result->verified_cert = cert; + result->cert_status = CERT_STATUS_REVOKED; +} + } // namespace class MultiThreadedCertVerifierTest : public TestWithScopedTaskEnvironment { public: - MultiThreadedCertVerifierTest() : verifier_(new MockCertVerifyProc()) {} + MultiThreadedCertVerifierTest() + : mock_verify_proc_(base::MakeRefCounted<MockCertVerifyProc>()), + verifier_(mock_verify_proc_) { + EXPECT_CALL(*mock_verify_proc_, SupportsAdditionalTrustAnchors()) + .WillRepeatedly(Return(true)); + EXPECT_CALL(*mock_verify_proc_, VerifyInternal(_, _, _, _, _, _, _)) + .WillRepeatedly( + DoAll(SetCertVerifyResult(), Return(ERR_CERT_COMMON_NAME_INVALID))); + } ~MultiThreadedCertVerifierTest() override = default; protected: + scoped_refptr<MockCertVerifyProc> mock_verify_proc_; MultiThreadedCertVerifier verifier_; }; @@ -256,4 +276,53 @@ ASSERT_EQ(2u, verifier_.inflight_joins()); } +// Tests propagation of configuration options into CertVerifyProc flags +TEST_F(MultiThreadedCertVerifierTest, ConvertsConfigToFlags) { + base::FilePath certs_dir = GetTestCertsDirectory(); + scoped_refptr<X509Certificate> test_cert( + ImportCertFromFile(certs_dir, "ok_cert.pem")); + ASSERT_TRUE(test_cert); + + const struct TestConfig { + bool CertVerifier::Config::*config_ptr; + int expected_flag; + } kTestConfig[] = { + {&CertVerifier::Config::enable_rev_checking, + CertVerifyProc::VERIFY_REV_CHECKING_ENABLED}, + {&CertVerifier::Config::require_rev_checking_local_anchors, + CertVerifyProc::VERIFY_REV_CHECKING_REQUIRED_LOCAL_ANCHORS}, + {&CertVerifier::Config::enable_sha1_local_anchors, + CertVerifyProc::VERIFY_ENABLE_SHA1_LOCAL_ANCHORS}, + {&CertVerifier::Config::disable_symantec_enforcement, + CertVerifyProc::VERIFY_DISABLE_SYMANTEC_ENFORCEMENT}, + }; + for (const auto& test_config : kTestConfig) { + CertVerifier::Config config; + config.*test_config.config_ptr = true; + + verifier_.SetConfig(config); + + EXPECT_CALL(*mock_verify_proc_, + VerifyInternal(_, _, _, test_config.expected_flag, _, _, _)) + .WillRepeatedly( + DoAll(SetCertVerifyRevokedResult(), Return(ERR_CERT_REVOKED))); + + CertVerifyResult verify_result; + TestCompletionCallback callback; + std::unique_ptr<CertVerifier::Request> request; + int error = verifier_.Verify( + CertVerifier::RequestParams(test_cert, "www.example.com", 0, + std::string(), CertificateList()), + nullptr, &verify_result, callback.callback(), &request, + NetLogWithSource()); + ASSERT_THAT(error, IsError(ERR_IO_PENDING)); + EXPECT_TRUE(request); + error = callback.WaitForResult(); + EXPECT_TRUE(IsCertificateError(error)); + EXPECT_THAT(error, IsError(ERR_CERT_REVOKED)); + + testing::Mock::VerifyAndClearExpectations(mock_verify_proc_.get()); + } +} + } // namespace net
diff --git a/net/cookies/cookie_monster.cc b/net/cookies/cookie_monster.cc index e6a416b..d4382d39 100644 --- a/net/cookies/cookie_monster.cc +++ b/net/cookies/cookie_monster.cc
@@ -864,7 +864,8 @@ // We bind in the current time so that we can report the wall-clock time for // loading cookies. store_->Load(base::Bind(&CookieMonster::OnLoaded, - weak_ptr_factory_.GetWeakPtr(), TimeTicks::Now())); + weak_ptr_factory_.GetWeakPtr(), TimeTicks::Now()), + net_log_); } void CookieMonster::OnLoaded(
diff --git a/net/cookies/cookie_monster.h b/net/cookies/cookie_monster.h index bf39cd0bc..9251db4d 100644 --- a/net/cookies/cookie_monster.h +++ b/net/cookies/cookie_monster.h
@@ -670,7 +670,10 @@ // that are not yet returned to CookieMonster by previous priority loads. // // |loaded_callback| may not be NULL. - virtual void Load(const LoadedCallback& loaded_callback) = 0; + // |net_log| is a NetLogWithSource that may be copied if the persistent + // store wishes to log NetLog events. + virtual void Load(const LoadedCallback& loaded_callback, + const NetLogWithSource& net_log) = 0; // Does a priority load of all cookies for the domain key (eTLD+1). The // callback will return all the cookies that are not yet returned by previous
diff --git a/net/cookies/cookie_monster_store_test.cc b/net/cookies/cookie_monster_store_test.cc index 13a7d057..4c7d7c40 100644 --- a/net/cookies/cookie_monster_store_test.cc +++ b/net/cookies/cookie_monster_store_test.cc
@@ -42,7 +42,8 @@ load_result_.swap(result); } -void MockPersistentCookieStore::Load(const LoadedCallback& loaded_callback) { +void MockPersistentCookieStore::Load(const LoadedCallback& loaded_callback, + const NetLogWithSource& /* net_log */) { if (store_load_commands_) { commands_.push_back( CookieStoreCommand(CookieStoreCommand::LOAD, loaded_callback, "")); @@ -66,7 +67,7 @@ return; } if (!loaded_) { - Load(loaded_callback); + Load(loaded_callback, NetLogWithSource()); } else { std::vector<std::unique_ptr<CanonicalCookie>> empty_cookies; base::ThreadTaskRunnerHandle::Get()->PostTask( @@ -86,6 +87,8 @@ commands_.push_back(CookieStoreCommand(CookieStoreCommand::REMOVE, cookie)); } +void MockPersistentCookieStore::SetForceKeepSessionState() {} + void MockPersistentCookieStore::SetBeforeFlushCallback( base::RepeatingClosure callback) {} @@ -95,9 +98,6 @@ std::move(callback)); } -void MockPersistentCookieStore::SetForceKeepSessionState() { -} - MockPersistentCookieStore::~MockPersistentCookieStore() = default; std::unique_ptr<CanonicalCookie> BuildCanonicalCookie( @@ -139,7 +139,8 @@ } void MockSimplePersistentCookieStore::Load( - const LoadedCallback& loaded_callback) { + const LoadedCallback& loaded_callback, + const NetLogWithSource& /* net_log */) { std::vector<std::unique_ptr<CanonicalCookie>> out_cookies; for (auto it = cookies_.begin(); it != cookies_.end(); it++) @@ -154,7 +155,7 @@ const std::string& key, const LoadedCallback& loaded_callback) { if (!loaded_) { - Load(loaded_callback); + Load(loaded_callback, NetLogWithSource()); } else { std::vector<std::unique_ptr<CanonicalCookie>> empty_cookies; base::ThreadTaskRunnerHandle::Get()->PostTask( @@ -183,6 +184,8 @@ cookies_.erase(it); } +void MockSimplePersistentCookieStore::SetForceKeepSessionState() {} + void MockSimplePersistentCookieStore::SetBeforeFlushCallback( base::RepeatingClosure callback) {} @@ -192,9 +195,6 @@ std::move(callback)); } -void MockSimplePersistentCookieStore::SetForceKeepSessionState() { -} - std::unique_ptr<CookieMonster> CreateMonsterFromStoreForGC( int num_secure_cookies, int num_old_secure_cookies,
diff --git a/net/cookies/cookie_monster_store_test.h b/net/cookies/cookie_monster_store_test.h index 05bdb93d..79f0d12 100644 --- a/net/cookies/cookie_monster_store_test.h +++ b/net/cookies/cookie_monster_store_test.h
@@ -21,6 +21,7 @@ #include "base/macros.h" #include "net/cookies/canonical_cookie.h" #include "net/cookies/cookie_monster.h" +#include "net/log/net_log_with_source.h" class GURL; @@ -88,7 +89,8 @@ const CommandList& commands() const { return commands_; } - void Load(const LoadedCallback& loaded_callback) override; + void Load(const LoadedCallback& loaded_callback, + const NetLogWithSource& net_log) override; void LoadCookiesForKey(const std::string& key, const LoadedCallback& loaded_callback) override; @@ -99,12 +101,12 @@ void DeleteCookie(const CanonicalCookie& cookie) override; + void SetForceKeepSessionState() override; + void SetBeforeFlushCallback(base::RepeatingClosure callback) override; void Flush(base::OnceClosure callback) override; - void SetForceKeepSessionState() override; - protected: ~MockPersistentCookieStore() override; @@ -143,7 +145,8 @@ public: MockSimplePersistentCookieStore(); - void Load(const LoadedCallback& loaded_callback) override; + void Load(const LoadedCallback& loaded_callback, + const NetLogWithSource& net_log) override; void LoadCookiesForKey(const std::string& key, const LoadedCallback& loaded_callback) override; @@ -154,12 +157,12 @@ void DeleteCookie(const CanonicalCookie& cookie) override; + void SetForceKeepSessionState() override; + void SetBeforeFlushCallback(base::RepeatingClosure callback) override; void Flush(base::OnceClosure callback) override; - void SetForceKeepSessionState() override; - protected: ~MockSimplePersistentCookieStore() override;
diff --git a/net/cookies/cookie_monster_unittest.cc b/net/cookies/cookie_monster_unittest.cc index 13f68b5..ecedc22 100644 --- a/net/cookies/cookie_monster_unittest.cc +++ b/net/cookies/cookie_monster_unittest.cc
@@ -40,6 +40,7 @@ #include "net/cookies/cookie_store_unittest.h" #include "net/cookies/cookie_util.h" #include "net/cookies/parsed_cookie.h" +#include "net/log/net_log_with_source.h" #include "net/log/test_net_log.h" #include "net/log/test_net_log_util.h" #include "net/ssl/channel_id_service.h" @@ -61,7 +62,9 @@ class NewMockPersistentCookieStore : public CookieMonster::PersistentCookieStore { public: - MOCK_METHOD1(Load, void(const LoadedCallback& loaded_callback)); + MOCK_METHOD2(Load, + void(const LoadedCallback& loaded_callback, + const NetLogWithSource& net_log)); MOCK_METHOD2(LoadCookiesForKey, void(const std::string& key, const LoadedCallback& loaded_callback)); @@ -1004,7 +1007,7 @@ // Make sure the |load_run_loop_| is not reused. CHECK(!expect_load_called_); expect_load_called_ = true; - EXPECT_CALL(*persistent_store_.get(), Load(testing::_)) + EXPECT_CALL(*persistent_store_.get(), Load(testing::_, testing::_)) .WillOnce(testing::DoAll(testing::SaveArg<0>(&loaded_callback_), QuitRunLoop(&load_run_loop_))); }
diff --git a/net/cookies/cookie_store_test_helpers.cc b/net/cookies/cookie_store_test_helpers.cc index 731398f..4577dfd4 100644 --- a/net/cookies/cookie_store_test_helpers.cc +++ b/net/cookies/cookie_store_test_helpers.cc
@@ -232,7 +232,8 @@ // FlushablePersistentStore::FlushablePersistentStore() : flush_count_(0) {} -void FlushablePersistentStore::Load(const LoadedCallback& loaded_callback) { +void FlushablePersistentStore::Load(const LoadedCallback& loaded_callback, + const NetLogWithSource& /* net_log */) { std::vector<std::unique_ptr<CanonicalCookie>> out_cookies; base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(loaded_callback, std::move(out_cookies))); @@ -241,7 +242,7 @@ void FlushablePersistentStore::LoadCookiesForKey( const std::string& key, const LoadedCallback& loaded_callback) { - Load(loaded_callback); + Load(loaded_callback, NetLogWithSource()); } void FlushablePersistentStore::AddCookie(const CanonicalCookie&) {}
diff --git a/net/cookies/cookie_store_test_helpers.h b/net/cookies/cookie_store_test_helpers.h index 496a24f..8527b69 100644 --- a/net/cookies/cookie_store_test_helpers.h +++ b/net/cookies/cookie_store_test_helpers.h
@@ -14,6 +14,7 @@ #include "base/macros.h" #include "base/synchronization/lock.h" #include "net/cookies/cookie_change_dispatcher.h" +#include "net/log/net_log_with_source.h" #include "testing/gtest/include/gtest/gtest.h" class GURL; @@ -151,7 +152,8 @@ FlushablePersistentStore(); // CookieMonster::PersistentCookieStore implementation: - void Load(const LoadedCallback& loaded_callback) override; + void Load(const LoadedCallback& loaded_callback, + const NetLogWithSource& net_log) override; void LoadCookiesForKey(const std::string& key, const LoadedCallback& loaded_callback) override; void AddCookie(const CanonicalCookie&) override;
diff --git a/net/data/ssl/certificates/README b/net/data/ssl/certificates/README index ed5dbf47..3594a94 100644 --- a/net/data/ssl/certificates/README +++ b/net/data/ssl/certificates/README
@@ -66,6 +66,9 @@ Trust the certificate in verisign_class3_g5_crosssigned.pem (Generated by scripts/generate-verisign_class3_g5_crosssigned-trusted-keychain.sh) +- www.ahrn.com.pem: A certificate issued by the Legacy Symantec PKI in 2014, + expires on 2019-10-27. + ===== Manually generated certificates - client.p12 : A PKCS #12 file containing a client certificate and a private key created for testing. The password is "12345".
diff --git a/net/data/ssl/certificates/www.ahrn.com.pem b/net/data/ssl/certificates/www.ahrn.com.pem new file mode 100644 index 0000000..b050b18 --- /dev/null +++ b/net/data/ssl/certificates/www.ahrn.com.pem
@@ -0,0 +1,299 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 4b:55:a8:9e:db:00:a8:b5:62:d7:5c:a3:2c:b3:70:0f + Signature Algorithm: sha256WithRSAEncryption + Issuer: C = US, O = Symantec Corporation, OU = Symantec Trust Network, CN = Symantec Class 3 Secure Server CA - G4 + Validity + Not Before: Oct 28 00:00:00 2014 GMT + Not After : Oct 27 23:59:59 2019 GMT + Subject: C = US, ST = Wisconsin, L = Waterford, O = Runzheimer International LTD, OU = IT, CN = www.ahrn.com + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:d1:30:e0:95:77:78:37:76:72:63:76:d8:7d:f7: + e0:ca:c8:3f:3d:43:70:bb:ed:50:8f:8e:50:16:0d: + 28:64:8f:e6:0c:5c:eb:cd:a9:24:93:1a:51:fa:9f: + 7f:52:da:32:7a:1d:86:7c:b7:3f:be:be:76:a3:4f: + 4e:b9:ab:38:79:69:9a:ab:1f:77:7a:94:80:77:5f: + 6c:c8:25:2b:b0:9d:60:0a:78:88:27:33:c5:ac:1a: + 35:2f:a9:65:f9:c0:0e:8f:8f:e5:66:06:df:bb:60: + bf:67:85:2f:c1:26:57:78:ac:ce:dd:39:a9:fd:04: + 17:f3:0b:53:bb:b4:76:fc:fb:e3:2e:21:87:fd:40: + 4f:12:9a:43:8f:b3:15:4a:6f:bc:0c:0b:4e:94:33: + 06:a5:2c:66:50:ff:7a:2f:6f:f7:83:83:9d:a8:52: + 9a:36:97:ea:97:88:96:96:0b:e9:d9:c6:37:7c:e1: + b4:63:b7:4a:a8:2c:e6:75:fe:0f:33:dd:28:7a:5a: + 4a:7a:c8:26:b1:cb:7d:1a:f4:b1:63:5b:c7:01:3c: + 53:86:33:4e:b6:5a:2c:81:42:41:12:85:60:a7:38: + a7:7b:05:ea:b0:7b:ef:ec:f4:ba:5d:8b:63:dc:ba: + 3d:aa:78:d8:66:9c:d1:35:b3:0d:97:a3:62:95:1f: + 64:af + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Subject Alternative Name: + DNS:www.ahrn.com + X509v3 Basic Constraints: + CA:FALSE + X509v3 Key Usage: critical + Digital Signature, Key Encipherment + X509v3 CRL Distribution Points: + + Full Name: + URI:http://ss.symcb.com/ss.crl + + X509v3 Certificate Policies: + Policy: 2.16.840.1.113733.1.7.54 + CPS: https://d.symcb.com/cps + User Notice: + Explicit Text: https://d.symcb.com/rpa + + X509v3 Extended Key Usage: + TLS Web Server Authentication, TLS Web Client Authentication + X509v3 Authority Key Identifier: + keyid:5F:60:CF:61:90:55:DF:84:43:14:8A:60:2A:B2:F5:7A:F4:43:18:EF + + Authority Information Access: + OCSP - URI:http://ss.symcd.com + CA Issuers - URI:http://ss.symcb.com/ss.crt + + Signature Algorithm: sha256WithRSAEncryption + b0:e7:ed:25:04:03:bc:86:9a:1c:4d:93:99:c1:a0:18:6d:61: + 4d:ab:e1:a8:74:c0:34:71:99:1b:90:9a:62:88:b4:92:ca:c5: + 3a:ba:b3:a6:4f:6a:00:3f:75:9b:fe:69:d7:68:8c:26:63:a8: + 22:ee:8e:ed:3e:20:2e:54:5d:c7:d3:82:ac:18:42:28:ef:7b: + 69:f3:86:f6:55:d1:67:1b:cf:28:0c:0f:82:2b:d6:f4:07:4b: + de:57:3d:02:3e:88:01:59:3d:7c:cd:80:68:61:e3:ac:0b:7f: + 16:4e:1e:54:9b:7d:80:26:31:eb:0c:da:f4:53:5e:bc:62:2a: + 8a:ff:6a:df:f5:b4:07:89:82:b4:67:68:68:54:b9:d5:1b:a0: + f1:35:de:e7:18:b0:64:08:4f:93:13:88:02:8a:9f:42:c5:c3: + 67:a0:d7:aa:dd:54:84:8d:c7:5a:a5:3c:5e:d1:9a:1c:3d:36: + 45:6a:66:a3:10:ad:3e:bf:95:a2:27:8d:a6:7a:7a:6b:59:d3: + 66:79:10:05:fb:3f:0c:f6:b3:b5:85:83:e1:a4:49:02:56:db: + 5b:9d:36:ea:59:e7:b5:f4:9a:aa:59:21:ab:54:a7:fc:b7:15: + 0c:41:29:39:15:ff:83:1f:5e:d3:73:85:96:6e:a4:dc:01:bd: + 7d:21:34:3f +-----BEGIN CERTIFICATE----- +MIIE8DCCA9igAwIBAgIQS1WontsAqLVi11yjLLNwDzANBgkqhkiG9w0BAQsFADB+ +MQswCQYDVQQGEwJVUzEdMBsGA1UEChMUU3ltYW50ZWMgQ29ycG9yYXRpb24xHzAd +BgNVBAsTFlN5bWFudGVjIFRydXN0IE5ldHdvcmsxLzAtBgNVBAMTJlN5bWFudGVj +IENsYXNzIDMgU2VjdXJlIFNlcnZlciBDQSAtIEc0MB4XDTE0MTAyODAwMDAwMFoX +DTE5MTAyNzIzNTk1OVowgYAxCzAJBgNVBAYTAlVTMRIwEAYDVQQIDAlXaXNjb25z +aW4xEjAQBgNVBAcMCVdhdGVyZm9yZDElMCMGA1UECgwcUnVuemhlaW1lciBJbnRl +cm5hdGlvbmFsIExURDELMAkGA1UECwwCSVQxFTATBgNVBAMMDHd3dy5haHJuLmNv +bTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANEw4JV3eDd2cmN22H33 +4MrIPz1DcLvtUI+OUBYNKGSP5gxc682pJJMaUfqff1LaMnodhny3P76+dqNPTrmr +OHlpmqsfd3qUgHdfbMglK7CdYAp4iCczxawaNS+pZfnADo+P5WYG37tgv2eFL8Em +V3iszt05qf0EF/MLU7u0dvz74y4hh/1ATxKaQ4+zFUpvvAwLTpQzBqUsZlD/ei9v +94ODnahSmjaX6peIlpYL6dnGN3zhtGO3Sqgs5nX+DzPdKHpaSnrIJrHLfRr0sWNb +xwE8U4YzTrZaLIFCQRKFYKc4p3sF6rB77+z0ul2LY9y6Pap42Gac0TWzDZejYpUf +ZK8CAwEAAaOCAWUwggFhMBcGA1UdEQQQMA6CDHd3dy5haHJuLmNvbTAJBgNVHRME +AjAAMA4GA1UdDwEB/wQEAwIFoDArBgNVHR8EJDAiMCCgHqAchhpodHRwOi8vc3Mu +c3ltY2IuY29tL3NzLmNybDBlBgNVHSAEXjBcMFoGCmCGSAGG+EUBBzYwTDAjBggr +BgEFBQcCARYXaHR0cHM6Ly9kLnN5bWNiLmNvbS9jcHMwJQYIKwYBBQUHAgIwGQwX +aHR0cHM6Ly9kLnN5bWNiLmNvbS9ycGEwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsG +AQUFBwMCMB8GA1UdIwQYMBaAFF9gz2GQVd+EQxSKYCqy9Xr0QxjvMFcGCCsGAQUF +BwEBBEswSTAfBggrBgEFBQcwAYYTaHR0cDovL3NzLnN5bWNkLmNvbTAmBggrBgEF +BQcwAoYaaHR0cDovL3NzLnN5bWNiLmNvbS9zcy5jcnQwDQYJKoZIhvcNAQELBQAD +ggEBALDn7SUEA7yGmhxNk5nBoBhtYU2r4ah0wDRxmRuQmmKItJLKxTq6s6ZPagA/ +dZv+addojCZjqCLuju0+IC5UXcfTgqwYQijve2nzhvZV0WcbzygMD4Ir1vQHS95X +PQI+iAFZPXzNgGhh46wLfxZOHlSbfYAmMesM2vRTXrxiKor/at/1tAeJgrRnaGhU +udUboPE13ucYsGQIT5MTiAKKn0LFw2eg16rdVISNx1qlPF7Rmhw9NkVqZqMQrT6/ +laInjaZ6emtZ02Z5EAX7Pwz2s7WFg+GkSQJW21udNupZ57X0mqpZIatUp/y3FQxB +KTkV/4MfXtNzhZZupNwBvX0hND8= +-----END CERTIFICATE----- +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 13:b3:e3:02:18:03:97:66:8d:50:34:e0:e6:74:e2:8d + Signature Algorithm: sha256WithRSAEncryption + Issuer: C = US, O = "VeriSign, Inc.", OU = VeriSign Trust Network, OU = "(c) 2006 VeriSign, Inc. - For authorized use only", CN = VeriSign Class 3 Public Primary Certification Authority - G5 + Validity + Not Before: Oct 31 00:00:00 2013 GMT + Not After : Oct 30 23:59:59 2023 GMT + Subject: C = US, O = Symantec Corporation, OU = Symantec Trust Network, CN = Symantec Class 3 Secure Server CA - G4 + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:b2:d8:05:ca:1c:74:2d:b5:17:56:39:c5:4a:52: + 09:96:e8:4b:d8:0c:f1:68:9f:9a:42:28:62:c3:a5: + 30:53:7e:55:11:82:5b:03:7a:0d:2f:e1:79:04:c9: + b4:96:77:19:81:01:94:59:f9:bc:f7:7a:99:27:82: + 2d:b7:83:dd:5a:27:7f:b2:03:7a:9c:53:25:e9:48: + 1f:46:4f:c8:9d:29:f8:be:79:56:f6:f7:fd:d9:3a: + 68:da:8b:4b:82:33:41:12:c3:c8:3c:cc:d6:96:7a: + 84:21:1a:22:04:03:27:17:8b:1c:68:61:93:0f:0e: + 51:80:33:1d:b4:b5:ce:eb:7e:d0:62:ac:ee:b3:7b: + 01:74:ef:69:35:eb:ca:d5:3d:a9:ee:97:98:ca:8d: + aa:44:0e:25:99:4a:15:96:a4:ce:6d:02:54:1f:2a: + 6a:26:e2:06:3a:63:48:ac:b4:4c:d1:75:93:50:ff: + 13:2f:d6:da:e1:c6:18:f5:9f:c9:25:5d:f3:00:3a: + de:26:4d:b4:29:09:cd:0f:3d:23:6f:16:4a:81:16: + fb:f2:83:10:c3:b8:d6:d8:55:32:3d:f1:bd:0f:bd: + 8c:52:95:4a:16:97:7a:52:21:63:75:2f:16:f9:c4: + 66:be:f5:b5:09:d8:ff:27:00:cd:44:7c:6f:4b:3f: + b0:f7 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: critical + CA:TRUE, pathlen:0 + X509v3 CRL Distribution Points: + + Full Name: + URI:http://s1.symcb.com/pca3-g5.crl + + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + X509v3 Subject Alternative Name: + DirName:/CN=SymantecPKI-1-534 + X509v3 Subject Key Identifier: + 5F:60:CF:61:90:55:DF:84:43:14:8A:60:2A:B2:F5:7A:F4:43:18:EF + X509v3 Certificate Policies: + Policy: 2.23.140.1.2.2 + CPS: http://www.symauth.com/cps + User Notice: + Explicit Text: http://www.symauth.com/rpa + + Authority Information Access: + OCSP - URI:http://s2.symcb.com + + X509v3 Authority Key Identifier: + keyid:7F:D3:65:A7:C2:DD:EC:BB:F0:30:09:F3:43:39:FA:02:AF:33:31:33 + + Signature Algorithm: sha256WithRSAEncryption + 16:19:9a:85:c5:85:ea:47:56:4f:40:37:ad:34:e5:a3:2d:74: + 82:be:3a:cd:25:fe:62:70:25:bb:98:09:35:be:77:80:5b:ae: + 28:66:e7:37:34:c0:da:0f:b5:b4:2e:97:78:3e:c8:53:3f:a6: + b1:ae:d5:a4:fd:bc:43:af:7a:20:7b:c8:15:a6:ed:5a:e5:1c: + 8c:a6:81:ef:61:a4:a8:50:76:bd:d0:e0:a2:95:99:78:5f:50: + 88:89:e6:e0:8a:db:ae:f2:e5:be:7a:7d:a0:a9:cf:48:ef:7b: + c6:09:d0:1a:46:11:c5:f8:99:90:5e:6f:c5:91:0d:f6:9e:3f: + 78:95:fe:84:af:73:64:ec:8d:6a:d2:6e:70:08:00:cc:88:a9: + 4e:85:95:f3:31:8a:9e:10:e2:62:23:3d:0b:5c:97:96:7e:db: + 36:64:fb:c9:d6:55:44:21:77:0f:0a:64:26:e2:15:2f:96:31: + 50:eb:f5:bd:ee:1d:e3:dd:d1:50:7e:c4:86:9a:31:fe:a8:7f: + cd:2b:bc:93:c1:2f:67:60:f0:30:59:0d:d6:f5:05:2b:55:31: + 8f:60:b0:b9:f3:1a:de:bc:8d:50:aa:12:39:87:54:38:2a:b7: + 9b:1c:1f:51:ef:9e:a0:fc:8e:fd:c4:4a:de:8a:62:82:9c:a1: + 9d:97:5c:92 +-----BEGIN CERTIFICATE----- +MIIFNDCCBBygAwIBAgIQE7PjAhgDl2aNUDTg5nTijTANBgkqhkiG9w0BAQsFADCB +yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL +ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJp +U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxW +ZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0 +aG9yaXR5IC0gRzUwHhcNMTMxMDMxMDAwMDAwWhcNMjMxMDMwMjM1OTU5WjB+MQsw +CQYDVQQGEwJVUzEdMBsGA1UEChMUU3ltYW50ZWMgQ29ycG9yYXRpb24xHzAdBgNV +BAsTFlN5bWFudGVjIFRydXN0IE5ldHdvcmsxLzAtBgNVBAMTJlN5bWFudGVjIENs +YXNzIDMgU2VjdXJlIFNlcnZlciBDQSAtIEc0MIIBIjANBgkqhkiG9w0BAQEFAAOC +AQ8AMIIBCgKCAQEAstgFyhx0LbUXVjnFSlIJluhL2AzxaJ+aQihiw6UwU35VEYJb +A3oNL+F5BMm0lncZgQGUWfm893qZJ4Itt4PdWid/sgN6nFMl6UgfRk/InSn4vnlW +9vf92Tpo2otLgjNBEsPIPMzWlnqEIRoiBAMnF4scaGGTDw5RgDMdtLXO637QYqzu +s3sBdO9pNevK1T2p7peYyo2qRA4lmUoVlqTObQJUHypqJuIGOmNIrLRM0XWTUP8T +L9ba4cYY9Z/JJV3zADreJk20KQnNDz0jbxZKgRb78oMQw7jW2FUyPfG9D72MUpVK +Fpd6UiFjdS8W+cRmvvW1Cdj/JwDNRHxvSz+w9wIDAQABo4IBXzCCAVswEgYDVR0T +AQH/BAgwBgEB/wIBADAwBgNVHR8EKTAnMCWgI6Ahhh9odHRwOi8vczEuc3ltY2Iu +Y29tL3BjYTMtZzUuY3JsMA4GA1UdDwEB/wQEAwIBBjApBgNVHREEIjAgpB4wHDEa +MBgGA1UEAxMRU3ltYW50ZWNQS0ktMS01MzQwHQYDVR0OBBYEFF9gz2GQVd+EQxSK +YCqy9Xr0QxjvMGcGA1UdIARgMF4wXAYGZ4EMAQICMFIwJgYIKwYBBQUHAgEWGmh0 +dHA6Ly93d3cuc3ltYXV0aC5jb20vY3BzMCgGCCsGAQUFBwICMBwaGmh0dHA6Ly93 +d3cuc3ltYXV0aC5jb20vcnBhMC8GCCsGAQUFBwEBBCMwITAfBggrBgEFBQcwAYYT +aHR0cDovL3MyLnN5bWNiLmNvbTAfBgNVHSMEGDAWgBR/02Wnwt3su/AwCfNDOfoC +rzMxMzANBgkqhkiG9w0BAQsFAAOCAQEAFhmahcWF6kdWT0A3rTTloy10gr46zSX+ +YnAlu5gJNb53gFuuKGbnNzTA2g+1tC6XeD7IUz+msa7VpP28Q696IHvIFabtWuUc +jKaB72GkqFB2vdDgopWZeF9QiInm4IrbrvLlvnp9oKnPSO97xgnQGkYRxfiZkF5v +xZEN9p4/eJX+hK9zZOyNatJucAgAzIipToWV8zGKnhDiYiM9C1yXln7bNmT7ydZV +RCF3DwpkJuIVL5YxUOv1ve4d493RUH7Ehpox/qh/zSu8k8EvZ2DwMFkN1vUFK1Ux +j2CwufMa3ryNUKoSOYdUOCq3mxwfUe+eoPyO/cRK3opigpyhnZdckg== +-----END CERTIFICATE----- +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 18:da:d1:9e:26:7d:e8:bb:4a:21:58:cd:cc:6b:3b:4a + Signature Algorithm: sha1WithRSAEncryption + Issuer: C = US, O = "VeriSign, Inc.", OU = VeriSign Trust Network, OU = "(c) 2006 VeriSign, Inc. - For authorized use only", CN = VeriSign Class 3 Public Primary Certification Authority - G5 + Validity + Not Before: Nov 8 00:00:00 2006 GMT + Not After : Jul 16 23:59:59 2036 GMT + Subject: C = US, O = "VeriSign, Inc.", OU = VeriSign Trust Network, OU = "(c) 2006 VeriSign, Inc. - For authorized use only", CN = VeriSign Class 3 Public Primary Certification Authority - G5 + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:af:24:08:08:29:7a:35:9e:60:0c:aa:e7:4b:3b: + 4e:dc:7c:bc:3c:45:1c:bb:2b:e0:fe:29:02:f9:57: + 08:a3:64:85:15:27:f5:f1:ad:c8:31:89:5d:22:e8: + 2a:aa:a6:42:b3:8f:f8:b9:55:b7:b1:b7:4b:b3:fe: + 8f:7e:07:57:ec:ef:43:db:66:62:15:61:cf:60:0d: + a4:d8:de:f8:e0:c3:62:08:3d:54:13:eb:49:ca:59: + 54:85:26:e5:2b:8f:1b:9f:eb:f5:a1:91:c2:33:49: + d8:43:63:6a:52:4b:d2:8f:e8:70:51:4d:d1:89:69: + 7b:c7:70:f6:b3:dc:12:74:db:7b:5d:4b:56:d3:96: + bf:15:77:a1:b0:f4:a2:25:f2:af:1c:92:67:18:e5: + f4:06:04:ef:90:b9:e4:00:e4:dd:3a:b5:19:ff:02: + ba:f4:3c:ee:e0:8b:eb:37:8b:ec:f4:d7:ac:f2:f6: + f0:3d:af:dd:75:91:33:19:1d:1c:40:cb:74:24:19: + 21:93:d9:14:fe:ac:2a:52:c7:8f:d5:04:49:e4:8d: + 63:47:88:3c:69:83:cb:fe:47:bd:2b:7e:4f:c5:95: + ae:0e:9d:d4:d1:43:c0:67:73:e3:14:08:7e:e5:3f: + 9f:73:b8:33:0a:cf:5d:3f:34:87:96:8a:ee:53:e8: + 25:15 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: critical + CA:TRUE + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + 1.3.6.1.5.5.7.1.12: + 0_.].[0Y0W0U..image/gif0!0.0...+..............k...j.H.,{..0%.#http://logo.verisign.com/vslogo.gif + X509v3 Subject Key Identifier: + 7F:D3:65:A7:C2:DD:EC:BB:F0:30:09:F3:43:39:FA:02:AF:33:31:33 + Signature Algorithm: sha1WithRSAEncryption + 93:24:4a:30:5f:62:cf:d8:1a:98:2f:3d:ea:dc:99:2d:bd:77: + f6:a5:79:22:38:ec:c4:a7:a0:78:12:ad:62:0e:45:70:64:c5: + e7:97:66:2d:98:09:7e:5f:af:d6:cc:28:65:f2:01:aa:08:1a: + 47:de:f9:f9:7c:92:5a:08:69:20:0d:d9:3e:6d:6e:3c:0d:6e: + d8:e6:06:91:40:18:b9:f8:c1:ed:df:db:41:aa:e0:96:20:c9: + cd:64:15:38:81:c9:94:ee:a2:84:29:0b:13:6f:8e:db:0c:dd: + 25:02:db:a4:8b:19:44:d2:41:7a:05:69:4a:58:4f:60:ca:7e: + 82:6a:0b:02:aa:25:17:39:b5:db:7f:e7:84:65:2a:95:8a:bd: + 86:de:5e:81:16:83:2d:10:cc:de:fd:a8:82:2a:6d:28:1f:0d: + 0b:c4:e5:e7:1a:26:19:e1:f4:11:6f:10:b5:95:fc:e7:42:05: + 32:db:ce:9d:51:5e:28:b6:9e:85:d3:5b:ef:a5:7d:45:40:72: + 8e:b7:0e:6b:0e:06:fb:33:35:48:71:b8:9d:27:8b:c4:65:5f: + 0d:86:76:9c:44:7a:f6:95:5c:f6:5d:32:08:33:a4:54:b6:18: + 3f:68:5c:f2:42:4a:85:38:54:83:5f:d1:e8:2c:f2:ac:11:d6: + a8:ed:63:6a +-----BEGIN CERTIFICATE----- +MIIE0zCCA7ugAwIBAgIQGNrRniZ96LtKIVjNzGs7SjANBgkqhkiG9w0BAQUFADCB +yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL +ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJp +U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxW +ZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0 +aG9yaXR5IC0gRzUwHhcNMDYxMTA4MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCByjEL +MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZW +ZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2ln +biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJp +U2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9y +aXR5IC0gRzUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvJAgIKXo1 +nmAMqudLO07cfLw8RRy7K+D+KQL5VwijZIUVJ/XxrcgxiV0i6CqqpkKzj/i5Vbex +t0uz/o9+B1fs70PbZmIVYc9gDaTY3vjgw2IIPVQT60nKWVSFJuUrjxuf6/WhkcIz +SdhDY2pSS9KP6HBRTdGJaXvHcPaz3BJ023tdS1bTlr8Vd6Gw9KIl8q8ckmcY5fQG +BO+QueQA5N06tRn/Arr0PO7gi+s3i+z016zy9vA9r911kTMZHRxAy3QkGSGT2RT+ +rCpSx4/VBEnkjWNHiDxpg8v+R70rfk/Fla4OndTRQ8Bnc+MUCH7lP59zuDMKz10/ +NIeWiu5T6CUVAgMBAAGjgbIwga8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8E +BAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2UvZ2lmMCEwHzAH +BgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVy +aXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFH/TZafC3ey78DAJ80M5+gKv +MzEzMA0GCSqGSIb3DQEBBQUAA4IBAQCTJEowX2LP2BqYLz3q3JktvXf2pXkiOOzE +p6B4Eq1iDkVwZMXnl2YtmAl+X6/WzChl8gGqCBpH3vn5fJJaCGkgDdk+bW48DW7Y +5gaRQBi5+MHt39tBquCWIMnNZBU4gcmU7qKEKQsTb47bDN0lAtukixlE0kF6BWlK +WE9gyn6CagsCqiUXObXbf+eEZSqVir2G3l6BFoMtEMze/aiCKm0oHw0LxOXnGiYZ +4fQRbxC1lfznQgUy286dUV4otp6F01vvpX1FQHKOtw5rDgb7MzVIcbidJ4vEZV8N +hnacRHr2lVz2XTIIM6RUthg/aFzyQkqFOFSDX9HoLPKsEdao7WNq +-----END CERTIFICATE-----
diff --git a/net/dns/host_resolver.cc b/net/dns/host_resolver.cc index 1f4d821d..135e769 100644 --- a/net/dns/host_resolver.cc +++ b/net/dns/host_resolver.cc
@@ -160,6 +160,53 @@ return CreateSystemResolverImpl(Options(), net_log); } +// static +AddressFamily HostResolver::DnsQueryTypeToAddressFamily( + DnsQueryType dns_query_type) { + switch (dns_query_type) { + case DnsQueryType::UNSPECIFIED: + return ADDRESS_FAMILY_UNSPECIFIED; + case DnsQueryType::A: + return ADDRESS_FAMILY_IPV4; + case DnsQueryType::AAAA: + return ADDRESS_FAMILY_IPV6; + default: + // |dns_query_type| should be an address type (A or AAAA) or UNSPECIFIED. + NOTREACHED(); + return ADDRESS_FAMILY_UNSPECIFIED; + } +} + +// static +HostResolver::DnsQueryType HostResolver::AddressFamilyToDnsQueryType( + AddressFamily address_family) { + switch (address_family) { + case ADDRESS_FAMILY_UNSPECIFIED: + return DnsQueryType::UNSPECIFIED; + case ADDRESS_FAMILY_IPV4: + return DnsQueryType::A; + case ADDRESS_FAMILY_IPV6: + return DnsQueryType::AAAA; + default: + NOTREACHED(); + return DnsQueryType::UNSPECIFIED; + } +} + +// static +HostResolver::ResolveHostParameters +HostResolver::RequestInfoToResolveHostParameters( + const HostResolver::RequestInfo& request_info, + RequestPriority priority) { + ResolveHostParameters parameters; + + parameters.dns_query_type = + AddressFamilyToDnsQueryType(request_info.address_family()); + parameters.initial_priority = priority; + + return parameters; +} + HostResolver::HostResolver() = default; } // namespace net
diff --git a/net/dns/host_resolver.h b/net/dns/host_resolver.h index a337724..5b4320f 100644 --- a/net/dns/host_resolver.h +++ b/net/dns/host_resolver.h
@@ -12,6 +12,7 @@ #include <string> #include <vector> +#include "base/optional.h" #include "net/base/address_family.h" #include "net/base/completion_once_callback.h" #include "net/base/host_port_pair.h" @@ -113,6 +114,9 @@ // The parameters for doing a Resolve(). A hostname and port are // required; the rest are optional (and have reasonable defaults). + // + // TODO(crbug.com/821021): Delete this class once all usage has been + // converted to the new CreateRequest() API. class NET_EXPORT RequestInfo { public: explicit RequestInfo(const HostPortPair& host_port_pair); @@ -171,6 +175,29 @@ bool is_my_ip_address_; }; + // DNS query type for a ResolveHostRequest. + // See: + // https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml#dns-parameters-4 + // + // TODO(crbug.com/846423): Add support for non-address types. + enum class DnsQueryType { + UNSPECIFIED, + A, + AAAA, + }; + + // Parameter-grouping struct for additional optional parameters for + // CreateRequest() calls. All fields are optional and have a reasonable + // default. + struct ResolveHostParameters { + // Requested DNS query type. If UNSPECIFIED, resolver will pick A or AAAA + // (or both) based on IPv4/IPv6 settings. + DnsQueryType dns_query_type = DnsQueryType::UNSPECIFIED; + + // The initial net priority for the host resolution request. + RequestPriority initial_priority = RequestPriority::DEFAULT_PRIORITY; + }; + // Set Options.max_concurrent_resolves to this to select a default level // of concurrency. static const size_t kDefaultParallelism = 0; @@ -186,6 +213,9 @@ // Creates a request to resolve the given hostname (or IP address literal). // Profiling information for the request is saved to |net_log| if non-NULL. // + // Additional parameters may be set using |optional_parameters|. Reasonable + // defaults will be used if passed |base::nullopt|. + // // This method is intended as a direct replacement for the old Resolve() // method, but it may not yet cover all the capabilities of the old method. // @@ -193,7 +223,8 @@ // capabilities of Resolve() and M/DnsClient functionality. virtual std::unique_ptr<ResolveHostRequest> CreateRequest( const HostPortPair& host, - const NetLogWithSource& net_log) = 0; + const NetLogWithSource& net_log, + const base::Optional<ResolveHostParameters>& optional_parameters) = 0; // DEPRECATION NOTE: This method is being replaced by CreateRequest(). New // callers should prefer CreateRequest() if it works for their needs. @@ -300,6 +331,18 @@ static std::unique_ptr<HostResolverImpl> CreateDefaultResolverImpl( NetLog* net_log); + static AddressFamily DnsQueryTypeToAddressFamily(DnsQueryType query_type); + + // Helpers for converting old Resolve() API parameters to new CreateRequest() + // parameters. + // + // TODO(crbug.com/821021): Delete these methods once all usage has been + // converted to the new CreateRequest() API. + static DnsQueryType AddressFamilyToDnsQueryType(AddressFamily address_family); + static ResolveHostParameters RequestInfoToResolveHostParameters( + const RequestInfo& request_info, + RequestPriority priority); + protected: HostResolver();
diff --git a/net/dns/host_resolver_impl.cc b/net/dns/host_resolver_impl.cc index 6b71265..77e2dc3 100644 --- a/net/dns/host_resolver_impl.cc +++ b/net/dns/host_resolver_impl.cc
@@ -617,35 +617,34 @@ public: RequestImpl(const NetLogWithSource& source_net_log, const HostPortPair& request_host, + const base::Optional<ResolveHostParameters>& optional_parameters, bool is_speculative, - RequestPriority priority, base::WeakPtr<HostResolverImpl> resolver) : RequestImpl(source_net_log, request_host, - ADDRESS_FAMILY_UNSPECIFIED, + optional_parameters, 0 /* host_resolver_flags */, true /* allow_cached_response */, is_speculative, - priority, resolver) {} // Overload for use by the legacy Resolve() API. Has more advanced parameters // not yet supported by the CreateRequest() API. RequestImpl(const NetLogWithSource& source_net_log, const HostPortPair& request_host, - AddressFamily address_family, + const base::Optional<ResolveHostParameters>& optional_parameters, HostResolverFlags host_resolver_flags, bool allow_cached_response, bool is_speculative, - RequestPriority priority, base::WeakPtr<HostResolverImpl> resolver) : source_net_log_(source_net_log), request_host_(request_host), - address_family_(address_family), host_resolver_flags_(host_resolver_flags), allow_cached_response_(allow_cached_response), is_speculative_(is_speculative), - priority_(priority), + parameters_(optional_parameters ? optional_parameters.value() + : ResolveHostParameters()), + priority_(parameters_.initial_priority), job_(nullptr), resolver_(resolver), complete_(false) {} @@ -730,14 +729,14 @@ const HostPortPair& request_host() const { return request_host_; } - AddressFamily address_family() const { return address_family_; } - HostResolverFlags host_resolver_flags() const { return host_resolver_flags_; } bool allow_cached_response() const { return allow_cached_response_; } bool is_speculative() const { return is_speculative_; } + const ResolveHostParameters& parameters() const { return parameters_; } + RequestPriority priority() const { return priority_; } void set_priority(RequestPriority priority) { priority_ = priority; } @@ -757,10 +756,10 @@ const NetLogWithSource source_net_log_; const HostPortPair request_host_; - const AddressFamily address_family_; const HostResolverFlags host_resolver_flags_; const bool allow_cached_response_; const bool is_speculative_; + const ResolveHostParameters parameters_; RequestPriority priority_; @@ -2141,11 +2140,13 @@ } std::unique_ptr<HostResolver::ResolveHostRequest> -HostResolverImpl::CreateRequest(const HostPortPair& host, - const NetLogWithSource& net_log) { - return std::make_unique<RequestImpl>( - net_log, host, false /* is_speculative */, - RequestPriority::DEFAULT_PRIORITY, weak_ptr_factory_.GetWeakPtr()); +HostResolverImpl::CreateRequest( + const HostPortPair& host, + const NetLogWithSource& net_log, + const base::Optional<ResolveHostParameters>& optional_parameters) { + return std::make_unique<RequestImpl>(net_log, host, optional_parameters, + false /* is_speculative */, + weak_ptr_factory_.GetWeakPtr()); } int HostResolverImpl::Resolve(const RequestInfo& info, @@ -2160,9 +2161,10 @@ DCHECK(out_req); auto request = std::make_unique<RequestImpl>( - source_net_log, info.host_port_pair(), info.address_family(), + source_net_log, info.host_port_pair(), + RequestInfoToResolveHostParameters(info, priority), info.host_resolver_flags(), info.allow_cached_response(), - info.is_speculative(), priority, weak_ptr_factory_.GetWeakPtr()); + info.is_speculative(), weak_ptr_factory_.GetWeakPtr()); auto wrapped_request = std::make_unique<LegacyRequestImpl>(std::move(request)); @@ -2190,9 +2192,10 @@ Key key; int rv = ResolveLocally( - info.host_port_pair(), info.address_family(), info.host_resolver_flags(), - info.allow_cached_response(), false /* allow_stale */, - nullptr /* stale_info */, source_net_log, addresses, &key); + info.host_port_pair(), AddressFamilyToDnsQueryType(info.address_family()), + info.host_resolver_flags(), info.allow_cached_response(), + false /* allow_stale */, nullptr /* stale_info */, source_net_log, + addresses, &key); LogFinishRequest(source_net_log, rv); return rv; @@ -2211,10 +2214,10 @@ LogStartRequest(source_net_log, info); Key key; - int rv = ResolveLocally(info.host_port_pair(), info.address_family(), - info.host_resolver_flags(), - info.allow_cached_response(), true /* allow_stale */, - stale_info, source_net_log, addresses, &key); + int rv = ResolveLocally( + info.host_port_pair(), AddressFamilyToDnsQueryType(info.address_family()), + info.host_resolver_flags(), info.allow_cached_response(), + true /* allow_stale */, stale_info, source_net_log, addresses, &key); LogFinishRequest(source_net_log, rv); return rv; } @@ -2349,11 +2352,11 @@ AddressList addresses; Key key; - int rv = ResolveLocally(request->request_host(), request->address_family(), - request->host_resolver_flags(), - request->allow_cached_response(), - false /* allow_stale */, nullptr /* stale_info */, - request->source_net_log(), &addresses, &key); + int rv = ResolveLocally( + request->request_host(), request->parameters().dns_query_type, + request->host_resolver_flags(), request->allow_cached_response(), + false /* allow_stale */, nullptr /* stale_info */, + request->source_net_log(), &addresses, &key); if (rv == OK) { request->set_address_results( EnsurePortOnAddressList(addresses, request->request_host().port())); @@ -2373,7 +2376,7 @@ } int HostResolverImpl::ResolveLocally(const HostPortPair& host, - AddressFamily requested_address_family, + DnsQueryType dns_query_type, HostResolverFlags flags, bool allow_cache, bool allow_stale, @@ -2393,7 +2396,7 @@ // Build a key that identifies the request in the cache and in the // outstanding jobs map. - *key = GetEffectiveKeyForRequest(host.host(), requested_address_family, flags, + *key = GetEffectiveKeyForRequest(host.host(), dns_query_type, flags, ip_address_ptr, source_net_log); DCHECK(allow_stale == !!stale_info); @@ -2620,12 +2623,14 @@ HostResolverImpl::Key HostResolverImpl::GetEffectiveKeyForRequest( const std::string& hostname, - AddressFamily requested_address_family, + DnsQueryType dns_query_type, HostResolverFlags flags, const IPAddress* ip_address, const NetLogWithSource& net_log) { HostResolverFlags effective_flags = flags | additional_resolver_flags_; - AddressFamily effective_address_family = requested_address_family; + + AddressFamily effective_address_family = + DnsQueryTypeToAddressFamily(dns_query_type); if (effective_address_family == ADDRESS_FAMILY_UNSPECIFIED && // When resolving IPv4 literals, there's no need to probe for IPv6.
diff --git a/net/dns/host_resolver_impl.h b/net/dns/host_resolver_impl.h index eea6dd5c6..41482fa 100644 --- a/net/dns/host_resolver_impl.h +++ b/net/dns/host_resolver_impl.h
@@ -137,7 +137,9 @@ // HostResolver methods: std::unique_ptr<ResolveHostRequest> CreateRequest( const HostPortPair& host, - const NetLogWithSource& net_log) override; + const NetLogWithSource& net_log, + const base::Optional<ResolveHostParameters>& optional_parameters) + override; int Resolve(const RequestInfo& info, RequestPriority priority, AddressList* addresses, @@ -228,7 +230,7 @@ // If |allow_stale| is false, then stale cache entries will not be returned, // and |stale_info| must be null. int ResolveLocally(const HostPortPair& host, - AddressFamily requested_address_family, + DnsQueryType requested_address_family, HostResolverFlags flags, bool allow_cache, bool allow_stale, @@ -283,7 +285,7 @@ // "effective" address family by inheriting the resolver's default address // family when the request leaves it unspecified. Key GetEffectiveKeyForRequest(const std::string& hostname, - AddressFamily requested_address_family, + DnsQueryType dns_query_type, HostResolverFlags flags, const IPAddress* ip_address, const NetLogWithSource& net_log);
diff --git a/net/dns/host_resolver_impl_unittest.cc b/net/dns/host_resolver_impl_unittest.cc index 6b05fbe..66cdcd4a 100644 --- a/net/dns/host_resolver_impl_unittest.cc +++ b/net/dns/host_resolver_impl_unittest.cc
@@ -746,7 +746,7 @@ proc_->SignalMultiple(1u); ResolveHostResponseHelper response(resolver_->CreateRequest( - HostPortPair("just.testing", 80), NetLogWithSource())); + HostPortPair("just.testing", 80), NetLogWithSource(), base::nullopt)); EXPECT_THAT(response.result_error(), IsOk()); EXPECT_THAT(response.request()->GetAddressResults().value().endpoints(), @@ -755,6 +755,31 @@ EXPECT_EQ("just.testing", proc_->GetCaptureList()[0].hostname); } +TEST_F(HostResolverImplTest, DnsQueryType) { + proc_->AddRule("host", ADDRESS_FAMILY_IPV4, "192.168.1.20"); + proc_->AddRule("host", ADDRESS_FAMILY_IPV6, "::5"); + + HostResolver::ResolveHostParameters parameters; + + parameters.dns_query_type = HostResolver::DnsQueryType::A; + ResolveHostResponseHelper v4_response(resolver_->CreateRequest( + HostPortPair("host", 80), NetLogWithSource(), parameters)); + + parameters.dns_query_type = HostResolver::DnsQueryType::AAAA; + ResolveHostResponseHelper v6_response(resolver_->CreateRequest( + HostPortPair("host", 80), NetLogWithSource(), parameters)); + + proc_->SignalMultiple(2u); + + EXPECT_THAT(v4_response.result_error(), IsOk()); + EXPECT_THAT(v4_response.request()->GetAddressResults().value().endpoints(), + testing::ElementsAre(CreateExpected("192.168.1.20", 80))); + + EXPECT_THAT(v6_response.result_error(), IsOk()); + EXPECT_THAT(v6_response.request()->GetAddressResults().value().endpoints(), + testing::ElementsAre(CreateExpected("::5", 80))); +} + TEST_F(HostResolverImplTest, LocalhostIPV4IPV6Lookup) { Request* req1 = CreateRequest("localhost6", 80, MEDIUM, ADDRESS_FAMILY_IPV4); EXPECT_THAT(req1->Resolve(), IsOk()); @@ -778,6 +803,53 @@ EXPECT_TRUE(req5->HasOneAddress("::1", 80)); } +TEST_F(HostResolverImplTest, LocalhostIPV4IPV6Lookup_ResolveHost) { + HostResolver::ResolveHostParameters parameters; + + parameters.dns_query_type = HostResolver::DnsQueryType::A; + ResolveHostResponseHelper v6_v4_response(resolver_->CreateRequest( + HostPortPair("localhost6", 80), NetLogWithSource(), parameters)); + EXPECT_THAT(v6_v4_response.result_error(), IsOk()); + EXPECT_THAT(v6_v4_response.request()->GetAddressResults().value().endpoints(), + testing::IsEmpty()); + + parameters.dns_query_type = HostResolver::DnsQueryType::AAAA; + ResolveHostResponseHelper v6_v6_response(resolver_->CreateRequest( + HostPortPair("localhost6", 80), NetLogWithSource(), parameters)); + EXPECT_THAT(v6_v6_response.result_error(), IsOk()); + EXPECT_THAT(v6_v6_response.request()->GetAddressResults().value().endpoints(), + testing::ElementsAre(CreateExpected("::1", 80))); + + ResolveHostResponseHelper v6_unsp_response(resolver_->CreateRequest( + HostPortPair("localhost6", 80), NetLogWithSource(), base::nullopt)); + EXPECT_THAT(v6_unsp_response.result_error(), IsOk()); + EXPECT_THAT( + v6_unsp_response.request()->GetAddressResults().value().endpoints(), + testing::ElementsAre(CreateExpected("::1", 80))); + + parameters.dns_query_type = HostResolver::DnsQueryType::A; + ResolveHostResponseHelper v4_v4_response(resolver_->CreateRequest( + HostPortPair("localhost", 80), NetLogWithSource(), parameters)); + EXPECT_THAT(v4_v4_response.result_error(), IsOk()); + EXPECT_THAT(v4_v4_response.request()->GetAddressResults().value().endpoints(), + testing::ElementsAre(CreateExpected("127.0.0.1", 80))); + + parameters.dns_query_type = HostResolver::DnsQueryType::AAAA; + ResolveHostResponseHelper v4_v6_response(resolver_->CreateRequest( + HostPortPair("localhost", 80), NetLogWithSource(), parameters)); + EXPECT_THAT(v4_v6_response.result_error(), IsOk()); + EXPECT_THAT(v4_v6_response.request()->GetAddressResults().value().endpoints(), + testing::ElementsAre(CreateExpected("::1", 80))); + + ResolveHostResponseHelper v4_unsp_response(resolver_->CreateRequest( + HostPortPair("localhost", 80), NetLogWithSource(), base::nullopt)); + EXPECT_THAT(v4_unsp_response.result_error(), IsOk()); + EXPECT_THAT( + v4_unsp_response.request()->GetAddressResults().value().endpoints(), + testing::UnorderedElementsAre(CreateExpected("127.0.0.1", 80), + CreateExpected("::1", 80))); +} + TEST_F(HostResolverImplTest, ResolveIPLiteralWithHostResolverSystemOnly) { const char kIpLiteral[] = "178.78.32.1"; // Add a mapping to tell if the resolver proc was called (if it was called, @@ -810,7 +882,7 @@ proc_->SignalMultiple(1u); ResolveHostResponseHelper response(resolver_->CreateRequest( - HostPortPair("just.testing", 80), NetLogWithSource())); + HostPortPair("just.testing", 80), NetLogWithSource(), base::nullopt)); EXPECT_THAT(response.result_error(), IsError(ERR_NAME_NOT_RESOLVED)); EXPECT_FALSE(response.request()->GetAddressResults()); @@ -839,7 +911,7 @@ proc_->SignalMultiple(1u); ResolveHostResponseHelper response(resolver_->CreateRequest( - HostPortPair("just.testing", 80), NetLogWithSource())); + HostPortPair("just.testing", 80), NetLogWithSource(), base::nullopt)); EXPECT_THAT(response.result_error(), IsError(ERR_NAME_NOT_RESOLVED)); EXPECT_FALSE(response.request()->GetAddressResults()); @@ -876,7 +948,7 @@ TEST_F(HostResolverImplTest, AbortedAsynchronousLookup_ResolveHost) { ResolveHostResponseHelper response0(resolver_->CreateRequest( - HostPortPair("just.testing", 80), NetLogWithSource())); + HostPortPair("just.testing", 80), NetLogWithSource(), base::nullopt)); ASSERT_FALSE(response0.complete()); ASSERT_TRUE(proc_->WaitFor(1u)); @@ -888,7 +960,7 @@ // To ensure there was no spurious callback, complete with a new resolver. CreateResolver(); ResolveHostResponseHelper response1(resolver_->CreateRequest( - HostPortPair("just.testing", 80), NetLogWithSource())); + HostPortPair("just.testing", 80), NetLogWithSource(), base::nullopt)); proc_->SignalMultiple(2u); @@ -921,7 +993,7 @@ #endif TEST_F(HostResolverImplTest, MAYBE_NumericIPv4Address_ResolveHost) { ResolveHostResponseHelper response(resolver_->CreateRequest( - HostPortPair("127.1.2.3", 5555), NetLogWithSource())); + HostPortPair("127.1.2.3", 5555), NetLogWithSource(), base::nullopt)); EXPECT_THAT(response.result_error(), IsOk()); EXPECT_THAT(response.request()->GetAddressResults().value().endpoints(), @@ -954,7 +1026,7 @@ // Resolve a plain IPv6 address. Don't worry about [brackets], because // the caller should have removed them. ResolveHostResponseHelper response(resolver_->CreateRequest( - HostPortPair("2001:db8::1", 5555), NetLogWithSource())); + HostPortPair("2001:db8::1", 5555), NetLogWithSource(), base::nullopt)); EXPECT_THAT(response.result_error(), IsOk()); EXPECT_THAT(response.request()->GetAddressResults().value().endpoints(), @@ -980,7 +1052,7 @@ #endif TEST_F(HostResolverImplTest, MAYBE_EmptyHost_ResolveHost) { ResolveHostResponseHelper response(resolver_->CreateRequest( - HostPortPair(std::string(), 5555), NetLogWithSource())); + HostPortPair(std::string(), 5555), NetLogWithSource(), base::nullopt)); EXPECT_THAT(response.result_error(), IsError(ERR_NAME_NOT_RESOLVED)); EXPECT_FALSE(response.request()->GetAddressResults()); @@ -1013,8 +1085,9 @@ #endif TEST_F(HostResolverImplTest, MAYBE_EmptyDotsHost_ResolveHost) { for (int i = 0; i < 16; ++i) { - ResolveHostResponseHelper response(resolver_->CreateRequest( - HostPortPair(std::string(i, '.'), 5555), NetLogWithSource())); + ResolveHostResponseHelper response( + resolver_->CreateRequest(HostPortPair(std::string(i, '.'), 5555), + NetLogWithSource(), base::nullopt)); EXPECT_THAT(response.result_error(), IsError(ERR_NAME_NOT_RESOLVED)); EXPECT_FALSE(response.request()->GetAddressResults()); @@ -1043,8 +1116,9 @@ #define MAYBE_LongHost_ResolveHost LongHost_ResolveHost #endif TEST_F(HostResolverImplTest, MAYBE_LongHost_ResolveHost) { - ResolveHostResponseHelper response(resolver_->CreateRequest( - HostPortPair(std::string(4097, 'a'), 5555), NetLogWithSource())); + ResolveHostResponseHelper response( + resolver_->CreateRequest(HostPortPair(std::string(4097, 'a'), 5555), + NetLogWithSource(), base::nullopt)); EXPECT_THAT(response.result_error(), IsError(ERR_NAME_NOT_RESOLVED)); EXPECT_FALSE(response.request()->GetAddressResults()); @@ -1070,16 +1144,21 @@ // Start 5 requests, duplicating hosts "a" and "b". Since the resolver_proc is // blocked, these should all pile up until we signal it. std::vector<std::unique_ptr<ResolveHostResponseHelper>> responses; - responses.emplace_back(std::make_unique<ResolveHostResponseHelper>( - resolver_->CreateRequest(HostPortPair("a", 80), NetLogWithSource()))); - responses.emplace_back(std::make_unique<ResolveHostResponseHelper>( - resolver_->CreateRequest(HostPortPair("b", 80), NetLogWithSource()))); - responses.emplace_back(std::make_unique<ResolveHostResponseHelper>( - resolver_->CreateRequest(HostPortPair("b", 81), NetLogWithSource()))); - responses.emplace_back(std::make_unique<ResolveHostResponseHelper>( - resolver_->CreateRequest(HostPortPair("a", 82), NetLogWithSource()))); - responses.emplace_back(std::make_unique<ResolveHostResponseHelper>( - resolver_->CreateRequest(HostPortPair("b", 83), NetLogWithSource()))); + responses.emplace_back( + std::make_unique<ResolveHostResponseHelper>(resolver_->CreateRequest( + HostPortPair("a", 80), NetLogWithSource(), base::nullopt))); + responses.emplace_back( + std::make_unique<ResolveHostResponseHelper>(resolver_->CreateRequest( + HostPortPair("b", 80), NetLogWithSource(), base::nullopt))); + responses.emplace_back( + std::make_unique<ResolveHostResponseHelper>(resolver_->CreateRequest( + HostPortPair("b", 81), NetLogWithSource(), base::nullopt))); + responses.emplace_back( + std::make_unique<ResolveHostResponseHelper>(resolver_->CreateRequest( + HostPortPair("a", 82), NetLogWithSource(), base::nullopt))); + responses.emplace_back( + std::make_unique<ResolveHostResponseHelper>(resolver_->CreateRequest( + HostPortPair("b", 83), NetLogWithSource(), base::nullopt))); for (auto& response : responses) { ASSERT_FALSE(response->complete()); @@ -1112,16 +1191,21 @@ TEST_F(HostResolverImplTest, CancelMultipleRequests_ResolveHost) { std::vector<std::unique_ptr<ResolveHostResponseHelper>> responses; - responses.emplace_back(std::make_unique<ResolveHostResponseHelper>( - resolver_->CreateRequest(HostPortPair("a", 80), NetLogWithSource()))); - responses.emplace_back(std::make_unique<ResolveHostResponseHelper>( - resolver_->CreateRequest(HostPortPair("b", 80), NetLogWithSource()))); - responses.emplace_back(std::make_unique<ResolveHostResponseHelper>( - resolver_->CreateRequest(HostPortPair("b", 81), NetLogWithSource()))); - responses.emplace_back(std::make_unique<ResolveHostResponseHelper>( - resolver_->CreateRequest(HostPortPair("a", 82), NetLogWithSource()))); - responses.emplace_back(std::make_unique<ResolveHostResponseHelper>( - resolver_->CreateRequest(HostPortPair("b", 83), NetLogWithSource()))); + responses.emplace_back( + std::make_unique<ResolveHostResponseHelper>(resolver_->CreateRequest( + HostPortPair("a", 80), NetLogWithSource(), base::nullopt))); + responses.emplace_back( + std::make_unique<ResolveHostResponseHelper>(resolver_->CreateRequest( + HostPortPair("b", 80), NetLogWithSource(), base::nullopt))); + responses.emplace_back( + std::make_unique<ResolveHostResponseHelper>(resolver_->CreateRequest( + HostPortPair("b", 81), NetLogWithSource(), base::nullopt))); + responses.emplace_back( + std::make_unique<ResolveHostResponseHelper>(resolver_->CreateRequest( + HostPortPair("a", 82), NetLogWithSource(), base::nullopt))); + responses.emplace_back( + std::make_unique<ResolveHostResponseHelper>(resolver_->CreateRequest( + HostPortPair("b", 83), NetLogWithSource(), base::nullopt))); for (auto& response : responses) { ASSERT_FALSE(response->complete()); @@ -1180,12 +1264,12 @@ responses.emplace_back( std::make_unique<ResolveHostResponseHelper>(resolver_->CreateRequest( - HostPortPair(hostname, 80), NetLogWithSource()))); + HostPortPair(hostname, 80), NetLogWithSource(), base::nullopt))); ASSERT_FALSE(responses.back()->complete()); responses.emplace_back( std::make_unique<ResolveHostResponseHelper>(resolver_->CreateRequest( - HostPortPair(hostname, 81), NetLogWithSource()))); + HostPortPair(hostname, 81), NetLogWithSource(), base::nullopt))); ASSERT_FALSE(responses.back()->complete()); } @@ -1253,20 +1337,23 @@ }); ResolveHostResponseHelper cancelling_response( - resolver_->CreateRequest(HostPortPair("a", 80), NetLogWithSource()), + resolver_->CreateRequest(HostPortPair("a", 80), NetLogWithSource(), + base::nullopt), std::move(custom_callback)); - responses.emplace_back(std::make_unique<ResolveHostResponseHelper>( - resolver_->CreateRequest(HostPortPair("a", 81), NetLogWithSource()))); - responses.emplace_back(std::make_unique<ResolveHostResponseHelper>( - resolver_->CreateRequest(HostPortPair("a", 82), NetLogWithSource()))); + responses.emplace_back( + std::make_unique<ResolveHostResponseHelper>(resolver_->CreateRequest( + HostPortPair("a", 81), NetLogWithSource(), base::nullopt))); + responses.emplace_back( + std::make_unique<ResolveHostResponseHelper>(resolver_->CreateRequest( + HostPortPair("a", 82), NetLogWithSource(), base::nullopt))); proc_->SignalMultiple(2u); // One for "a". One for "finalrequest". EXPECT_THAT(cancelling_response.result_error(), IsOk()); ResolveHostResponseHelper final_response(resolver_->CreateRequest( - HostPortPair("finalrequest", 70), NetLogWithSource())); + HostPortPair("finalrequest", 70), NetLogWithSource(), base::nullopt)); EXPECT_THAT(final_response.result_error(), IsOk()); for (auto& response : responses) { @@ -1317,16 +1404,19 @@ }); ResolveHostResponseHelper deleting_response( - resolver_->CreateRequest(HostPortPair("a", 80), NetLogWithSource()), + resolver_->CreateRequest(HostPortPair("a", 80), NetLogWithSource(), + base::nullopt), std::move(custom_callback)); // Start additional requests to be cancelled as part of the first's deletion. // Assumes all requests for a job are handled in order so that the deleting // request will run first and cancel the rest. - responses.emplace_back(std::make_unique<ResolveHostResponseHelper>( - resolver_->CreateRequest(HostPortPair("a", 81), NetLogWithSource()))); - responses.emplace_back(std::make_unique<ResolveHostResponseHelper>( - resolver_->CreateRequest(HostPortPair("a", 82), NetLogWithSource()))); + responses.emplace_back( + std::make_unique<ResolveHostResponseHelper>(resolver_->CreateRequest( + HostPortPair("a", 81), NetLogWithSource(), base::nullopt))); + responses.emplace_back( + std::make_unique<ResolveHostResponseHelper>(resolver_->CreateRequest( + HostPortPair("a", 82), NetLogWithSource(), base::nullopt))); proc_->SignalMultiple(3u); @@ -1395,15 +1485,19 @@ }); ResolveHostResponseHelper deleting_response( - resolver_->CreateRequest(HostPortPair("a", 80), NetLogWithSource()), + resolver_->CreateRequest(HostPortPair("a", 80), NetLogWithSource(), + base::nullopt), std::move(custom_callback)); - responses.emplace_back(std::make_unique<ResolveHostResponseHelper>( - resolver_->CreateRequest(HostPortPair("a", 81), NetLogWithSource()))); - responses.emplace_back(std::make_unique<ResolveHostResponseHelper>( - resolver_->CreateRequest(HostPortPair("b", 82), NetLogWithSource()))); - responses.emplace_back(std::make_unique<ResolveHostResponseHelper>( - resolver_->CreateRequest(HostPortPair("b", 83), NetLogWithSource()))); + responses.emplace_back( + std::make_unique<ResolveHostResponseHelper>(resolver_->CreateRequest( + HostPortPair("a", 81), NetLogWithSource(), base::nullopt))); + responses.emplace_back( + std::make_unique<ResolveHostResponseHelper>(resolver_->CreateRequest( + HostPortPair("b", 82), NetLogWithSource(), base::nullopt))); + responses.emplace_back( + std::make_unique<ResolveHostResponseHelper>(resolver_->CreateRequest( + HostPortPair("b", 83), NetLogWithSource(), base::nullopt))); // Wait for all calls to queue up, trigger abort via IP address change, then // signal all the queued requests to let them all try to finish. @@ -1455,12 +1549,13 @@ [&](CompletionOnceCallback completion_callback, int error) { new_response = std::make_unique<ResolveHostResponseHelper>( resolver_->CreateRequest(HostPortPair("new", 70), - NetLogWithSource())); + NetLogWithSource(), base::nullopt)); std::move(completion_callback).Run(error); }); ResolveHostResponseHelper starting_response( - resolver_->CreateRequest(HostPortPair("a", 80), NetLogWithSource()), + resolver_->CreateRequest(HostPortPair("a", 80), NetLogWithSource(), + base::nullopt), std::move(custom_callback)); proc_->SignalMultiple(2u); // One for "a". One for "new". @@ -1538,20 +1633,20 @@ TEST_F(HostResolverImplTest, FlushCacheOnIPAddressChange_ResolveHost) { proc_->SignalMultiple(2u); // One before the flush, one after. - ResolveHostResponseHelper initial_response( - resolver_->CreateRequest(HostPortPair("host1", 70), NetLogWithSource())); + ResolveHostResponseHelper initial_response(resolver_->CreateRequest( + HostPortPair("host1", 70), NetLogWithSource(), base::nullopt)); EXPECT_THAT(initial_response.result_error(), IsOk()); EXPECT_EQ(1u, proc_->GetCaptureList().size()); - ResolveHostResponseHelper cached_response( - resolver_->CreateRequest(HostPortPair("host1", 75), NetLogWithSource())); + ResolveHostResponseHelper cached_response(resolver_->CreateRequest( + HostPortPair("host1", 75), NetLogWithSource(), base::nullopt)); EXPECT_THAT(cached_response.result_error(), IsOk()); EXPECT_EQ(1u, proc_->GetCaptureList().size()); // No expected increase. // Verify initial DNS config read does not flush cache. NetworkChangeNotifier::NotifyObserversOfInitialDNSConfigReadForTests(); - ResolveHostResponseHelper unflushed_response( - resolver_->CreateRequest(HostPortPair("host1", 75), NetLogWithSource())); + ResolveHostResponseHelper unflushed_response(resolver_->CreateRequest( + HostPortPair("host1", 75), NetLogWithSource(), base::nullopt)); EXPECT_THAT(unflushed_response.result_error(), IsOk()); EXPECT_EQ(1u, proc_->GetCaptureList().size()); // No expected increase. @@ -1561,8 +1656,8 @@ // Resolve "host1" again -- this time it won't be served from cache, so it // will complete asynchronously. - ResolveHostResponseHelper flushed_response( - resolver_->CreateRequest(HostPortPair("host1", 80), NetLogWithSource())); + ResolveHostResponseHelper flushed_response(resolver_->CreateRequest( + HostPortPair("host1", 80), NetLogWithSource(), base::nullopt)); EXPECT_THAT(flushed_response.result_error(), IsOk()); EXPECT_EQ(2u, proc_->GetCaptureList().size()); // Expected increase. } @@ -1584,8 +1679,8 @@ // Test that IP address changes send ERR_NETWORK_CHANGED to pending requests. TEST_F(HostResolverImplTest, AbortOnIPAddressChanged_ResolveHost) { - ResolveHostResponseHelper response( - resolver_->CreateRequest(HostPortPair("host1", 70), NetLogWithSource())); + ResolveHostResponseHelper response(resolver_->CreateRequest( + HostPortPair("host1", 70), NetLogWithSource(), base::nullopt)); ASSERT_FALSE(response.complete()); ASSERT_TRUE(proc_->WaitFor(1u)); @@ -1616,8 +1711,8 @@ // Test that initial DNS config read signals do not abort pending requests. TEST_F(HostResolverImplTest, DontAbortOnInitialDNSConfigRead_ResolveHost) { - ResolveHostResponseHelper response( - resolver_->CreateRequest(HostPortPair("host1", 70), NetLogWithSource())); + ResolveHostResponseHelper response(resolver_->CreateRequest( + HostPortPair("host1", 70), NetLogWithSource(), base::nullopt)); ASSERT_FALSE(response.complete()); ASSERT_TRUE(proc_->WaitFor(1u)); @@ -1663,12 +1758,15 @@ CreateSerialResolver(); std::vector<std::unique_ptr<ResolveHostResponseHelper>> responses; - responses.emplace_back(std::make_unique<ResolveHostResponseHelper>( - resolver_->CreateRequest(HostPortPair("a", 80), NetLogWithSource()))); - responses.emplace_back(std::make_unique<ResolveHostResponseHelper>( - resolver_->CreateRequest(HostPortPair("b", 80), NetLogWithSource()))); - responses.emplace_back(std::make_unique<ResolveHostResponseHelper>( - resolver_->CreateRequest(HostPortPair("c", 80), NetLogWithSource()))); + responses.emplace_back( + std::make_unique<ResolveHostResponseHelper>(resolver_->CreateRequest( + HostPortPair("a", 80), NetLogWithSource(), base::nullopt))); + responses.emplace_back( + std::make_unique<ResolveHostResponseHelper>(resolver_->CreateRequest( + HostPortPair("b", 80), NetLogWithSource(), base::nullopt))); + responses.emplace_back( + std::make_unique<ResolveHostResponseHelper>(resolver_->CreateRequest( + HostPortPair("c", 80), NetLogWithSource(), base::nullopt))); for (auto& response : responses) { ASSERT_FALSE(response->complete()); @@ -1748,24 +1846,28 @@ std::unique_ptr<ResolveHostResponseHelper>* next_response, CompletionOnceCallback completion_callback, int error) { *next_response = std::make_unique<ResolveHostResponseHelper>( - resolver_->CreateRequest(next_host, NetLogWithSource())); + resolver_->CreateRequest(next_host, NetLogWithSource(), + base::nullopt)); std::move(completion_callback).Run(error); }); std::vector<std::unique_ptr<ResolveHostResponseHelper>> next_responses(3); ResolveHostResponseHelper response0( - resolver_->CreateRequest(HostPortPair("bbb", 80), NetLogWithSource()), + resolver_->CreateRequest(HostPortPair("bbb", 80), NetLogWithSource(), + base::nullopt), base::BindOnce(custom_callback_template, HostPortPair("zzz", 80), &next_responses[0])); ResolveHostResponseHelper response1( - resolver_->CreateRequest(HostPortPair("eee", 80), NetLogWithSource()), + resolver_->CreateRequest(HostPortPair("eee", 80), NetLogWithSource(), + base::nullopt), base::BindOnce(custom_callback_template, HostPortPair("aaa", 80), &next_responses[1])); ResolveHostResponseHelper response2( - resolver_->CreateRequest(HostPortPair("ccc", 80), NetLogWithSource()), + resolver_->CreateRequest(HostPortPair("ccc", 80), NetLogWithSource(), + base::nullopt), base::BindOnce(custom_callback_template, HostPortPair("eee", 80), &next_responses[2])); @@ -1799,7 +1901,6 @@ // Tests that when the maximum threads is set to 1, requests are dequeued // in order of priority. -// TODO(crbug.com/821021): Add ResolveHost test once priorities are supported. TEST_F(HostResolverImplTest, HigherPriorityRequestsStartedFirst) { CreateSerialResolver(); @@ -1842,8 +1943,78 @@ EXPECT_EQ("req6", capture_list[6].hostname); } +// Tests that when the maximum threads is set to 1, requests are dequeued +// in order of priority. +TEST_F(HostResolverImplTest, HigherPriorityRequestsStartedFirst_ResolveHost) { + CreateSerialResolver(); + + HostResolver::ResolveHostParameters low_priority; + low_priority.initial_priority = LOW; + HostResolver::ResolveHostParameters medium_priority; + medium_priority.initial_priority = MEDIUM; + HostResolver::ResolveHostParameters highest_priority; + highest_priority.initial_priority = HIGHEST; + + // Note that at this point the MockHostResolverProc is blocked, so any + // requests we make will not complete. + + std::vector<std::unique_ptr<ResolveHostResponseHelper>> responses; + responses.emplace_back( + std::make_unique<ResolveHostResponseHelper>(resolver_->CreateRequest( + HostPortPair("req0", 80), NetLogWithSource(), low_priority))); + responses.emplace_back( + std::make_unique<ResolveHostResponseHelper>(resolver_->CreateRequest( + HostPortPair("req1", 80), NetLogWithSource(), medium_priority))); + responses.emplace_back( + std::make_unique<ResolveHostResponseHelper>(resolver_->CreateRequest( + HostPortPair("req2", 80), NetLogWithSource(), medium_priority))); + responses.emplace_back( + std::make_unique<ResolveHostResponseHelper>(resolver_->CreateRequest( + HostPortPair("req3", 80), NetLogWithSource(), low_priority))); + responses.emplace_back( + std::make_unique<ResolveHostResponseHelper>(resolver_->CreateRequest( + HostPortPair("req4", 80), NetLogWithSource(), highest_priority))); + responses.emplace_back( + std::make_unique<ResolveHostResponseHelper>(resolver_->CreateRequest( + HostPortPair("req5", 80), NetLogWithSource(), low_priority))); + responses.emplace_back( + std::make_unique<ResolveHostResponseHelper>(resolver_->CreateRequest( + HostPortPair("req6", 80), NetLogWithSource(), low_priority))); + responses.emplace_back( + std::make_unique<ResolveHostResponseHelper>(resolver_->CreateRequest( + HostPortPair("req5", 80), NetLogWithSource(), highest_priority))); + + for (const auto& response : responses) { + ASSERT_FALSE(response->complete()); + } + + // Unblock the resolver thread so the requests can run. + proc_->SignalMultiple(responses.size()); // More than needed. + + // Wait for all the requests to complete successfully. + for (auto& response : responses) { + EXPECT_THAT(response->result_error(), IsOk()); + } + + // Since we have restricted to a single concurrent thread in the jobpool, + // the requests should complete in order of priority (with the exception + // of the first request, which gets started right away, since there is + // nothing outstanding). + MockHostResolverProc::CaptureList capture_list = proc_->GetCaptureList(); + ASSERT_EQ(7u, capture_list.size()); + + EXPECT_EQ("req0", capture_list[0].hostname); + EXPECT_EQ("req4", capture_list[1].hostname); + EXPECT_EQ("req5", capture_list[2].hostname); + EXPECT_EQ("req1", capture_list[3].hostname); + EXPECT_EQ("req2", capture_list[4].hostname); + EXPECT_EQ("req3", capture_list[5].hostname); + EXPECT_EQ("req6", capture_list[6].hostname); +} + // Test that changing a job's priority affects the dequeueing order. -// TODO(crbug.com/821021): Add ResolveHost test once priorities are supported. +// TODO(crbug.com/821021): Add ResolveHost test once changing priorities is +// supported. TEST_F(HostResolverImplTest, ChangePriority) { CreateSerialResolver(); @@ -1922,25 +2093,40 @@ } // Try cancelling a job which has not started yet. -// TODO(crbug.com/821021): Add tests for priorities once supported. TEST_F(HostResolverImplTest, CancelPendingRequest_ResolveHost) { CreateSerialResolver(); + HostResolver::ResolveHostParameters lowest_priority; + lowest_priority.initial_priority = LOWEST; + HostResolver::ResolveHostParameters low_priority; + low_priority.initial_priority = LOW; + HostResolver::ResolveHostParameters medium_priority; + medium_priority.initial_priority = MEDIUM; + HostResolver::ResolveHostParameters highest_priority; + highest_priority.initial_priority = HIGHEST; + std::vector<std::unique_ptr<ResolveHostResponseHelper>> responses; - responses.emplace_back(std::make_unique<ResolveHostResponseHelper>( - resolver_->CreateRequest(HostPortPair("req0", 80), NetLogWithSource()))); - responses.emplace_back(std::make_unique<ResolveHostResponseHelper>( - resolver_->CreateRequest(HostPortPair("req1", 80), NetLogWithSource()))); - responses.emplace_back(std::make_unique<ResolveHostResponseHelper>( - resolver_->CreateRequest(HostPortPair("req2", 80), NetLogWithSource()))); - responses.emplace_back(std::make_unique<ResolveHostResponseHelper>( - resolver_->CreateRequest(HostPortPair("req3", 80), NetLogWithSource()))); - responses.emplace_back(std::make_unique<ResolveHostResponseHelper>( - resolver_->CreateRequest(HostPortPair("req4", 80), NetLogWithSource()))); - responses.emplace_back(std::make_unique<ResolveHostResponseHelper>( - resolver_->CreateRequest(HostPortPair("req5", 80), NetLogWithSource()))); - responses.emplace_back(std::make_unique<ResolveHostResponseHelper>( - resolver_->CreateRequest(HostPortPair("req6", 80), NetLogWithSource()))); + responses.emplace_back( + std::make_unique<ResolveHostResponseHelper>(resolver_->CreateRequest( + HostPortPair("req0", 80), NetLogWithSource(), lowest_priority))); + responses.emplace_back( + std::make_unique<ResolveHostResponseHelper>(resolver_->CreateRequest( + HostPortPair("req1", 80), NetLogWithSource(), highest_priority))); + responses.emplace_back( + std::make_unique<ResolveHostResponseHelper>(resolver_->CreateRequest( + HostPortPair("req2", 80), NetLogWithSource(), medium_priority))); + responses.emplace_back( + std::make_unique<ResolveHostResponseHelper>(resolver_->CreateRequest( + HostPortPair("req3", 80), NetLogWithSource(), low_priority))); + responses.emplace_back( + std::make_unique<ResolveHostResponseHelper>(resolver_->CreateRequest( + HostPortPair("req4", 80), NetLogWithSource(), highest_priority))); + responses.emplace_back( + std::make_unique<ResolveHostResponseHelper>(resolver_->CreateRequest( + HostPortPair("req5", 80), NetLogWithSource(), lowest_priority))); + responses.emplace_back( + std::make_unique<ResolveHostResponseHelper>(resolver_->CreateRequest( + HostPortPair("req6", 80), NetLogWithSource(), medium_priority))); // Cancel some requests responses[1]->CancelRequest(); @@ -1971,8 +2157,8 @@ EXPECT_EQ("req0", capture_list[0].hostname); EXPECT_EQ("req2", capture_list[1].hostname); - EXPECT_EQ("req3", capture_list[2].hostname); - EXPECT_EQ("req6", capture_list[3].hostname); + EXPECT_EQ("req6", capture_list[2].hostname); + EXPECT_EQ("req3", capture_list[3].hostname); } // Test that when too many requests are enqueued, old ones start to be aborted. @@ -2043,8 +2229,6 @@ } // Test that when too many requests are enqueued, old ones start to be aborted. -// TODO(crbug.com/821021): Once ResolveHost supports priorities, test that the -// queue evictions happen by priority. TEST_F(HostResolverImplTest, QueueOverflow_ResolveHost) { CreateSerialResolver(); @@ -2052,45 +2236,62 @@ const size_t kMaxPendingJobs = 3u; resolver_->SetMaxQueuedJobsForTesting(kMaxPendingJobs); + HostResolver::ResolveHostParameters lowest_priority; + lowest_priority.initial_priority = LOWEST; + HostResolver::ResolveHostParameters low_priority; + low_priority.initial_priority = LOW; + HostResolver::ResolveHostParameters medium_priority; + medium_priority.initial_priority = MEDIUM; + HostResolver::ResolveHostParameters highest_priority; + highest_priority.initial_priority = HIGHEST; + // Note that at this point the MockHostResolverProc is blocked, so any // requests we make will not complete. std::vector<std::unique_ptr<ResolveHostResponseHelper>> responses; - responses.emplace_back(std::make_unique<ResolveHostResponseHelper>( - resolver_->CreateRequest(HostPortPair("req0", 80), NetLogWithSource()))); - responses.emplace_back(std::make_unique<ResolveHostResponseHelper>( - resolver_->CreateRequest(HostPortPair("req1", 80), NetLogWithSource()))); - responses.emplace_back(std::make_unique<ResolveHostResponseHelper>( - resolver_->CreateRequest(HostPortPair("req2", 80), NetLogWithSource()))); - responses.emplace_back(std::make_unique<ResolveHostResponseHelper>( - resolver_->CreateRequest(HostPortPair("req3", 80), NetLogWithSource()))); + responses.emplace_back( + std::make_unique<ResolveHostResponseHelper>(resolver_->CreateRequest( + HostPortPair("req0", 80), NetLogWithSource(), lowest_priority))); + responses.emplace_back( + std::make_unique<ResolveHostResponseHelper>(resolver_->CreateRequest( + HostPortPair("req1", 80), NetLogWithSource(), highest_priority))); + responses.emplace_back( + std::make_unique<ResolveHostResponseHelper>(resolver_->CreateRequest( + HostPortPair("req2", 80), NetLogWithSource(), medium_priority))); + responses.emplace_back( + std::make_unique<ResolveHostResponseHelper>(resolver_->CreateRequest( + HostPortPair("req3", 80), NetLogWithSource(), medium_priority))); // At this point, there are 3 enqueued jobs (and one "running" job). // Insertion of subsequent requests will cause evictions. - responses.emplace_back(std::make_unique<ResolveHostResponseHelper>( - resolver_->CreateRequest(HostPortPair("req4", 80), NetLogWithSource()))); - EXPECT_THAT(responses[1]->result_error(), - IsError(ERR_HOST_RESOLVER_QUEUE_TOO_LARGE)); - EXPECT_FALSE(responses[1]->request()->GetAddressResults()); + responses.emplace_back( + std::make_unique<ResolveHostResponseHelper>(resolver_->CreateRequest( + HostPortPair("req4", 80), NetLogWithSource(), low_priority))); + EXPECT_THAT(responses[4]->result_error(), + IsError(ERR_HOST_RESOLVER_QUEUE_TOO_LARGE)); // Evicts self. + EXPECT_FALSE(responses[4]->request()->GetAddressResults()); - responses.emplace_back(std::make_unique<ResolveHostResponseHelper>( - resolver_->CreateRequest(HostPortPair("req5", 80), NetLogWithSource()))); + responses.emplace_back( + std::make_unique<ResolveHostResponseHelper>(resolver_->CreateRequest( + HostPortPair("req5", 80), NetLogWithSource(), medium_priority))); EXPECT_THAT(responses[2]->result_error(), IsError(ERR_HOST_RESOLVER_QUEUE_TOO_LARGE)); EXPECT_FALSE(responses[2]->request()->GetAddressResults()); - responses.emplace_back(std::make_unique<ResolveHostResponseHelper>( - resolver_->CreateRequest(HostPortPair("req6", 80), NetLogWithSource()))); + responses.emplace_back( + std::make_unique<ResolveHostResponseHelper>(resolver_->CreateRequest( + HostPortPair("req6", 80), NetLogWithSource(), highest_priority))); EXPECT_THAT(responses[3]->result_error(), IsError(ERR_HOST_RESOLVER_QUEUE_TOO_LARGE)); EXPECT_FALSE(responses[3]->request()->GetAddressResults()); - responses.emplace_back(std::make_unique<ResolveHostResponseHelper>( - resolver_->CreateRequest(HostPortPair("req7", 80), NetLogWithSource()))); - EXPECT_THAT(responses[4]->result_error(), + responses.emplace_back( + std::make_unique<ResolveHostResponseHelper>(resolver_->CreateRequest( + HostPortPair("req7", 80), NetLogWithSource(), medium_priority))); + EXPECT_THAT(responses[5]->result_error(), IsError(ERR_HOST_RESOLVER_QUEUE_TOO_LARGE)); - EXPECT_FALSE(responses[4]->request()->GetAddressResults()); + EXPECT_FALSE(responses[5]->request()->GetAddressResults()); // Unblock the resolver thread so the requests can run. proc_->SignalMultiple(4u); @@ -2098,8 +2299,8 @@ // The rest should succeed. EXPECT_THAT(responses[0]->result_error(), IsOk()); EXPECT_TRUE(responses[0]->request()->GetAddressResults()); - EXPECT_THAT(responses[5]->result_error(), IsOk()); - EXPECT_TRUE(responses[5]->request()->GetAddressResults()); + EXPECT_THAT(responses[1]->result_error(), IsOk()); + EXPECT_TRUE(responses[1]->request()->GetAddressResults()); EXPECT_THAT(responses[6]->result_error(), IsOk()); EXPECT_TRUE(responses[6]->request()->GetAddressResults()); EXPECT_THAT(responses[7]->result_error(), IsOk()); @@ -2111,7 +2312,7 @@ ASSERT_EQ(4u, capture_list.size()); EXPECT_EQ("req0", capture_list[0].hostname); - EXPECT_EQ("req5", capture_list[1].hostname); + EXPECT_EQ("req1", capture_list[1].hostname); EXPECT_EQ("req6", capture_list[2].hostname); EXPECT_EQ("req7", capture_list[3].hostname); @@ -2131,11 +2332,11 @@ // Note that at this point the MockHostResolverProc is blocked, so any // requests we make will not complete. - ResolveHostResponseHelper run_response( - resolver_->CreateRequest(HostPortPair("run", 80), NetLogWithSource())); + ResolveHostResponseHelper run_response(resolver_->CreateRequest( + HostPortPair("run", 80), NetLogWithSource(), base::nullopt)); - ResolveHostResponseHelper evict_response( - resolver_->CreateRequest(HostPortPair("req1", 80), NetLogWithSource())); + ResolveHostResponseHelper evict_response(resolver_->CreateRequest( + HostPortPair("req1", 80), NetLogWithSource(), base::nullopt)); EXPECT_THAT(evict_response.result_error(), IsError(ERR_HOST_RESOLVER_QUEUE_TOO_LARGE)); EXPECT_FALSE(evict_response.request()->GetAddressResults()); @@ -2148,8 +2349,6 @@ // Make sure that the address family parameter is respected when raw IPs are // passed in. -// TODO(crbug.com/821021): Make an equivalent ResolveHost test once specifying -// A or AAAA is implemented. TEST_F(HostResolverImplTest, AddressFamilyWithRawIPs) { Request* request = CreateRequest("127.0.0.1", 80, MEDIUM, ADDRESS_FAMILY_IPV4); @@ -2175,6 +2374,50 @@ EXPECT_TRUE(request->HasOneAddress("::1", 80)); } +// Make sure that the dns query type parameter is respected when raw IPs are +// passed in. +TEST_F(HostResolverImplTest, AddressFamilyWithRawIPs_ResolveHost) { + HostResolver::ResolveHostParameters v4_parameters; + v4_parameters.dns_query_type = HostResolver::DnsQueryType::A; + + HostResolver::ResolveHostParameters v6_parameters; + v6_parameters.dns_query_type = HostResolver::DnsQueryType::AAAA; + + ResolveHostResponseHelper v4_v4_request(resolver_->CreateRequest( + HostPortPair("127.0.0.1", 80), NetLogWithSource(), v4_parameters)); + EXPECT_THAT(v4_v4_request.result_error(), IsOk()); + EXPECT_THAT(v4_v4_request.request()->GetAddressResults().value().endpoints(), + testing::ElementsAre(CreateExpected("127.0.0.1", 80))); + + ResolveHostResponseHelper v4_v6_request(resolver_->CreateRequest( + HostPortPair("127.0.0.1", 80), NetLogWithSource(), v6_parameters)); + EXPECT_THAT(v4_v6_request.result_error(), IsError(ERR_NAME_NOT_RESOLVED)); + + ResolveHostResponseHelper v4_unsp_request(resolver_->CreateRequest( + HostPortPair("127.0.0.1", 80), NetLogWithSource(), base::nullopt)); + EXPECT_THAT(v4_unsp_request.result_error(), IsOk()); + EXPECT_THAT( + v4_unsp_request.request()->GetAddressResults().value().endpoints(), + testing::ElementsAre(CreateExpected("127.0.0.1", 80))); + + ResolveHostResponseHelper v6_v4_request(resolver_->CreateRequest( + HostPortPair("::1", 80), NetLogWithSource(), v4_parameters)); + EXPECT_THAT(v6_v4_request.result_error(), IsError(ERR_NAME_NOT_RESOLVED)); + + ResolveHostResponseHelper v6_v6_request(resolver_->CreateRequest( + HostPortPair("::1", 80), NetLogWithSource(), v6_parameters)); + EXPECT_THAT(v6_v6_request.result_error(), IsOk()); + EXPECT_THAT(v6_v6_request.request()->GetAddressResults().value().endpoints(), + testing::ElementsAre(CreateExpected("::1", 80))); + + ResolveHostResponseHelper v6_unsp_request(resolver_->CreateRequest( + HostPortPair("::1", 80), NetLogWithSource(), base::nullopt)); + EXPECT_THAT(v6_unsp_request.result_error(), IsOk()); + EXPECT_THAT( + v6_unsp_request.request()->GetAddressResults().value().endpoints(), + testing::ElementsAre(CreateExpected("::1", 80))); +} + TEST_F(HostResolverImplTest, ResolveFromCache) { proc_->AddRuleForAllFamilies("just.testing", "192.168.1.42"); proc_->SignalMultiple(1u); // Need only one. @@ -2400,8 +2643,8 @@ base::ThreadTaskRunnerHandle::OverrideForTesting(test_task_runner); // Resolve "host1". - ResolveHostResponseHelper response( - resolver_->CreateRequest(HostPortPair("host1", 70), NetLogWithSource())); + ResolveHostResponseHelper response(resolver_->CreateRequest( + HostPortPair("host1", 70), NetLogWithSource(), base::nullopt)); EXPECT_FALSE(response.complete()); resolver_proc->WaitForNAttemptsToBeBlocked(1); @@ -2496,8 +2739,8 @@ proc_->AddRuleForAllFamilies("not_reserved3", "10.0.53.53"); proc_->SignalMultiple(6u); - ResolveHostResponseHelper single_response( - resolver_->CreateRequest(HostPortPair("single", 80), NetLogWithSource())); + ResolveHostResponseHelper single_response(resolver_->CreateRequest( + HostPortPair("single", 80), NetLogWithSource(), base::nullopt)); EXPECT_THAT(single_response.result_error(), IsError(ERR_ICANN_NAME_COLLISION)); EXPECT_FALSE(single_response.request()->GetAddressResults()); @@ -2509,33 +2752,33 @@ EXPECT_THAT(cache_request->ResolveFromCache(), IsError(ERR_DNS_CACHE_MISS)); ResolveHostResponseHelper multiple_response(resolver_->CreateRequest( - HostPortPair("multiple", 80), NetLogWithSource())); + HostPortPair("multiple", 80), NetLogWithSource(), base::nullopt)); EXPECT_THAT(multiple_response.result_error(), IsError(ERR_ICANN_NAME_COLLISION)); // Resolving an IP literal of 127.0.53.53 however is allowed. ResolveHostResponseHelper literal_response(resolver_->CreateRequest( - HostPortPair("127.0.53.53", 80), NetLogWithSource())); + HostPortPair("127.0.53.53", 80), NetLogWithSource(), base::nullopt)); EXPECT_THAT(literal_response.result_error(), IsOk()); // Moreover the address should not be recognized when embedded in an IPv6 // address. ResolveHostResponseHelper ipv6_response(resolver_->CreateRequest( - HostPortPair("127.0.53.53", 80), NetLogWithSource())); + HostPortPair("127.0.53.53", 80), NetLogWithSource(), base::nullopt)); EXPECT_THAT(ipv6_response.result_error(), IsOk()); // Try some other IPs which are similar, but NOT an exact match on // 127.0.53.53. ResolveHostResponseHelper similar_response1(resolver_->CreateRequest( - HostPortPair("not_reserved1", 80), NetLogWithSource())); + HostPortPair("not_reserved1", 80), NetLogWithSource(), base::nullopt)); EXPECT_THAT(similar_response1.result_error(), IsOk()); ResolveHostResponseHelper similar_response2(resolver_->CreateRequest( - HostPortPair("not_reserved2", 80), NetLogWithSource())); + HostPortPair("not_reserved2", 80), NetLogWithSource(), base::nullopt)); EXPECT_THAT(similar_response2.result_error(), IsOk()); ResolveHostResponseHelper similar_response3(resolver_->CreateRequest( - HostPortPair("not_reserved3", 80), NetLogWithSource())); + HostPortPair("not_reserved3", 80), NetLogWithSource(), base::nullopt)); EXPECT_THAT(similar_response3.result_error(), IsOk()); } @@ -2813,21 +3056,21 @@ proc_->AddRuleForAllFamilies("localhost.", "192.168.1.42"); ResolveHostResponseHelper response0(resolver_->CreateRequest( - HostPortPair("foo.localhost", 80), NetLogWithSource())); + HostPortPair("foo.localhost", 80), NetLogWithSource(), base::nullopt)); EXPECT_THAT(response0.result_error(), IsOk()); EXPECT_THAT(response0.request()->GetAddressResults().value().endpoints(), testing::UnorderedElementsAre(CreateExpected("127.0.0.1", 80), CreateExpected("::1", 80))); ResolveHostResponseHelper response1(resolver_->CreateRequest( - HostPortPair("localhost", 80), NetLogWithSource())); + HostPortPair("localhost", 80), NetLogWithSource(), base::nullopt)); EXPECT_THAT(response1.result_error(), IsOk()); EXPECT_THAT(response1.request()->GetAddressResults().value().endpoints(), testing::UnorderedElementsAre(CreateExpected("127.0.0.1", 80), CreateExpected("::1", 80))); ResolveHostResponseHelper response2(resolver_->CreateRequest( - HostPortPair("localhost.", 80), NetLogWithSource())); + HostPortPair("localhost.", 80), NetLogWithSource(), base::nullopt)); EXPECT_THAT(response2.result_error(), IsOk()); EXPECT_THAT(response2.request()->GetAddressResults().value().endpoints(), testing::UnorderedElementsAre(CreateExpected("127.0.0.1", 80), @@ -2874,14 +3117,14 @@ ChangeDnsConfig(config); ResolveHostResponseHelper response0(resolver_->CreateRequest( - HostPortPair("localhost", 80), NetLogWithSource())); + HostPortPair("localhost", 80), NetLogWithSource(), base::nullopt)); EXPECT_THAT(response0.result_error(), IsOk()); EXPECT_THAT(response0.request()->GetAddressResults().value().endpoints(), testing::UnorderedElementsAre(CreateExpected("127.0.0.1", 80), CreateExpected("::1", 80))); ResolveHostResponseHelper response1(resolver_->CreateRequest( - HostPortPair("foo.localhost", 80), NetLogWithSource())); + HostPortPair("foo.localhost", 80), NetLogWithSource(), base::nullopt)); EXPECT_THAT(response1.result_error(), IsOk()); EXPECT_THAT(response1.request()->GetAddressResults().value().endpoints(), testing::UnorderedElementsAre(CreateExpected("127.0.0.1", 80), @@ -2943,7 +3186,7 @@ // Initially there is no config, so client should not be invoked. ResolveHostResponseHelper initial_response(resolver_->CreateRequest( - HostPortPair("ok_fail", 80), NetLogWithSource())); + HostPortPair("ok_fail", 80), NetLogWithSource(), base::nullopt)); EXPECT_FALSE(initial_response.complete()); proc_->SignalMultiple(1u); @@ -2953,11 +3196,11 @@ ChangeDnsConfig(CreateValidDnsConfig()); ResolveHostResponseHelper response0(resolver_->CreateRequest( - HostPortPair("ok_fail", 80), NetLogWithSource())); + HostPortPair("ok_fail", 80), NetLogWithSource(), base::nullopt)); ResolveHostResponseHelper response1(resolver_->CreateRequest( - HostPortPair("nx_fail", 80), NetLogWithSource())); + HostPortPair("nx_fail", 80), NetLogWithSource(), base::nullopt)); ResolveHostResponseHelper response2(resolver_->CreateRequest( - HostPortPair("nx_succeed", 80), NetLogWithSource())); + HostPortPair("nx_succeed", 80), NetLogWithSource(), base::nullopt)); proc_->SignalMultiple(4u); @@ -3038,9 +3281,9 @@ ChangeDnsConfig(DnsConfig()); // Initially there is no config, so client should not be invoked. ResolveHostResponseHelper initial_response0(resolver_->CreateRequest( - HostPortPair("ok_fail", 80), NetLogWithSource())); + HostPortPair("ok_fail", 80), NetLogWithSource(), base::nullopt)); ResolveHostResponseHelper initial_response1(resolver_->CreateRequest( - HostPortPair("nx_succeed", 80), NetLogWithSource())); + HostPortPair("nx_succeed", 80), NetLogWithSource(), base::nullopt)); proc_->SignalMultiple(2u); EXPECT_THAT(initial_response0.result_error(), IsError(ERR_NAME_NOT_RESOLVED)); @@ -3052,9 +3295,9 @@ ChangeDnsConfig(CreateValidDnsConfig()); ResolveHostResponseHelper abort_response0(resolver_->CreateRequest( - HostPortPair("ok_abort", 80), NetLogWithSource())); + HostPortPair("ok_abort", 80), NetLogWithSource(), base::nullopt)); ResolveHostResponseHelper abort_response1(resolver_->CreateRequest( - HostPortPair("nx_abort", 80), NetLogWithSource())); + HostPortPair("nx_abort", 80), NetLogWithSource(), base::nullopt)); // Simulate the case when the preference or policy has disabled the DNS // client causing AbortDnsTasks. @@ -3065,9 +3308,9 @@ // First request is resolved by MockDnsClient, others should fail due to // disabled fallback to ProcTask. ResolveHostResponseHelper response0(resolver_->CreateRequest( - HostPortPair("ok_fail", 80), NetLogWithSource())); + HostPortPair("ok_fail", 80), NetLogWithSource(), base::nullopt)); ResolveHostResponseHelper response1(resolver_->CreateRequest( - HostPortPair("nx_fail", 80), NetLogWithSource())); + HostPortPair("nx_fail", 80), NetLogWithSource(), base::nullopt)); proc_->SignalMultiple(6u); // Aborted due to Network Change. @@ -3112,7 +3355,7 @@ TEST_F(HostResolverImplDnsTest, OnDnsTaskFailureAbortedJob_ResolveHost) { ChangeDnsConfig(CreateValidDnsConfig()); ResolveHostResponseHelper response(resolver_->CreateRequest( - HostPortPair("nx_abort", 80), NetLogWithSource())); + HostPortPair("nx_abort", 80), NetLogWithSource(), base::nullopt)); // Abort all jobs here. CreateResolver(); proc_->SignalMultiple(1u); @@ -3125,7 +3368,7 @@ set_fallback_to_proctask(false); ChangeDnsConfig(CreateValidDnsConfig()); ResolveHostResponseHelper no_fallback_response(resolver_->CreateRequest( - HostPortPair("nx_abort", 80), NetLogWithSource())); + HostPortPair("nx_abort", 80), NetLogWithSource(), base::nullopt)); // Abort all jobs here. CreateResolver(); proc_->SignalMultiple(2u); @@ -3169,14 +3412,18 @@ // All other hostnames will fail in proc_. std::vector<std::unique_ptr<ResolveHostResponseHelper>> responses; - responses.emplace_back(std::make_unique<ResolveHostResponseHelper>( - resolver_->CreateRequest(HostPortPair("ok", 80), NetLogWithSource()))); - responses.emplace_back(std::make_unique<ResolveHostResponseHelper>( - resolver_->CreateRequest(HostPortPair("4ok", 80), NetLogWithSource()))); - responses.emplace_back(std::make_unique<ResolveHostResponseHelper>( - resolver_->CreateRequest(HostPortPair("6ok", 80), NetLogWithSource()))); - responses.emplace_back(std::make_unique<ResolveHostResponseHelper>( - resolver_->CreateRequest(HostPortPair("4nx", 80), NetLogWithSource()))); + responses.emplace_back( + std::make_unique<ResolveHostResponseHelper>(resolver_->CreateRequest( + HostPortPair("ok", 80), NetLogWithSource(), base::nullopt))); + responses.emplace_back( + std::make_unique<ResolveHostResponseHelper>(resolver_->CreateRequest( + HostPortPair("4ok", 80), NetLogWithSource(), base::nullopt))); + responses.emplace_back( + std::make_unique<ResolveHostResponseHelper>(resolver_->CreateRequest( + HostPortPair("6ok", 80), NetLogWithSource(), base::nullopt))); + responses.emplace_back( + std::make_unique<ResolveHostResponseHelper>(resolver_->CreateRequest( + HostPortPair("4nx", 80), NetLogWithSource(), base::nullopt))); proc_->SignalMultiple(4u); @@ -3229,7 +3476,7 @@ // When the resolver returns an A record with 127.0.53.53 it should be // mapped to a special error. ResolveHostResponseHelper response_ipv4(resolver_->CreateRequest( - HostPortPair("4collision", 80), NetLogWithSource())); + HostPortPair("4collision", 80), NetLogWithSource(), base::nullopt)); EXPECT_THAT(response_ipv4.result_error(), IsError(ERR_ICANN_NAME_COLLISION)); EXPECT_FALSE(response_ipv4.request()->GetAddressResults()); @@ -3237,7 +3484,7 @@ // work just like any other IP. (Despite having the same suffix, it is not // considered special) ResolveHostResponseHelper response_ipv6(resolver_->CreateRequest( - HostPortPair("6collision", 80), NetLogWithSource())); + HostPortPair("6collision", 80), NetLogWithSource(), base::nullopt)); EXPECT_THAT(response_ipv6.result_error(), IsOk()); EXPECT_THAT(response_ipv6.request()->GetAddressResults().value().endpoints(), testing::ElementsAre(CreateExpected("::127.0.53.53", 80))); @@ -3297,7 +3544,6 @@ EXPECT_TRUE(req6->HasOneAddress("127.0.0.1", 80)); } -// TODO(crbug.com/821021): Add resolves specifying address family once suported. TEST_F(HostResolverImplDnsTest, ServeFromHosts_ResolveHost) { // Initially, use empty HOSTS file. DnsConfig config = CreateValidDnsConfig(); @@ -3308,7 +3554,7 @@ proc_->SignalMultiple(1u); // For the first request which misses. ResolveHostResponseHelper initial_response(resolver_->CreateRequest( - HostPortPair("nx_ipv4", 80), NetLogWithSource())); + HostPortPair("nx_ipv4", 80), NetLogWithSource(), base::nullopt)); EXPECT_THAT(initial_response.result_error(), IsError(ERR_NAME_NOT_RESOLVED)); IPAddress local_ipv4 = IPAddress::IPv4Localhost(); @@ -3325,27 +3571,50 @@ ChangeDnsConfig(config); ResolveHostResponseHelper response_ipv4(resolver_->CreateRequest( - HostPortPair("nx_ipv4", 80), NetLogWithSource())); + HostPortPair("nx_ipv4", 80), NetLogWithSource(), base::nullopt)); EXPECT_THAT(response_ipv4.result_error(), IsOk()); EXPECT_THAT(response_ipv4.request()->GetAddressResults().value().endpoints(), testing::ElementsAre(CreateExpected("127.0.0.1", 80))); ResolveHostResponseHelper response_ipv6(resolver_->CreateRequest( - HostPortPair("nx_ipv6", 80), NetLogWithSource())); + HostPortPair("nx_ipv6", 80), NetLogWithSource(), base::nullopt)); EXPECT_THAT(response_ipv6.result_error(), IsOk()); EXPECT_THAT(response_ipv6.request()->GetAddressResults().value().endpoints(), testing::ElementsAre(CreateExpected("::1", 80))); ResolveHostResponseHelper response_both(resolver_->CreateRequest( - HostPortPair("nx_both", 80), NetLogWithSource())); + HostPortPair("nx_both", 80), NetLogWithSource(), base::nullopt)); EXPECT_THAT(response_both.result_error(), IsOk()); EXPECT_THAT(response_both.request()->GetAddressResults().value().endpoints(), testing::UnorderedElementsAre(CreateExpected("127.0.0.1", 80), CreateExpected("::1", 80))); + // Requests with specified DNS query type. + HostResolver::ResolveHostParameters parameters; + + parameters.dns_query_type = HostResolver::DnsQueryType::A; + ResolveHostResponseHelper response_specified_ipv4(resolver_->CreateRequest( + HostPortPair("nx_ipv4", 80), NetLogWithSource(), parameters)); + EXPECT_THAT(response_specified_ipv4.result_error(), IsOk()); + EXPECT_THAT(response_specified_ipv4.request() + ->GetAddressResults() + .value() + .endpoints(), + testing::ElementsAre(CreateExpected("127.0.0.1", 80))); + + parameters.dns_query_type = HostResolver::DnsQueryType::AAAA; + ResolveHostResponseHelper response_specified_ipv6(resolver_->CreateRequest( + HostPortPair("nx_ipv6", 80), NetLogWithSource(), parameters)); + EXPECT_THAT(response_specified_ipv6.result_error(), IsOk()); + EXPECT_THAT(response_specified_ipv6.request() + ->GetAddressResults() + .value() + .endpoints(), + testing::ElementsAre(CreateExpected("::1", 80))); + // Request with upper case. ResolveHostResponseHelper response_upper(resolver_->CreateRequest( - HostPortPair("nx_IPV4", 80), NetLogWithSource())); + HostPortPair("nx_IPV4", 80), NetLogWithSource(), base::nullopt)); EXPECT_THAT(response_upper.result_error(), IsOk()); EXPECT_THAT(response_upper.request()->GetAddressResults().value().endpoints(), testing::ElementsAre(CreateExpected("127.0.0.1", 80))); @@ -3401,9 +3670,9 @@ proc_->SignalMultiple(1u); // For the first request which fails. ResolveHostResponseHelper failure_response(resolver_->CreateRequest( - HostPortPair("nx_ipv4", 80), NetLogWithSource())); + HostPortPair("nx_ipv4", 80), NetLogWithSource(), base::nullopt)); ResolveHostResponseHelper queued_response(resolver_->CreateRequest( - HostPortPair("nx_ipv6", 80), NetLogWithSource())); + HostPortPair("nx_ipv6", 80), NetLogWithSource(), base::nullopt)); DnsHosts hosts; hosts[DnsHostsKey("nx_ipv4", ADDRESS_FAMILY_IPV4)] = @@ -3462,18 +3731,19 @@ responses.emplace_back( std::make_unique<ResolveHostResponseHelper>(resolver_->CreateRequest( - HostPortPair("ok.local", 80), NetLogWithSource()))); + HostPortPair("ok.local", 80), NetLogWithSource(), base::nullopt))); responses.emplace_back( std::make_unique<ResolveHostResponseHelper>(resolver_->CreateRequest( - HostPortPair("ok.local.", 80), NetLogWithSource()))); + HostPortPair("ok.local.", 80), NetLogWithSource(), base::nullopt))); responses.emplace_back( std::make_unique<ResolveHostResponseHelper>(resolver_->CreateRequest( - HostPortPair("oklocal", 80), NetLogWithSource()))); + HostPortPair("oklocal", 80), NetLogWithSource(), base::nullopt))); responses.emplace_back( std::make_unique<ResolveHostResponseHelper>(resolver_->CreateRequest( - HostPortPair("oklocal.", 80), NetLogWithSource()))); - responses.emplace_back(std::make_unique<ResolveHostResponseHelper>( - resolver_->CreateRequest(HostPortPair("ok", 80), NetLogWithSource()))); + HostPortPair("oklocal.", 80), NetLogWithSource(), base::nullopt))); + responses.emplace_back( + std::make_unique<ResolveHostResponseHelper>(resolver_->CreateRequest( + HostPortPair("ok", 80), NetLogWithSource(), base::nullopt))); proc_->SignalMultiple(5u); @@ -3552,8 +3822,8 @@ std::string()); // Default to failures. // Check that DnsTask works. - ResolveHostResponseHelper initial_response( - resolver_->CreateRequest(HostPortPair("ok_1", 80), NetLogWithSource())); + ResolveHostResponseHelper initial_response(resolver_->CreateRequest( + HostPortPair("ok_1", 80), NetLogWithSource(), base::nullopt)); EXPECT_THAT(initial_response.result_error(), IsOk()); std::vector<std::unique_ptr<ResolveHostResponseHelper>> responses; @@ -3564,7 +3834,7 @@ proc_->AddRuleForAllFamilies(hostname, "192.168.1.101"); responses.emplace_back( std::make_unique<ResolveHostResponseHelper>(resolver_->CreateRequest( - HostPortPair(hostname, 80), NetLogWithSource()))); + HostPortPair(hostname, 80), NetLogWithSource(), base::nullopt))); } proc_->SignalMultiple(responses.size()); @@ -3575,15 +3845,15 @@ ASSERT_FALSE(proc_->HasBlockedRequests()); // DnsTask should be disabled by now. - ResolveHostResponseHelper fail_response( - resolver_->CreateRequest(HostPortPair("ok_2", 80), NetLogWithSource())); + ResolveHostResponseHelper fail_response(resolver_->CreateRequest( + HostPortPair("ok_2", 80), NetLogWithSource(), base::nullopt)); proc_->SignalMultiple(1u); EXPECT_THAT(fail_response.result_error(), IsError(ERR_NAME_NOT_RESOLVED)); // Check that it is re-enabled after DNS change. ChangeDnsConfig(CreateValidDnsConfig()); - ResolveHostResponseHelper reenabled_response( - resolver_->CreateRequest(HostPortPair("ok_3", 80), NetLogWithSource())); + ResolveHostResponseHelper reenabled_response(resolver_->CreateRequest( + HostPortPair("ok_3", 80), NetLogWithSource(), base::nullopt)); EXPECT_THAT(reenabled_response.result_error(), IsOk()); } @@ -3628,7 +3898,7 @@ : base::StringPrintf("ok_%u", i); responses.emplace_back( std::make_unique<ResolveHostResponseHelper>(resolver_->CreateRequest( - HostPortPair(hostname, 80), NetLogWithSource()))); + HostPortPair(hostname, 80), NetLogWithSource(), base::nullopt))); } proc_->SignalMultiple(40u); @@ -3641,7 +3911,7 @@ // DnsTask should still be enabled. ResolveHostResponseHelper final_response(resolver_->CreateRequest( - HostPortPair("ok_last", 80), NetLogWithSource())); + HostPortPair("ok_last", 80), NetLogWithSource(), base::nullopt)); EXPECT_THAT(final_response.result_error(), IsOk()); } @@ -3724,7 +3994,7 @@ // Try without DnsClient. resolver_->SetDnsClient(nullptr); ResolveHostResponseHelper system_response(resolver_->CreateRequest( - HostPortPair("localhost", 80), NetLogWithSource())); + HostPortPair("localhost", 80), NetLogWithSource(), base::nullopt)); EXPECT_THAT(system_response.result_error(), IsOk()); EXPECT_THAT( system_response.request()->GetAddressResults().value().endpoints(), @@ -3735,7 +4005,7 @@ resolver_->SetDnsClient(std::unique_ptr<DnsClient>( new MockDnsClient(CreateValidDnsConfig(), dns_rules_))); ResolveHostResponseHelper builtin_response(resolver_->CreateRequest( - HostPortPair("localhost", 80), NetLogWithSource())); + HostPortPair("localhost", 80), NetLogWithSource(), base::nullopt)); EXPECT_THAT(builtin_response.result_error(), IsOk()); EXPECT_THAT( builtin_response.request()->GetAddressResults().value().endpoints(), @@ -3748,7 +4018,7 @@ config.use_local_ipv6 = false; ChangeDnsConfig(config); ResolveHostResponseHelper ipv6_disabled_response(resolver_->CreateRequest( - HostPortPair("localhost", 80), NetLogWithSource())); + HostPortPair("localhost", 80), NetLogWithSource(), base::nullopt)); EXPECT_THAT(ipv6_disabled_response.result_error(), IsOk()); EXPECT_THAT( ipv6_disabled_response.request()->GetAddressResults().value().endpoints(), @@ -3777,8 +4047,8 @@ config.use_local_ipv6 = false; ChangeDnsConfig(config); - ResolveHostResponseHelper response( - resolver_->CreateRequest(HostPortPair("ok", 80), NetLogWithSource())); + ResolveHostResponseHelper response(resolver_->CreateRequest( + HostPortPair("ok", 80), NetLogWithSource(), base::nullopt)); ASSERT_FALSE(response.complete()); ASSERT_EQ(1u, num_running_dispatcher_jobs()); @@ -3807,8 +4077,8 @@ CreateSerialResolver(); ChangeDnsConfig(CreateValidDnsConfig()); - ResolveHostResponseHelper response( - resolver_->CreateRequest(HostPortPair("ok", 80), NetLogWithSource())); + ResolveHostResponseHelper response(resolver_->CreateRequest( + HostPortPair("ok", 80), NetLogWithSource(), base::nullopt)); EXPECT_EQ(1u, num_running_dispatcher_jobs()); response.CancelRequest(); @@ -3833,8 +4103,8 @@ TEST_F(HostResolverImplDnsTest, CancelWithTwoTransactionsActive_ResolveHost) { ChangeDnsConfig(CreateValidDnsConfig()); - ResolveHostResponseHelper response( - resolver_->CreateRequest(HostPortPair("ok", 80), NetLogWithSource())); + ResolveHostResponseHelper response(resolver_->CreateRequest( + HostPortPair("ok", 80), NetLogWithSource(), base::nullopt)); EXPECT_EQ(2u, num_running_dispatcher_jobs()); response.CancelRequest(); @@ -3882,7 +4152,7 @@ std::string hostname = base::StringPrintf("ok%i", i); responses.emplace_back( std::make_unique<ResolveHostResponseHelper>(resolver_->CreateRequest( - HostPortPair(hostname, 80), NetLogWithSource()))); + HostPortPair(hostname, 80), NetLogWithSource(), base::nullopt))); } EXPECT_EQ(10u, num_running_dispatcher_jobs()); @@ -3915,7 +4185,7 @@ ChangeDnsConfig(CreateValidDnsConfig()); ResolveHostResponseHelper response(resolver_->CreateRequest( - HostPortPair("6slow_ok", 80), NetLogWithSource())); + HostPortPair("6slow_ok", 80), NetLogWithSource(), base::nullopt)); EXPECT_EQ(2u, num_running_dispatcher_jobs()); // The IPv4 request should complete, the IPv6 request is still pending. @@ -3951,7 +4221,7 @@ ChangeDnsConfig(CreateValidDnsConfig()); ResolveHostResponseHelper response(resolver_->CreateRequest( - HostPortPair("4slow_ok", 80), NetLogWithSource())); + HostPortPair("4slow_ok", 80), NetLogWithSource(), base::nullopt)); EXPECT_EQ(2u, num_running_dispatcher_jobs()); // The IPv6 request should complete, the IPv4 request is still pending. @@ -4011,16 +4281,16 @@ std::vector<std::unique_ptr<ResolveHostResponseHelper>> responses; responses.emplace_back( std::make_unique<ResolveHostResponseHelper>(resolver_->CreateRequest( - HostPortPair("4slow_ok", 80), NetLogWithSource()))); + HostPortPair("4slow_ok", 80), NetLogWithSource(), base::nullopt))); responses.emplace_back( std::make_unique<ResolveHostResponseHelper>(resolver_->CreateRequest( - HostPortPair("4slow_4ok", 80), NetLogWithSource()))); - responses.emplace_back( - std::make_unique<ResolveHostResponseHelper>(resolver_->CreateRequest( - HostPortPair("4slow_4timeout", 80), NetLogWithSource()))); - responses.emplace_back( - std::make_unique<ResolveHostResponseHelper>(resolver_->CreateRequest( - HostPortPair("4slow_6timeout", 80), NetLogWithSource()))); + HostPortPair("4slow_4ok", 80), NetLogWithSource(), base::nullopt))); + responses.emplace_back(std::make_unique<ResolveHostResponseHelper>( + resolver_->CreateRequest(HostPortPair("4slow_4timeout", 80), + NetLogWithSource(), base::nullopt))); + responses.emplace_back(std::make_unique<ResolveHostResponseHelper>( + resolver_->CreateRequest(HostPortPair("4slow_6timeout", 80), + NetLogWithSource(), base::nullopt))); base::RunLoop().RunUntilIdle(); EXPECT_FALSE(responses[0]->complete()); @@ -4067,8 +4337,8 @@ set_fallback_to_proctask(false); ChangeDnsConfig(CreateValidDnsConfig()); - ResolveHostResponseHelper response( - resolver_->CreateRequest(HostPortPair("ok", 80), NetLogWithSource())); + ResolveHostResponseHelper response(resolver_->CreateRequest( + HostPortPair("ok", 80), NetLogWithSource(), base::nullopt)); EXPECT_FALSE(response.complete()); EXPECT_EQ(1u, num_running_dispatcher_jobs()); @@ -4119,11 +4389,11 @@ set_fallback_to_proctask(false); ChangeDnsConfig(CreateValidDnsConfig()); - ResolveHostResponseHelper response0( - resolver_->CreateRequest(HostPortPair("ok", 80), NetLogWithSource())); + ResolveHostResponseHelper response0(resolver_->CreateRequest( + HostPortPair("ok", 80), NetLogWithSource(), base::nullopt)); EXPECT_EQ(2u, num_running_dispatcher_jobs()); ResolveHostResponseHelper response1(resolver_->CreateRequest( - HostPortPair("4slow_ok", 80), NetLogWithSource())); + HostPortPair("4slow_ok", 80), NetLogWithSource(), base::nullopt)); EXPECT_EQ(3u, num_running_dispatcher_jobs()); // Request 0's transactions should complete, starting Request 1's second @@ -4167,7 +4437,7 @@ proc_->SignalMultiple(1u); ResolveHostResponseHelper response(resolver_->CreateRequest( - HostPortPair("empty_fallback", 80), NetLogWithSource())); + HostPortPair("empty_fallback", 80), NetLogWithSource(), base::nullopt)); EXPECT_THAT(response.result_error(), IsOk()); EXPECT_THAT(response.request()->GetAddressResults().value().endpoints(), testing::ElementsAre(CreateExpected("192.168.0.1", 80))); @@ -4194,7 +4464,7 @@ proc_->SignalMultiple(1u); ResolveHostResponseHelper response(resolver_->CreateRequest( - HostPortPair("empty_fallback", 80), NetLogWithSource())); + HostPortPair("empty_fallback", 80), NetLogWithSource(), base::nullopt)); EXPECT_THAT(response.result_error(), IsOk()); EXPECT_THAT(response.request()->GetAddressResults().value().endpoints(), @@ -4258,13 +4528,14 @@ // First active job gets two slots. responses.emplace_back( std::make_unique<ResolveHostResponseHelper>(resolver_->CreateRequest( - HostPortPair("slow_nx1", 80), NetLogWithSource()))); + HostPortPair("slow_nx1", 80), NetLogWithSource(), base::nullopt))); // Next job gets one slot, and waits on another. responses.emplace_back( std::make_unique<ResolveHostResponseHelper>(resolver_->CreateRequest( - HostPortPair("slow_nx2", 80), NetLogWithSource()))); - responses.emplace_back(std::make_unique<ResolveHostResponseHelper>( - resolver_->CreateRequest(HostPortPair("ok", 80), NetLogWithSource()))); + HostPortPair("slow_nx2", 80), NetLogWithSource(), base::nullopt))); + responses.emplace_back( + std::make_unique<ResolveHostResponseHelper>(resolver_->CreateRequest( + HostPortPair("ok", 80), NetLogWithSource(), base::nullopt))); EXPECT_EQ(3u, num_running_dispatcher_jobs()); for (auto& response : responses) { @@ -4309,8 +4580,8 @@ TEST_F(HostResolverImplDnsTest, DontAbortOnInitialDNSConfigRead_ResolveHost) { // DnsClient is enabled, but there's no DnsConfig, so the request should start // using ProcTask. - ResolveHostResponseHelper response( - resolver_->CreateRequest(HostPortPair("host1", 70), NetLogWithSource())); + ResolveHostResponseHelper response(resolver_->CreateRequest( + HostPortPair("host1", 70), NetLogWithSource(), base::nullopt)); EXPECT_FALSE(response.complete()); EXPECT_TRUE(proc_->WaitFor(1u)); @@ -4395,7 +4666,7 @@ proc_->AddRuleForAllFamilies(host, "192.168.0.1"); failure_responses.emplace_back( std::make_unique<ResolveHostResponseHelper>(resolver_->CreateRequest( - HostPortPair(host, 80), NetLogWithSource()))); + HostPortPair(host, 80), NetLogWithSource(), base::nullopt))); EXPECT_FALSE(failure_responses[i]->complete()); } @@ -4403,15 +4674,15 @@ // so should end up using ProcTasks. proc_->AddRuleForAllFamilies("slow_ok1", "192.168.0.2"); ResolveHostResponseHelper response0(resolver_->CreateRequest( - HostPortPair("slow_ok1", 80), NetLogWithSource())); + HostPortPair("slow_ok1", 80), NetLogWithSource(), base::nullopt)); EXPECT_FALSE(response0.complete()); proc_->AddRuleForAllFamilies("slow_ok2", "192.168.0.3"); ResolveHostResponseHelper response1(resolver_->CreateRequest( - HostPortPair("slow_ok2", 80), NetLogWithSource())); + HostPortPair("slow_ok2", 80), NetLogWithSource(), base::nullopt)); EXPECT_FALSE(response1.complete()); proc_->AddRuleForAllFamilies("slow_ok3", "192.168.0.4"); ResolveHostResponseHelper response2(resolver_->CreateRequest( - HostPortPair("slow_ok3", 80), NetLogWithSource())); + HostPortPair("slow_ok3", 80), NetLogWithSource(), base::nullopt)); EXPECT_FALSE(response2.complete()); proc_->SignalMultiple(maximum_dns_failures() + 3); @@ -4498,16 +4769,17 @@ // First active job gets two slots. responses.emplace_back( std::make_unique<ResolveHostResponseHelper>(resolver_->CreateRequest( - HostPortPair("slow_ok1", 80), NetLogWithSource()))); + HostPortPair("slow_ok1", 80), NetLogWithSource(), base::nullopt))); EXPECT_FALSE(responses[0]->complete()); // Next job gets one slot, and waits on another. responses.emplace_back( std::make_unique<ResolveHostResponseHelper>(resolver_->CreateRequest( - HostPortPair("slow_ok2", 80), NetLogWithSource()))); + HostPortPair("slow_ok2", 80), NetLogWithSource(), base::nullopt))); EXPECT_FALSE(responses[1]->complete()); // Next one is queued. - responses.emplace_back(std::make_unique<ResolveHostResponseHelper>( - resolver_->CreateRequest(HostPortPair("ok", 80), NetLogWithSource()))); + responses.emplace_back( + std::make_unique<ResolveHostResponseHelper>(resolver_->CreateRequest( + HostPortPair("ok", 80), NetLogWithSource(), base::nullopt))); EXPECT_FALSE(responses[2]->complete()); EXPECT_EQ(3u, num_running_dispatcher_jobs()); @@ -4635,37 +4907,63 @@ proc_->AddRule("h1", ADDRESS_FAMILY_UNSPECIFIED, "::3"); proc_->AddRule("h1", ADDRESS_FAMILY_IPV4, "1.0.0.1"); + proc_->AddRule("h1", ADDRESS_FAMILY_IPV6, "::2"); - // TODO(crbug.com/821021): Add more requests with different A vs AAAA - // specified once supported. - ResolveHostResponseHelper response( - resolver_->CreateRequest(HostPortPair("h1", 80), NetLogWithSource())); + ResolveHostResponseHelper response(resolver_->CreateRequest( + HostPortPair("h1", 80), NetLogWithSource(), base::nullopt)); + HostResolver::ResolveHostParameters parameters; + parameters.dns_query_type = HostResolver::DnsQueryType::A; + ResolveHostResponseHelper v4_response(resolver_->CreateRequest( + HostPortPair("h1", 80), NetLogWithSource(), parameters)); + parameters.dns_query_type = HostResolver::DnsQueryType::AAAA; + ResolveHostResponseHelper v6_response(resolver_->CreateRequest( + HostPortPair("h1", 80), NetLogWithSource(), parameters)); - proc_->SignalMultiple(1u); + proc_->SignalMultiple(3u); // Should revert to only IPV4 request. EXPECT_THAT(response.result_error(), IsOk()); EXPECT_THAT(response.request()->GetAddressResults().value().endpoints(), testing::ElementsAre(CreateExpected("1.0.0.1", 80))); + EXPECT_THAT(v4_response.result_error(), IsOk()); + EXPECT_THAT(v4_response.request()->GetAddressResults().value().endpoints(), + testing::ElementsAre(CreateExpected("1.0.0.1", 80))); + EXPECT_THAT(v6_response.result_error(), IsOk()); + EXPECT_THAT(v6_response.request()->GetAddressResults().value().endpoints(), + testing::ElementsAre(CreateExpected("::2", 80))); + // Now repeat the test on non-wifi to check that IPv6 is used as normal // after the network changes. notifier.mock_network_change_notifier()->SetConnectionType( NetworkChangeNotifier::CONNECTION_4G); base::RunLoop().RunUntilIdle(); // Wait for NetworkChangeNotifier. - // TODO(crbug.com/821021): Add more requests with different A vs AAAA - // specified once supported. - ResolveHostResponseHelper no_wifi_response( - resolver_->CreateRequest(HostPortPair("h1", 80), NetLogWithSource())); + ResolveHostResponseHelper no_wifi_response(resolver_->CreateRequest( + HostPortPair("h1", 80), NetLogWithSource(), base::nullopt)); + parameters.dns_query_type = HostResolver::DnsQueryType::A; + ResolveHostResponseHelper no_wifi_v4_response(resolver_->CreateRequest( + HostPortPair("h1", 80), NetLogWithSource(), parameters)); + parameters.dns_query_type = HostResolver::DnsQueryType::AAAA; + ResolveHostResponseHelper no_wifi_v6_response(resolver_->CreateRequest( + HostPortPair("h1", 80), NetLogWithSource(), parameters)); - proc_->SignalMultiple(1u); + proc_->SignalMultiple(3u); // IPV6 should be available. EXPECT_THAT(no_wifi_response.result_error(), IsOk()); EXPECT_THAT( no_wifi_response.request()->GetAddressResults().value().endpoints(), testing::ElementsAre(CreateExpected("::3", 80))); + + EXPECT_THAT(no_wifi_v4_response.result_error(), IsOk()); + EXPECT_THAT( + no_wifi_v4_response.request()->GetAddressResults().value().endpoints(), + testing::ElementsAre(CreateExpected("1.0.0.1", 80))); + EXPECT_THAT(no_wifi_v6_response.result_error(), IsOk()); + EXPECT_THAT( + no_wifi_v6_response.request()->GetAddressResults().value().endpoints(), + testing::ElementsAre(CreateExpected("::2", 80))); } TEST_F(HostResolverImplDnsTest, NotFoundTTL) { @@ -4705,8 +5003,8 @@ ChangeDnsConfig(CreateValidDnsConfig()); // NODATA - ResolveHostResponseHelper no_data_response( - resolver_->CreateRequest(HostPortPair("empty", 80), NetLogWithSource())); + ResolveHostResponseHelper no_data_response(resolver_->CreateRequest( + HostPortPair("empty", 80), NetLogWithSource(), base::nullopt)); EXPECT_THAT(no_data_response.result_error(), IsError(ERR_NAME_NOT_RESOLVED)); EXPECT_FALSE(no_data_response.request()->GetAddressResults()); HostCache::Key key("empty", ADDRESS_FAMILY_UNSPECIFIED, 0); @@ -4719,7 +5017,7 @@ // NXDOMAIN ResolveHostResponseHelper no_domain_response(resolver_->CreateRequest( - HostPortPair("nodomain", 80), NetLogWithSource())); + HostPortPair("nodomain", 80), NetLogWithSource(), base::nullopt)); EXPECT_THAT(no_domain_response.result_error(), IsError(ERR_NAME_NOT_RESOLVED)); EXPECT_FALSE(no_domain_response.request()->GetAddressResults());
diff --git a/net/dns/host_resolver_mojo.cc b/net/dns/host_resolver_mojo.cc index 8256b2fc..a0ce5d0 100644 --- a/net/dns/host_resolver_mojo.cc +++ b/net/dns/host_resolver_mojo.cc
@@ -71,8 +71,10 @@ HostResolverMojo::~HostResolverMojo() = default; std::unique_ptr<HostResolver::ResolveHostRequest> -HostResolverMojo::CreateRequest(const HostPortPair& host, - const NetLogWithSource& source_net_log) { +HostResolverMojo::CreateRequest( + const HostPortPair& host, + const NetLogWithSource& source_net_log, + const base::Optional<ResolveHostParameters>& optional_parameters) { // TODO(crbug.com/821021): Implement. NOTIMPLEMENTED(); return nullptr;
diff --git a/net/dns/host_resolver_mojo.h b/net/dns/host_resolver_mojo.h index 0057b2f..8fe03ed0 100644 --- a/net/dns/host_resolver_mojo.h +++ b/net/dns/host_resolver_mojo.h
@@ -38,7 +38,9 @@ // HostResolver overrides. std::unique_ptr<ResolveHostRequest> CreateRequest( const HostPortPair& host, - const NetLogWithSource& net_log) override; + const NetLogWithSource& net_log, + const base::Optional<ResolveHostParameters>& optional_parameters) + override; // Note: |Resolve()| currently ignores |priority|. int Resolve(const RequestInfo& info, RequestPriority priority,
diff --git a/net/dns/mapped_host_resolver.cc b/net/dns/mapped_host_resolver.cc index bfb0890..8a237dda 100644 --- a/net/dns/mapped_host_resolver.cc +++ b/net/dns/mapped_host_resolver.cc
@@ -36,15 +36,17 @@ MappedHostResolver::~MappedHostResolver() = default; std::unique_ptr<HostResolver::ResolveHostRequest> -MappedHostResolver::CreateRequest(const HostPortPair& host, - const NetLogWithSource& source_net_log) { +MappedHostResolver::CreateRequest( + const HostPortPair& host, + const NetLogWithSource& source_net_log, + const base::Optional<ResolveHostParameters>& optional_parameters) { HostPortPair rewritten = host; rules_.RewriteHost(&rewritten); if (rewritten.host() == "~NOTFOUND") return std::make_unique<AlwaysErrorRequestImpl>(ERR_NAME_NOT_RESOLVED); - return impl_->CreateRequest(rewritten, source_net_log); + return impl_->CreateRequest(rewritten, source_net_log, optional_parameters); } int MappedHostResolver::Resolve(const RequestInfo& original_info,
diff --git a/net/dns/mapped_host_resolver.h b/net/dns/mapped_host_resolver.h index ed603c4..88edc98 100644 --- a/net/dns/mapped_host_resolver.h +++ b/net/dns/mapped_host_resolver.h
@@ -48,7 +48,9 @@ // HostResolver methods: std::unique_ptr<ResolveHostRequest> CreateRequest( const HostPortPair& host, - const NetLogWithSource& net_log) override; + const NetLogWithSource& net_log, + const base::Optional<ResolveHostParameters>& optional_parameters) + override; int Resolve(const RequestInfo& info, RequestPriority priority, AddressList* addresses,
diff --git a/net/dns/mapped_host_resolver_unittest.cc b/net/dns/mapped_host_resolver_unittest.cc index eb113f0..3695c79 100644 --- a/net/dns/mapped_host_resolver_unittest.cc +++ b/net/dns/mapped_host_resolver_unittest.cc
@@ -118,7 +118,7 @@ TestCompletionCallback callback; std::unique_ptr<HostResolver::ResolveHostRequest> request = resolver->CreateRequest(HostPortPair("www.google.com", 80), - NetLogWithSource()); + NetLogWithSource(), base::nullopt); int rv = request->Start(callback.callback()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback.WaitForResult(); @@ -131,7 +131,7 @@ // Try resolving "www.google.com:80". Should be remapped to "baz.com:80". request = resolver->CreateRequest(HostPortPair("www.google.com", 80), - NetLogWithSource()); + NetLogWithSource(), base::nullopt); rv = request->Start(callback.callback()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback.WaitForResult(); @@ -142,8 +142,8 @@ // Try resolving "foo.com:77". This will NOT be remapped, so result // is "foo.com:77". - request = - resolver->CreateRequest(HostPortPair("foo.com", 77), NetLogWithSource()); + request = resolver->CreateRequest(HostPortPair("foo.com", 77), + NetLogWithSource(), base::nullopt); rv = request->Start(callback.callback()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback.WaitForResult(); @@ -157,7 +157,7 @@ // Try resolving "chromium.org:61". Should be remapped to "proxy:99". request = resolver->CreateRequest(HostPortPair("chromium.org", 61), - NetLogWithSource()); + NetLogWithSource(), base::nullopt); rv = request->Start(callback.callback()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback.WaitForResult(); @@ -237,7 +237,7 @@ // Try resolving "www.google.com". Should not be remapped due to exclusion). std::unique_ptr<HostResolver::ResolveHostRequest> request = resolver->CreateRequest(HostPortPair("www.google.com", 80), - NetLogWithSource()); + NetLogWithSource(), base::nullopt); int rv = request->Start(callback.callback()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback.WaitForResult(); @@ -248,7 +248,7 @@ // Try resolving "chrome.com:80". Should be remapped to "baz:80". request = resolver->CreateRequest(HostPortPair("chrome.com", 80), - NetLogWithSource()); + NetLogWithSource(), base::nullopt); rv = request->Start(callback.callback()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback.WaitForResult(); @@ -320,7 +320,7 @@ // Try resolving "www.google.com". Should be remapped to "baz". std::unique_ptr<HostResolver::ResolveHostRequest> request = resolver->CreateRequest(HostPortPair("www.google.com", 80), - NetLogWithSource()); + NetLogWithSource(), base::nullopt); int rv = request->Start(callback.callback()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback.WaitForResult(); @@ -331,7 +331,7 @@ // Try resolving "chrome.net:80". Should be remapped to "bar:60". request = resolver->CreateRequest(HostPortPair("chrome.net", 80), - NetLogWithSource()); + NetLogWithSource(), base::nullopt); rv = request->Start(callback.callback()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback.WaitForResult(); @@ -414,7 +414,7 @@ TestCompletionCallback callback1; std::unique_ptr<HostResolver::ResolveHostRequest> request = resolver->CreateRequest(HostPortPair("www.google.com", 80), - NetLogWithSource()); + NetLogWithSource(), base::nullopt); int rv = request->Start(callback1.callback()); EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED)); request.reset(); @@ -422,7 +422,7 @@ // Try resolving www.foo.com --> Should succeed. TestCompletionCallback callback2; request = resolver->CreateRequest(HostPortPair("www.foo.com", 80), - NetLogWithSource()); + NetLogWithSource(), base::nullopt); rv = request->Start(callback2.callback()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback2.WaitForResult();
diff --git a/net/dns/mock_host_resolver.cc b/net/dns/mock_host_resolver.cc index 4892ac2..2b19984 100644 --- a/net/dns/mock_host_resolver.cc +++ b/net/dns/mock_host_resolver.cc
@@ -61,28 +61,27 @@ : public HostResolver::ResolveHostRequest { public: RequestImpl(const HostPortPair& request_host, + const base::Optional<ResolveHostParameters>& optional_parameters, base::WeakPtr<MockHostResolverBase> resolver) : RequestImpl(request_host, - ADDRESS_FAMILY_UNSPECIFIED, + optional_parameters, 0 /* host_resolver_flags */, true /* allow_cached_response */, false /* is_speculative */, - RequestPriority::DEFAULT_PRIORITY, resolver) {} RequestImpl(const HostPortPair& request_host, - AddressFamily address_family, + const base::Optional<ResolveHostParameters>& optional_parameters, HostResolverFlags host_resolver_flags, bool allow_cached_response, bool is_speculative, - RequestPriority priority, base::WeakPtr<MockHostResolverBase> resolver) : request_host_(request_host), - address_family_(address_family), host_resolver_flags_(host_resolver_flags), allow_cached_response_(allow_cached_response), is_speculative_(is_speculative), - priority_(priority), + parameters_(optional_parameters ? optional_parameters.value() + : ResolveHostParameters()), id_(0), resolver_(resolver), complete_(false) {} @@ -145,15 +144,13 @@ const HostPortPair& request_host() const { return request_host_; } - AddressFamily address_family() const { return address_family_; } - int host_resolver_flags() const { return host_resolver_flags_; } bool allow_cached_response() const { return allow_cached_response_; } bool is_speculative() const { return is_speculative_; } - RequestPriority priority() const { return priority_; } + const ResolveHostParameters& parameters() const { return parameters_; } size_t id() { return id_; } @@ -168,11 +165,10 @@ private: const HostPortPair request_host_; - AddressFamily address_family_; int host_resolver_flags_; bool allow_cached_response_; bool is_speculative_; - RequestPriority priority_; + const ResolveHostParameters parameters_; base::Optional<AddressList> address_results_; @@ -249,9 +245,11 @@ } std::unique_ptr<HostResolver::ResolveHostRequest> -MockHostResolverBase::CreateRequest(const HostPortPair& host, - const NetLogWithSource& source_net_log) { - return std::make_unique<RequestImpl>(host, AsWeakPtr()); +MockHostResolverBase::CreateRequest( + const HostPortPair& host, + const NetLogWithSource& source_net_log, + const base::Optional<ResolveHostParameters>& optional_parameters) { + return std::make_unique<RequestImpl>(host, optional_parameters, AsWeakPtr()); } int MockHostResolverBase::Resolve(const RequestInfo& info, @@ -264,9 +262,9 @@ DCHECK(out_request); auto request = std::make_unique<RequestImpl>( - info.host_port_pair(), info.address_family(), info.host_resolver_flags(), - info.allow_cached_response(), info.is_speculative(), priority, - AsWeakPtr()); + info.host_port_pair(), RequestInfoToResolveHostParameters(info, priority), + info.host_resolver_flags(), info.allow_cached_response(), + info.is_speculative(), AsWeakPtr()); auto wrapped_request = std::make_unique<LegacyRequestImpl>(std::move(request)); @@ -357,11 +355,12 @@ int MockHostResolverBase::Resolve(RequestImpl* request) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - last_request_priority_ = request->priority(); + last_request_priority_ = request->parameters().initial_priority; num_resolve_++; AddressList addresses; int rv = ResolveFromIPLiteralOrCache( - request->request_host(), request->address_family(), + request->request_host(), + DnsQueryTypeToAddressFamily(request->parameters().dns_query_type), request->host_resolver_flags(), request->allow_cached_response(), &addresses); if (rv == OK) @@ -375,8 +374,10 @@ return ERR_NAME_NOT_RESOLVED; if (synchronous_mode_) { - int rv = ResolveProc(request->request_host(), request->address_family(), - request->host_resolver_flags(), &addresses); + int rv = ResolveProc( + request->request_host(), + DnsQueryTypeToAddressFamily(request->parameters().dns_query_type), + request->host_resolver_flags(), &addresses); if (rv == OK) request->set_address_results(addresses); return rv; @@ -464,8 +465,10 @@ requests_.erase(it); AddressList addresses; - int error = ResolveProc(req->request_host(), req->address_family(), - req->host_resolver_flags(), &addresses); + int error = + ResolveProc(req->request_host(), + DnsQueryTypeToAddressFamily(req->parameters().dns_query_type), + req->host_resolver_flags(), &addresses); if (error == OK) req->set_address_results(addresses); req->OnAsyncCompleted(id, error); @@ -750,8 +753,10 @@ HangingHostResolver::~HangingHostResolver() = default; std::unique_ptr<HostResolver::ResolveHostRequest> -HangingHostResolver::CreateRequest(const HostPortPair& host, - const NetLogWithSource& source_net_log) { +HangingHostResolver::CreateRequest( + const HostPortPair& host, + const NetLogWithSource& source_net_log, + const base::Optional<ResolveHostParameters>& optional_parameters) { return std::make_unique<RequestImpl>(weak_ptr_factory_.GetWeakPtr(), false /* started */); }
diff --git a/net/dns/mock_host_resolver.h b/net/dns/mock_host_resolver.h index 47b1d3c..dcfdb176 100644 --- a/net/dns/mock_host_resolver.h +++ b/net/dns/mock_host_resolver.h
@@ -87,7 +87,9 @@ // HostResolver methods: std::unique_ptr<ResolveHostRequest> CreateRequest( const HostPortPair& host, - const NetLogWithSource& net_log) override; + const NetLogWithSource& net_log, + const base::Optional<ResolveHostParameters>& optional_parameters) + override; int Resolve(const RequestInfo& info, RequestPriority priority, AddressList* addresses, @@ -306,7 +308,9 @@ ~HangingHostResolver() override; std::unique_ptr<ResolveHostRequest> CreateRequest( const HostPortPair& host, - const NetLogWithSource& net_log) override; + const NetLogWithSource& net_log, + const base::Optional<ResolveHostParameters>& optional_parameters) + override; int Resolve(const RequestInfo& info, RequestPriority priority, AddressList* addresses,
diff --git a/net/extras/sqlite/sqlite_persistent_cookie_store.cc b/net/extras/sqlite/sqlite_persistent_cookie_store.cc index 6a191d3..67a46fc 100644 --- a/net/extras/sqlite/sqlite_persistent_cookie_store.cc +++ b/net/extras/sqlite/sqlite_persistent_cookie_store.cc
@@ -24,10 +24,12 @@ #include "base/synchronization/atomic_flag.h" #include "base/synchronization/lock.h" #include "base/time/time.h" +#include "base/values.h" #include "net/cookies/canonical_cookie.h" #include "net/cookies/cookie_constants.h" #include "net/cookies/cookie_util.h" #include "net/extras/sqlite/cookie_crypto_delegate.h" +#include "net/log/net_log.h" #include "sql/error_delegate_util.h" #include "sql/meta_table.h" #include "sql/statement.h" @@ -38,6 +40,16 @@ namespace { +std::unique_ptr<base::Value> CookieKeyedLoadNetLogCallback( + const std::string& key, + net::NetLogCaptureMode capture_mode) { + if (!capture_mode.include_cookies_and_credentials()) + return nullptr; + auto dict = std::make_unique<base::DictionaryValue>(); + dict->SetString("key", key); + return dict; +} + // Used to populate a histogram for problems when loading cookies. // // Please do not reorder or remove entries. New entries must be added to the @@ -642,7 +654,7 @@ void SQLitePersistentCookieStore::Backend::FlushAndNotifyInBackground( base::OnceClosure callback) { Commit(); - if (!callback.is_null()) + if (callback) PostClientTask(FROM_HERE, std::move(callback)); } @@ -1585,16 +1597,34 @@ backend_->DeleteAllInList(cookies); } -void SQLitePersistentCookieStore::Load(const LoadedCallback& loaded_callback) { +void SQLitePersistentCookieStore::Load(const LoadedCallback& loaded_callback, + const NetLogWithSource& net_log) { DCHECK(!loaded_callback.is_null()); - backend_->Load(loaded_callback); + net_log_ = net_log; + net_log_.BeginEvent(NetLogEventType::COOKIE_PERSISTENT_STORE_LOAD); + // Note that |backend_| keeps |this| alive by keeping a reference count. + // If this class is ever converted over to a WeakPtr<> pattern (as TODO it + // should be) this will need to be replaced by a more complex pattern that + // guarantees |loaded_callback| being called even if the class has been + // destroyed. |backend_| needs to outlive |this| to commit changes to disk. + backend_->Load(base::BindRepeating(&SQLitePersistentCookieStore::CompleteLoad, + this, loaded_callback)); } void SQLitePersistentCookieStore::LoadCookiesForKey( const std::string& key, const LoadedCallback& loaded_callback) { DCHECK(!loaded_callback.is_null()); - backend_->LoadCookiesForKey(key, loaded_callback); + net_log_.AddEvent(NetLogEventType::COOKIE_PERSISTENT_STORE_KEY_LOAD_STARTED, + base::BindRepeating(CookieKeyedLoadNetLogCallback, key)); + // Note that |backend_| keeps |this| alive by keeping a reference count. + // If this class is ever converted over to a WeakPtr<> pattern (as TODO it + // should be) this will need to be replaced by a more complex pattern that + // guarantees |loaded_callback| being called even if the class has been + // destroyed. |backend_| needs to outlive |this| to commit changes to disk. + backend_->LoadCookiesForKey( + key, base::BindRepeating(&SQLitePersistentCookieStore::CompleteKeyedLoad, + this, key, loaded_callback)); } void SQLitePersistentCookieStore::AddCookie(const CanonicalCookie& cc) { @@ -1624,7 +1654,26 @@ } SQLitePersistentCookieStore::~SQLitePersistentCookieStore() { + net_log_.AddEvent( + NetLogEventType::COOKIE_PERSISTENT_STORE_CLOSED, + NetLog::StringCallback("type", "SQLitePersistentCookieStore")); backend_->Close(); } +void SQLitePersistentCookieStore::CompleteLoad( + const LoadedCallback& callback, + std::vector<std::unique_ptr<CanonicalCookie>> cookie_list) { + net_log_.EndEvent(NetLogEventType::COOKIE_PERSISTENT_STORE_LOAD); + callback.Run(std::move(cookie_list)); +} + +void SQLitePersistentCookieStore::CompleteKeyedLoad( + const std::string& key, + const LoadedCallback& callback, + std::vector<std::unique_ptr<CanonicalCookie>> cookie_list) { + net_log_.AddEvent(NetLogEventType::COOKIE_PERSISTENT_STORE_KEY_LOAD_COMPLETED, + NetLog::StringCallback("domain", &key)); + callback.Run(std::move(cookie_list)); +} + } // namespace net
diff --git a/net/extras/sqlite/sqlite_persistent_cookie_store.h b/net/extras/sqlite/sqlite_persistent_cookie_store.h index 5dd0c91..b9c99d4 100644 --- a/net/extras/sqlite/sqlite_persistent_cookie_store.h +++ b/net/extras/sqlite/sqlite_persistent_cookie_store.h
@@ -14,6 +14,7 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" #include "net/cookies/cookie_monster.h" +#include "net/log/net_log_with_source.h" namespace base { class FilePath; @@ -48,7 +49,8 @@ void DeleteAllInList(const std::list<CookieOrigin>& cookies); // CookieMonster::PersistentCookieStore: - void Load(const LoadedCallback& loaded_callback) override; + void Load(const LoadedCallback& loaded_callback, + const NetLogWithSource& net_log) override; void LoadCookiesForKey(const std::string& key, const LoadedCallback& callback) override; void AddCookie(const CanonicalCookie& cc) override; @@ -60,10 +62,17 @@ private: ~SQLitePersistentCookieStore() override; + void CompleteLoad(const LoadedCallback& callback, + std::vector<std::unique_ptr<CanonicalCookie>> cookie_list); + void CompleteKeyedLoad( + const std::string& key, + const LoadedCallback& callback, + std::vector<std::unique_ptr<CanonicalCookie>> cookie_list); class Backend; const scoped_refptr<Backend> backend_; + NetLogWithSource net_log_; DISALLOW_COPY_AND_ASSIGN(SQLitePersistentCookieStore); };
diff --git a/net/extras/sqlite/sqlite_persistent_cookie_store_perftest.cc b/net/extras/sqlite/sqlite_persistent_cookie_store_perftest.cc index 6132b23..71005556 100644 --- a/net/extras/sqlite/sqlite_persistent_cookie_store_perftest.cc +++ b/net/extras/sqlite/sqlite_persistent_cookie_store_perftest.cc
@@ -20,6 +20,7 @@ #include "net/cookies/canonical_cookie.h" #include "net/cookies/cookie_constants.h" #include "net/extras/sqlite/cookie_crypto_delegate.h" +#include "net/log/net_log_with_source.h" #include "testing/gtest/include/gtest/gtest.h" #include "testing/perf/perf_test.h" #include "url/gurl.h" @@ -66,7 +67,8 @@ void Load() { store_->Load(base::Bind(&SQLitePersistentCookieStorePerfTest::OnLoaded, - base::Unretained(this))); + base::Unretained(this)), + NetLogWithSource()); loaded_event_.Wait(); }
diff --git a/net/extras/sqlite/sqlite_persistent_cookie_store_unittest.cc b/net/extras/sqlite/sqlite_persistent_cookie_store_unittest.cc index ade18a7..aed773f1 100644 --- a/net/extras/sqlite/sqlite_persistent_cookie_store_unittest.cc +++ b/net/extras/sqlite/sqlite_persistent_cookie_store_unittest.cc
@@ -30,6 +30,9 @@ #include "net/cookies/cookie_constants.h" #include "net/cookies/cookie_store_test_callbacks.h" #include "net/extras/sqlite/cookie_crypto_delegate.h" +#include "net/log/net_log_capture_mode.h" +#include "net/log/test_net_log.h" +#include "net/log/test_net_log_util.h" #include "net/test/test_with_scoped_task_environment.h" #include "sql/database.h" #include "sql/meta_table.h" @@ -111,7 +114,8 @@ void Load(CanonicalCookieVector* cookies) { EXPECT_FALSE(loaded_event_.IsSignaled()); store_->Load(base::Bind(&SQLitePersistentCookieStoreTest::OnLoaded, - base::Unretained(this))); + base::Unretained(this)), + net_log_.bound()); loaded_event_.Wait(); cookies->swap(cookies_); } @@ -211,6 +215,7 @@ base::ScopedTempDir temp_dir_; scoped_refptr<SQLitePersistentCookieStore> store_; std::unique_ptr<CookieCryptor> cookie_crypto_delegate_; + BoundTestNetLog net_log_; }; TEST_F(SQLitePersistentCookieStoreTest, TestInvalidMetaTableRecovery) { @@ -317,7 +322,8 @@ FROM_HERE, base::Bind(&SQLitePersistentCookieStoreTest::WaitOnDBEvent, base::Unretained(this))); store_->Load(base::Bind(&SQLitePersistentCookieStoreTest::OnLoaded, - base::Unretained(this))); + base::Unretained(this)), + NetLogWithSource()); t += base::TimeDelta::FromMicroseconds(10); AddCookieWithExpiration("A", "B", "c.com", "/", t, base::Time()); base::WaitableEvent event(base::WaitableEvent::ResetPolicy::AUTOMATIC, @@ -345,7 +351,8 @@ temp_dir_.GetPath().Append(kCookieFilename), client_task_runner_, background_task_runner_, true, nullptr); store_->Load(base::Bind(&SQLitePersistentCookieStoreTest::OnLoaded, - base::Unretained(this))); + base::Unretained(this)), + NetLogWithSource()); loaded_event_.Wait(); ASSERT_EQ(4u, cookies_.size()); cookies_.clear(); @@ -379,9 +386,12 @@ background_task_runner_->PostTask( FROM_HERE, base::Bind(&SQLitePersistentCookieStoreTest::WaitOnDBEvent, base::Unretained(this))); + BoundTestNetLog net_log; store_->Load(base::Bind(&SQLitePersistentCookieStoreTest::OnLoaded, - base::Unretained(this))); + base::Unretained(this)), + net_log.bound()); base::RunLoop run_loop; + net_log.SetCaptureMode(NetLogCaptureMode::Default()); store_->LoadCookiesForKey( "aaa.com", base::Bind(&SQLitePersistentCookieStoreTest::OnKeyLoaded, base::Unretained(this), run_loop.QuitClosure())); @@ -426,6 +436,33 @@ ASSERT_EQ(cookies_loaded.find("foo.bar") != cookies_loaded.end(), true); ASSERT_EQ(cookies_loaded.find("www.bbb.com") != cookies_loaded.end(), true); cookies_.clear(); + + store_ = nullptr; + TestNetLogEntry::List entries; + net_log.GetEntries(&entries); + size_t pos = ExpectLogContainsSomewhere( + entries, 0, NetLogEventType::COOKIE_PERSISTENT_STORE_LOAD, + NetLogEventPhase::BEGIN); + pos = ExpectLogContainsSomewhere( + entries, pos, NetLogEventType::COOKIE_PERSISTENT_STORE_LOAD, + NetLogEventPhase::END); + pos = ExpectLogContainsSomewhere( + entries, 0, NetLogEventType::COOKIE_PERSISTENT_STORE_LOAD, + NetLogEventPhase::BEGIN); + pos = ExpectLogContainsSomewhere( + entries, pos, NetLogEventType::COOKIE_PERSISTENT_STORE_KEY_LOAD_STARTED, + NetLogEventPhase::NONE); + std::string key; + EXPECT_FALSE(entries[pos].GetStringValue("key", &key)); + pos = ExpectLogContainsSomewhere( + entries, pos, NetLogEventType::COOKIE_PERSISTENT_STORE_KEY_LOAD_COMPLETED, + NetLogEventPhase::NONE); + pos = ExpectLogContainsSomewhere( + entries, pos, NetLogEventType::COOKIE_PERSISTENT_STORE_LOAD, + NetLogEventPhase::END); + ExpectLogContainsSomewhere(entries, pos, + NetLogEventType::COOKIE_PERSISTENT_STORE_CLOSED, + NetLogEventPhase::NONE); } TEST_F(SQLitePersistentCookieStoreTest, TestBeforeFlushCallback) {
diff --git a/net/http/http_network_session.cc b/net/http/http_network_session.cc index b492106..9c0395e 100644 --- a/net/http/http_network_session.cc +++ b/net/http/http_network_session.cc
@@ -128,6 +128,7 @@ quic::kInitialIdleTimeoutSecs), quic_migrate_sessions_on_network_change_v2(false), quic_migrate_sessions_early_v2(false), + quic_retry_on_alternate_network_before_handshake(false), quic_go_away_on_path_degrading(false), quic_max_time_on_non_default_network( base::TimeDelta::FromSeconds(kMaxTimeOnNonDefaultNetworkSecs)), @@ -220,6 +221,7 @@ params.quic_max_idle_time_before_crypto_handshake_seconds, params.quic_migrate_sessions_on_network_change_v2, params.quic_migrate_sessions_early_v2, + params.quic_retry_on_alternate_network_before_handshake, params.quic_go_away_on_path_degrading, params.quic_max_time_on_non_default_network, params.quic_max_migrations_to_non_default_network_on_write_error, @@ -383,6 +385,8 @@ params_.quic_migrate_sessions_on_network_change_v2); dict->SetBoolean("migrate_sessions_early_v2", params_.quic_migrate_sessions_early_v2); + dict->SetBoolean("retry_on_alternate_network_before_handshake", + params_.quic_retry_on_alternate_network_before_handshake); dict->SetBoolean("go_away_on_path_degrading", params_.quic_go_away_on_path_degrading); dict->SetInteger("max_time_on_non_default_network_seconds",
diff --git a/net/http/http_network_session.h b/net/http/http_network_session.h index 44f7b67..16aebbd 100644 --- a/net/http/http_network_session.h +++ b/net/http/http_network_session.h
@@ -178,6 +178,9 @@ // If true, connection migration v2 may be used to migrate active QUIC // sessions to alternative network if current network connectivity is poor. bool quic_migrate_sessions_early_v2; + // If true, a new connection may be kicked off on an alternate network when + // a connection fails on the default network before handshake is confirmed. + bool quic_retry_on_alternate_network_before_handshake; // If true, the quic session may mark itself as GOAWAY on path degrading. bool quic_go_away_on_path_degrading; // Maximum time the session could be on the non-default network before
diff --git a/net/http/http_network_transaction.cc b/net/http/http_network_transaction.cc index 526e9e7d..cd6b96b 100644 --- a/net/http/http_network_transaction.cc +++ b/net/http/http_network_transaction.cc
@@ -147,9 +147,9 @@ // Now that we have an HttpRequestInfo object, update server_ssl_config_. session_->GetSSLConfig(*request_, &server_ssl_config_, &proxy_ssl_config_); - if (request_->load_flags & LOAD_DISABLE_CERT_REVOCATION_CHECKING) { - server_ssl_config_.rev_checking_enabled = false; - proxy_ssl_config_.rev_checking_enabled = false; + if (request_->load_flags & LOAD_DISABLE_CERT_NETWORK_FETCHES) { + server_ssl_config_.disable_cert_verification_network_fetches = true; + proxy_ssl_config_.disable_cert_verification_network_fetches = true; } if (HttpUtil::IsMethodSafe(request_info->method)) {
diff --git a/net/http/http_proxy_client_socket_wrapper_unittest.cc b/net/http/http_proxy_client_socket_wrapper_unittest.cc index 6ca6397..8a5970e 100644 --- a/net/http/http_proxy_client_socket_wrapper_unittest.cc +++ b/net/http/http_proxy_client_socket_wrapper_unittest.cc
@@ -136,7 +136,8 @@ quic::kInitialIdleTimeoutSecs, /*migrate_sessions_on_network_change_v2=*/false, /*migrate_sessions_early_v2=*/false, - /*go_away_on_path_degrading*/ false, + /*retry_on_alternate_network_before_handshake=*/false, + /*go_away_on_path_degrading=*/false, base::TimeDelta::FromSeconds(kMaxTimeOnNonDefaultNetworkSecs), kMaxMigrationsToNonDefaultNetworkOnWriteError, kMaxMigrationsToNonDefaultNetworkOnPathDegrading,
diff --git a/net/http/http_stream_factory_job.cc b/net/http/http_stream_factory_job.cc index a04327d2..75e62eb1 100644 --- a/net/http/http_stream_factory_job.cc +++ b/net/http/http_stream_factory_job.cc
@@ -863,9 +863,9 @@ if (proxy_info_.is_https() || proxy_info_.is_quic()) { InitSSLConfig(&proxy_ssl_config_, /*is_proxy=*/true); - // Disable revocation checking for HTTPS proxies since the revocation - // requests are probably going to need to go through the proxy too. - proxy_ssl_config_.rev_checking_enabled = false; + // Disable network fetches for HTTPS proxies, since the network requests + // are probably going to need to go through the proxy too. + proxy_ssl_config_.disable_cert_verification_network_fetches = true; } if (using_ssl_) { InitSSLConfig(&server_ssl_config_, /*is_proxy=*/false);
diff --git a/net/log/net_log_event_type_list.h b/net/log/net_log_event_type_list.h index a6587a9..7df3268 100644 --- a/net/log/net_log_event_type_list.h +++ b/net/log/net_log_event_type_list.h
@@ -3134,3 +3134,26 @@ // "persistence" : <Session persistence setting for the store> // } EVENT_TYPE(COOKIE_STORE_SESSION_PERSISTENCE) + +// Event emitted when the persistent database load is started and completed. +// { +// } +EVENT_TYPE(COOKIE_PERSISTENT_STORE_LOAD) + +// Event emitted when load for a particular key is started. +// { +// "key": <Key to be loaded> +// } +EVENT_TYPE(COOKIE_PERSISTENT_STORE_KEY_LOAD_STARTED) + +// Event emitted when load for a particular key is completed. +// { +// "key": <Key to be loaded> +// } +EVENT_TYPE(COOKIE_PERSISTENT_STORE_KEY_LOAD_COMPLETED) + +// Event emitted when a persistent store has been closed. +// { +// "type": <Classname of persistent cookie store> +// } +EVENT_TYPE(COOKIE_PERSISTENT_STORE_CLOSED)
diff --git a/net/proxy_resolution/pac_file_fetcher_impl.cc b/net/proxy_resolution/pac_file_fetcher_impl.cc index 0201c27..a688c00 100644 --- a/net/proxy_resolution/pac_file_fetcher_impl.cc +++ b/net/proxy_resolution/pac_file_fetcher_impl.cc
@@ -171,7 +171,7 @@ // the proxy might be the only way to the outside world. IGNORE_LIMITS is // used to avoid blocking proxy resolution on other network requests. cur_request_->SetLoadFlags(LOAD_BYPASS_PROXY | LOAD_DISABLE_CACHE | - LOAD_DISABLE_CERT_REVOCATION_CHECKING | + LOAD_DISABLE_CERT_NETWORK_FETCHES | LOAD_IGNORE_LIMITS); // Save the caller's info for notification on completion.
diff --git a/net/proxy_resolution/pac_file_fetcher_impl_unittest.cc b/net/proxy_resolution/pac_file_fetcher_impl_unittest.cc index 029c025..b658df8 100644 --- a/net/proxy_resolution/pac_file_fetcher_impl_unittest.cc +++ b/net/proxy_resolution/pac_file_fetcher_impl_unittest.cc
@@ -154,7 +154,7 @@ int OnBeforeURLRequest(URLRequest* request, CompletionOnceCallback callback, GURL* new_url) override { - EXPECT_TRUE(request->load_flags() & LOAD_DISABLE_CERT_REVOCATION_CHECKING); + EXPECT_TRUE(request->load_flags() & LOAD_DISABLE_CERT_NETWORK_FETCHES); return OK; }
diff --git a/net/proxy_resolution/proxy_resolver_v8_tracing_unittest.cc b/net/proxy_resolution/proxy_resolver_v8_tracing_unittest.cc index 49722ff..73d8c4f 100644 --- a/net/proxy_resolution/proxy_resolver_v8_tracing_unittest.cc +++ b/net/proxy_resolution/proxy_resolver_v8_tracing_unittest.cc
@@ -695,7 +695,9 @@ std::unique_ptr<ResolveHostRequest> CreateRequest( const HostPortPair& host, - const NetLogWithSource& net_log) override { + const NetLogWithSource& net_log, + const base::Optional<ResolveHostParameters>& optional_parameters) + override { NOTIMPLEMENTED(); return nullptr; }
diff --git a/net/proxy_resolution/proxy_resolver_v8_tracing_wrapper_unittest.cc b/net/proxy_resolution/proxy_resolver_v8_tracing_wrapper_unittest.cc index 7610e8bb..99de6bc 100644 --- a/net/proxy_resolution/proxy_resolver_v8_tracing_wrapper_unittest.cc +++ b/net/proxy_resolution/proxy_resolver_v8_tracing_wrapper_unittest.cc
@@ -792,7 +792,9 @@ std::unique_ptr<ResolveHostRequest> CreateRequest( const HostPortPair& host, - const NetLogWithSource& net_log) override { + const NetLogWithSource& net_log, + const base::Optional<ResolveHostParameters>& optional_parameters) + override { NOTIMPLEMENTED(); return nullptr; }
diff --git a/net/quic/crypto/proof_verifier_chromium_test.cc b/net/quic/crypto/proof_verifier_chromium_test.cc index c35ae43..af39290 100644 --- a/net/quic/crypto/proof_verifier_chromium_test.cc +++ b/net/quic/crypto/proof_verifier_chromium_test.cc
@@ -52,6 +52,7 @@ ADD_FAILURE() << "CertVerifier::Verify() should not be called"; return ERR_FAILED; } + void SetConfig(const Config& config) override {} }; // A mock CTPolicyEnforcer that returns a custom verification result.
diff --git a/net/quic/quic_chromium_client_session.cc b/net/quic/quic_chromium_client_session.cc index 9e10bf53..50d861e 100644 --- a/net/quic/quic_chromium_client_session.cc +++ b/net/quic/quic_chromium_client_session.cc
@@ -1446,6 +1446,7 @@ } NotifyRequestsOfConfirmation(OK); + // TODO(zhongyi): spin up the timer to migrate back to the default network. } quic::QuicSpdySession::OnCryptoHandshakeEvent(event); } @@ -2658,7 +2659,7 @@ going_away_ = true; DCHECK_EQ(0u, GetNumActiveStreams()); DCHECK(!connection()->connected()); - base::ThreadTaskRunnerHandle::Get()->PostTask( + task_runner_->PostTask( FROM_HERE, base::Bind(&QuicChromiumClientSession::NotifyFactoryOfSessionClosed, weak_factory_.GetWeakPtr()));
diff --git a/net/quic/quic_stream_factory.cc b/net/quic/quic_stream_factory.cc index 9db78c5..a13d210 100644 --- a/net/quic/quic_stream_factory.cc +++ b/net/quic/quic_stream_factory.cc
@@ -315,6 +315,7 @@ HostResolver* host_resolver, const QuicSessionAliasKey& key, bool was_alternative_service_recently_broken, + bool retry_on_alternate_network_before_handshake, RequestPriority priority, int cert_verify_flags, const NetLogWithSource& net_log); @@ -385,6 +386,7 @@ const RequestPriority priority_; const int cert_verify_flags_; const bool was_alternative_service_recently_broken_; + const bool retry_on_alternate_network_before_handshake_; const NetLogWithSource net_log_; int num_sent_client_hellos_; QuicChromiumClientSession* session_; @@ -407,6 +409,7 @@ HostResolver* host_resolver, const QuicSessionAliasKey& key, bool was_alternative_service_recently_broken, + bool retry_on_alternate_network_before_handshake, RequestPriority priority, int cert_verify_flags, const NetLogWithSource& net_log) @@ -419,6 +422,8 @@ cert_verify_flags_(cert_verify_flags), was_alternative_service_recently_broken_( was_alternative_service_recently_broken), + retry_on_alternate_network_before_handshake_( + retry_on_alternate_network_before_handshake), net_log_( NetLogWithSource::Make(net_log.net_log(), NetLogSourceType::QUIC_STREAM_FACTORY_JOB)), @@ -555,6 +560,8 @@ key_, quic_version_, cert_verify_flags_, require_confirmation, address_list_, dns_resolution_start_time_, dns_resolution_end_time_, net_log_, &session_, &network_); + DVLOG(1) << "Created session on network: " << network_; + if (rv != OK) { DCHECK(rv != ERR_IO_PENDING); DCHECK(!session_); @@ -601,6 +608,24 @@ if (was_alternative_service_recently_broken_) UMA_HISTOGRAM_BOOLEAN("Net.QuicSession.ConnectAfterBroken", rv == OK); + if (retry_on_alternate_network_before_handshake_ && session_ && + !session_->IsCryptoHandshakeConfirmed() && + network_ == factory_->default_network()) { + if (session_->error() == quic::QUIC_NETWORK_IDLE_TIMEOUT || + session_->error() == quic::QUIC_HANDSHAKE_TIMEOUT) { + // Retry the connection on an alternate network if crypto handshake failed + // with network idle time out or handshake time out. + DCHECK(network_ != NetworkChangeNotifier::kInvalidNetworkHandle); + network_ = factory_->FindAlternateNetwork(network_); + if (network_ != NetworkChangeNotifier::kInvalidNetworkHandle) { + DVLOG(1) << "Retry connection on alternate network"; + session_ = nullptr; + io_state_ = STATE_CONNECT; + return OK; + } + } + } + if (rv != OK) return rv; @@ -737,6 +762,7 @@ int max_idle_time_before_crypto_handshake_seconds, bool migrate_sessions_on_network_change_v2, bool migrate_sessions_early_v2, + bool retry_on_alternate_network_before_handshake, bool go_away_on_path_degrading, base::TimeDelta max_time_on_non_default_network, int max_migrations_to_non_default_network_on_write_error, @@ -792,6 +818,9 @@ NetworkChangeNotifier::AreNetworkHandlesSupported()), migrate_sessions_early_v2_(migrate_sessions_early_v2 && migrate_sessions_on_network_change_v2_), + retry_on_alternate_network_before_handshake_( + retry_on_alternate_network_before_handshake && + migrate_sessions_on_network_change_v2_), go_away_on_path_degrading_(go_away_on_path_degrading), default_network_(NetworkChangeNotifier::kInvalidNetworkHandle), max_time_on_non_default_network_(max_time_on_non_default_network), @@ -834,7 +863,7 @@ if (has_aes_hardware_support) crypto_config_.PreferAesGcm(); - if (migrate_sessions_early_v2) + if (migrate_sessions_early_v2 || retry_on_alternate_network_before_handshake) DCHECK(migrate_sessions_on_network_change_v2); // goaway_sessions_on_ip_change and close_sessions_on_ip_change should never @@ -1049,6 +1078,7 @@ std::unique_ptr<Job> job = std::make_unique<Job>(this, quic_version, host_resolver_, key, WasQuicRecentlyBroken(session_key.server_id()), + retry_on_alternate_network_before_handshake_, priority, cert_verify_flags, net_log); int rv = job->Run( base::BindRepeating(&QuicStreamFactory::OnJobComplete, @@ -1462,13 +1492,13 @@ CreateSocket(net_log.net_log(), net_log.source())); // Passing in kInvalidNetworkHandle binds socket to default network. - int rv = ConfigureSocket(socket.get(), addr, - NetworkChangeNotifier::kInvalidNetworkHandle, + int rv = ConfigureSocket(socket.get(), addr, *network, key.session_key().socket_tag()); if (rv != OK) return rv; - if (migrate_sessions_on_network_change_v2_) { + if (migrate_sessions_on_network_change_v2_ && + *network == NetworkChangeNotifier::kInvalidNetworkHandle) { *network = socket->GetBoundNetwork(); if (default_network_ == NetworkChangeNotifier::kInvalidNetworkHandle) { // QuicStreamFactory may miss the default network signal before its
diff --git a/net/quic/quic_stream_factory.h b/net/quic/quic_stream_factory.h index ca5e01c..3b4a2cc 100644 --- a/net/quic/quic_stream_factory.h +++ b/net/quic/quic_stream_factory.h
@@ -242,6 +242,7 @@ int max_idle_time_before_crypto_handshake_seconds, bool migrate_sessions_on_network_change_v2, bool migrate_sessions_early_v2, + bool retry_on_alternate_network_before_handshake, bool go_away_on_path_degrading, base::TimeDelta max_time_on_non_default_network, int max_migrations_to_non_default_network_on_write_error, @@ -380,6 +381,10 @@ return mark_quic_broken_when_network_blackholes_; } + NetworkChangeNotifier::NetworkHandle default_network() const { + return default_network_; + } + // Dumps memory allocation stats. |parent_dump_absolute_name| is the name // used by the parent MemoryAllocatorDump in the memory dump hierarchy. void DumpMemoryStats(base::trace_event::ProcessMemoryDump* pmd, @@ -542,6 +547,10 @@ // connection experiences poor connectivity. const bool migrate_sessions_early_v2_; + // Set if a new connection may be kicked off on an alternate network when a + // connection fails on the default network before handshake is confirmed. + const bool retry_on_alternate_network_before_handshake_; + // Set if client should mark the session as GOAWAY when the connection // experiences poor connectivity const bool go_away_on_path_degrading_;
diff --git a/net/quic/quic_stream_factory_fuzzer.cc b/net/quic/quic_stream_factory_fuzzer.cc index 99bb6bb..0d9ce44e 100644 --- a/net/quic/quic_stream_factory_fuzzer.cc +++ b/net/quic/quic_stream_factory_fuzzer.cc
@@ -110,6 +110,7 @@ bool goaway_sessions_on_ip_change = false; bool migrate_sessions_early_v2 = false; bool migrate_sessions_on_network_change_v2 = false; + bool retry_on_alternate_network_before_handshake = false; bool go_away_on_path_degrading = false; if (!close_sessions_on_ip_change) { @@ -118,6 +119,8 @@ migrate_sessions_on_network_change_v2 = data_provider.ConsumeBool(); if (migrate_sessions_on_network_change_v2) { migrate_sessions_early_v2 = data_provider.ConsumeBool(); + retry_on_alternate_network_before_handshake = + data_provider.ConsumeBool(); } } } @@ -139,6 +142,7 @@ kIdleConnectionTimeoutSeconds, quic::kPingTimeoutSecs, quic::kMaxTimeForCryptoHandshakeSecs, quic::kInitialIdleTimeoutSecs, migrate_sessions_on_network_change_v2, migrate_sessions_early_v2, + retry_on_alternate_network_before_handshake, go_away_on_path_degrading, base::TimeDelta::FromSeconds(kMaxTimeOnNonDefaultNetworkSecs), kMaxMigrationsToNonDefaultNetworkOnWriteError,
diff --git a/net/quic/quic_stream_factory_test.cc b/net/quic/quic_stream_factory_test.cc index 0326a176..fe535e8 100644 --- a/net/quic/quic_stream_factory_test.cc +++ b/net/quic/quic_stream_factory_test.cc
@@ -259,6 +259,7 @@ quic::kInitialIdleTimeoutSecs), migrate_sessions_on_network_change_v2_(false), migrate_sessions_early_v2_(false), + retry_on_alternate_network_before_handshake_(false), go_away_on_path_degrading_(false), allow_server_migration_(false), race_cert_verification_(false), @@ -283,6 +284,7 @@ max_time_before_crypto_handshake_seconds_, max_idle_time_before_crypto_handshake_seconds_, migrate_sessions_on_network_change_v2_, migrate_sessions_early_v2_, + retry_on_alternate_network_before_handshake_, go_away_on_path_degrading_, base::TimeDelta::FromSeconds(kMaxTimeOnNonDefaultNetworkSecs), kMaxMigrationsToNonDefaultNetworkOnWriteError, @@ -304,6 +306,7 @@ mock_ncn->SetConnectedNetworksList(connected_networks); migrate_sessions_on_network_change_v2_ = true; migrate_sessions_early_v2_ = true; + retry_on_alternate_network_before_handshake_ = true; socket_factory_.reset(new TestConnectionMigrationSocketFactory); Initialize(); } @@ -812,6 +815,8 @@ void TestMigrationOnWriteErrorWithMultipleNotifications( IoMode write_error_mode, bool disconnect_before_connect); + void TestNewConnectionOnAlternateNetworkBeforeHandshake( + quic::QuicErrorCode error); QuicFlagSaver flags_; // Save/restore all QUIC flag values. MockHostResolver host_resolver_; @@ -855,6 +860,7 @@ int max_idle_time_before_crypto_handshake_seconds_; bool migrate_sessions_on_network_change_v2_; bool migrate_sessions_early_v2_; + bool retry_on_alternate_network_before_handshake_; bool go_away_on_path_degrading_; bool allow_server_migration_; bool race_cert_verification_; @@ -4705,10 +4711,137 @@ EXPECT_EQ(0u, task_runner->GetPendingTaskCount()); EXPECT_FALSE(HasActiveSession(host_port_pair_)); + EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_)); EXPECT_TRUE(socket_data.AllReadDataConsumed()); EXPECT_TRUE(socket_data.AllWriteDataConsumed()); } +TEST_P(QuicStreamFactoryTest, NewConnectionBeforeHandshakeAfterIdleTimeout) { + TestNewConnectionOnAlternateNetworkBeforeHandshake( + quic::QUIC_NETWORK_IDLE_TIMEOUT); +} + +TEST_P(QuicStreamFactoryTest, NewConnectionAfterHandshakeTimeout) { + TestNewConnectionOnAlternateNetworkBeforeHandshake( + quic::QUIC_HANDSHAKE_TIMEOUT); +} + +void QuicStreamFactoryTestBase:: + TestNewConnectionOnAlternateNetworkBeforeHandshake( + quic::QuicErrorCode quic_error) { + DCHECK(quic_error == quic::QUIC_NETWORK_IDLE_TIMEOUT || + quic_error == quic::QUIC_HANDSHAKE_TIMEOUT); + InitializeConnectionMigrationV2Test( + {kDefaultNetworkForTests, kNewNetworkForTests}); + + // Using a testing task runner. + auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>(); + QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get()); + + // Use cold start mode to send crypto message for handshake. + crypto_client_stream_factory_.set_handshake_mode( + MockCryptoClientStream::COLD_START_WITH_CHLO_SENT); + + // Socket data for connection on the default network. + MockQuicData socket_data; + socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); + socket_data.AddWrite(ASYNC, client_maker_.MakeDummyCHLOPacket(1)); + socket_data.AddSocketDataToFactory(socket_factory_.get()); + + // Socket data for connection on the alternate network. + MockQuicData socket_data2; + quic::QuicStreamOffset header_stream_offset = 0; + socket_data2.AddWrite(SYNCHRONOUS, client_maker_.MakeDummyCHLOPacket(1)); + socket_data2.AddRead(ASYNC, ERR_IO_PENDING); // Pause. + // Change the encryption level after handshake is confirmed. + client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE); + socket_data2.AddWrite( + ASYNC, ConstructInitialSettingsPacket(2, &header_stream_offset)); + socket_data2.AddWrite( + ASYNC, ConstructGetRequestPacket(3, GetNthClientInitiatedStreamId(0), + true, true, &header_stream_offset)); + socket_data2.AddRead( + ASYNC, ConstructOkResponsePacket(1, GetNthClientInitiatedStreamId(0), + false, false)); + socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); + socket_data2.AddWrite(SYNCHRONOUS, + client_maker_.MakeAckAndRstPacket( + 4, false, GetNthClientInitiatedStreamId(0), + quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true)); + socket_data2.AddSocketDataToFactory(socket_factory_.get()); + + // Create request and QuicHttpStream. + QuicStreamRequest request(factory_.get()); + EXPECT_EQ(ERR_IO_PENDING, + request.Request(host_port_pair_, version_, privacy_mode_, + DEFAULT_PRIORITY, SocketTag(), + /*cert_verify_flags=*/0, url_, net_log_, + &net_error_details_, callback_.callback())); + + base::RunLoop().RunUntilIdle(); + + // Ensure that session is alive but not active. + EXPECT_FALSE(HasActiveSession(host_port_pair_)); + EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_)); + QuicChromiumClientSession* session = GetPendingSession(host_port_pair_); + EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session)); + EXPECT_EQ(0u, task_runner->GetPendingTaskCount()); + + quic::QuicString error_details; + if (quic_error == quic::QUIC_NETWORK_IDLE_TIMEOUT) { + error_details = "No recent network activity."; + } else { + error_details = "Handshake timeout expired."; + } + session->connection()->CloseConnection( + quic_error, error_details, quic::ConnectionCloseBehavior::SILENT_CLOSE); + + // A task will be posted to clean up the session in the factory. + EXPECT_EQ(1u, task_runner->GetPendingTaskCount()); + task_runner->FastForwardUntilNoTasksRemain(); + + // Verify a new session is created on the alternate network. + EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_)); + EXPECT_FALSE(HasActiveSession(host_port_pair_)); + QuicChromiumClientSession* session2 = GetPendingSession(host_port_pair_); + EXPECT_NE(session, session2); + + // Confirm the handshake on the alternate network. + crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent( + quic::QuicSession::HANDSHAKE_CONFIRMED); + EXPECT_THAT(callback_.WaitForResult(), IsOk()); + EXPECT_TRUE(HasActiveSession(host_port_pair_)); + // Resume the data now so that data can be sent and read. + socket_data2.Resume(); + + // Create the stream. + std::unique_ptr<HttpStream> stream = CreateStream(&request); + EXPECT_TRUE(stream.get()); + HttpRequestInfo request_info; + request_info.method = "GET"; + request_info.url = GURL("https://www.example.org/"); + request_info.traffic_annotation = + MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS); + EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY, + net_log_, CompletionOnceCallback())); + // Send the request. + HttpResponseInfo response; + HttpRequestHeaders request_headers; + EXPECT_EQ(OK, stream->SendRequest(request_headers, &response, + callback_.callback())); + // Run the message loop to finish asynchronous mock write. + base::RunLoop().RunUntilIdle(); + // Read the response. + EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback())); + EXPECT_EQ(200, response.headers->response_code()); + + stream.reset(); + EXPECT_TRUE(socket_data.AllReadDataConsumed()); + EXPECT_TRUE(socket_data.AllWriteDataConsumed()); + EXPECT_TRUE(socket_data2.AllReadDataConsumed()); + EXPECT_TRUE(socket_data2.AllWriteDataConsumed()); +} + // Test that connection will be closed with PACKET_WRITE_ERROR if a write error // is triggered before handshake is confirmed and connection migration is turned // on.
diff --git a/net/socket/socks_client_socket_unittest.cc b/net/socket/socks_client_socket_unittest.cc index da5e90a9..f4e87a03 100644 --- a/net/socket/socks_client_socket_unittest.cc +++ b/net/socket/socks_client_socket_unittest.cc
@@ -109,7 +109,9 @@ std::unique_ptr<ResolveHostRequest> CreateRequest( const HostPortPair& host, - const NetLogWithSource& net_log) override { + const NetLogWithSource& net_log, + const base::Optional<ResolveHostParameters>& optional_parameters) + override { NOTIMPLEMENTED(); return nullptr; }
diff --git a/net/ssl/ssl_config.cc b/net/ssl/ssl_config.cc index 515c410..dd7273a 100644 --- a/net/ssl/ssl_config.cc +++ b/net/ssl/ssl_config.cc
@@ -22,11 +22,7 @@ SSLConfig::CertAndStatus::~CertAndStatus() = default; SSLConfig::SSLConfig() - : rev_checking_enabled(false), - rev_checking_required_local_anchors(false), - sha1_local_anchors_enabled(false), - symantec_enforcement_disabled(false), - version_min(kDefaultSSLVersionMin), + : version_min(kDefaultSSLVersionMin), version_max(kDefaultSSLVersionMax), tls13_variant(kDefaultTLS13Variant), early_data_enabled(false), @@ -34,6 +30,7 @@ channel_id_enabled(false), false_start_enabled(true), require_ecdhe(false), + disable_cert_verification_network_fetches(false), send_client_cert(false), renego_allowed_default(false) {} @@ -55,14 +52,8 @@ int SSLConfig::GetCertVerifyFlags() const { int flags = 0; - if (rev_checking_enabled) - flags |= CertVerifier::VERIFY_REV_CHECKING_ENABLED; - if (rev_checking_required_local_anchors) - flags |= CertVerifier::VERIFY_REV_CHECKING_REQUIRED_LOCAL_ANCHORS; - if (sha1_local_anchors_enabled) - flags |= CertVerifier::VERIFY_ENABLE_SHA1_LOCAL_ANCHORS; - if (symantec_enforcement_disabled) - flags |= CertVerifier::VERIFY_DISABLE_SYMANTEC_ENFORCEMENT; + if (disable_cert_verification_network_fetches) + flags |= CertVerifier::VERIFY_DISABLE_NETWORK_FETCHES; return flags; }
diff --git a/net/ssl/ssl_config.h b/net/ssl/ssl_config.h index 6604979..2d7782e0 100644 --- a/net/ssl/ssl_config.h +++ b/net/ssl/ssl_config.h
@@ -66,31 +66,6 @@ // configuration. int GetCertVerifyFlags() const; - // rev_checking_enabled is true if online certificate revocation checking is - // enabled (i.e. OCSP and CRL fetching). - // - // Regardless of this flag, CRLSet checking is always enabled and locally - // cached revocation information will be considered. - bool rev_checking_enabled; - - // rev_checking_required_local_anchors is true if revocation checking is - // required to succeed when certificates chain to local trust anchors (that - // is, non-public CAs). If revocation information cannot be obtained, such - // certificates will be treated as revoked ("hard-fail"). - // Note: This is distinct from rev_checking_enabled. If true, it is - // equivalent to also setting rev_checking_enabled, but only when the - // certificate chain chains to a local (non-public) trust anchor. - bool rev_checking_required_local_anchors; - - // sha1_local_anchors_enabled is true if SHA-1 signed certificates issued by a - // local (non-public) trust anchor should be allowed. - bool sha1_local_anchors_enabled; - - // symantec_enforcement_disabled is true if the policies outlined in - // https://security.googleblog.com/2017/09/chromes-plan-to-distrust-symantec.html - // should not be enforced. - bool symantec_enforcement_disabled; - // The minimum and maximum protocol versions that are enabled. // (Use the SSL_PROTOCOL_VERSION_xxx enumerators defined above.) // SSL 2.0 and SSL 3.0 are not supported. If version_max < version_min, it @@ -162,6 +137,14 @@ // response to the user explicitly accepting the bad certificate. std::vector<CertAndStatus> allowed_bad_certs; + // True if, for a single connection, any dependent network fetches should + // be disabled. This can be used to avoid triggering re-entrancy in the + // network layer. For example, fetching a PAC script over HTTPS may cause + // AIA, OCSP, or CRL fetches to block on retrieving the PAC script, while + // the PAC script fetch is waiting for those dependent fetches, creating a + // deadlock. + bool disable_cert_verification_network_fetches; + // True if we should send client_cert to the server. bool send_client_cert;
diff --git a/net/ssl/ssl_config_service.cc b/net/ssl/ssl_config_service.cc index c53a449d..cb6799e 100644 --- a/net/ssl/ssl_config_service.cc +++ b/net/ssl/ssl_config_service.cc
@@ -17,20 +17,14 @@ // Checks if the config-service managed fields in two SSLConfigs are the same. bool SSLConfigsAreEqual(const net::SSLConfig& config1, const net::SSLConfig& config2) { - return std::tie(config1.rev_checking_enabled, - config1.rev_checking_required_local_anchors, - config1.sha1_local_anchors_enabled, - config1.symantec_enforcement_disabled, config1.version_min, - config1.version_max, config1.tls13_variant, - config1.disabled_cipher_suites, config1.channel_id_enabled, - config1.false_start_enabled, config1.require_ecdhe) == - std::tie(config2.rev_checking_enabled, - config2.rev_checking_required_local_anchors, - config2.sha1_local_anchors_enabled, - config2.symantec_enforcement_disabled, config2.version_min, - config2.version_max, config2.tls13_variant, - config2.disabled_cipher_suites, config2.channel_id_enabled, - config2.false_start_enabled, config2.require_ecdhe); + return std::tie(config1.version_min, config1.version_max, + config1.tls13_variant, config1.disabled_cipher_suites, + config1.channel_id_enabled, config1.false_start_enabled, + config1.require_ecdhe) == + std::tie(config2.version_min, config2.version_max, + config2.tls13_variant, config2.disabled_cipher_suites, + config2.channel_id_enabled, config2.false_start_enabled, + config2.require_ecdhe); } } // namespace
diff --git a/net/ssl/ssl_config_service.h b/net/ssl/ssl_config_service.h index 21e686c..b1157bb 100644 --- a/net/ssl/ssl_config_service.h +++ b/net/ssl/ssl_config_service.h
@@ -27,13 +27,13 @@ // Notify observers if SSL settings have changed. We don't check all of the // data in SSLConfig, just those that qualify as a user config change. // The following settings are considered user changes: - // rev_checking_enabled // version_min // version_max + // tls13_variant // disabled_cipher_suites // channel_id_enabled // false_start_enabled - // require_forward_secrecy + // require_ecdhe virtual void OnSSLConfigChanged() = 0; protected:
diff --git a/net/ssl/ssl_config_service_unittest.cc b/net/ssl/ssl_config_service_unittest.cc index 391d663..4763a7b6 100644 --- a/net/ssl/ssl_config_service_unittest.cc +++ b/net/ssl/ssl_config_service_unittest.cc
@@ -52,7 +52,6 @@ TEST(SSLConfigServiceTest, NoChangesWontNotifyObservers) { SSLConfig initial_config; - initial_config.rev_checking_enabled = true; initial_config.false_start_enabled = false; initial_config.version_min = SSL_PROTOCOL_VERSION_TLS1; initial_config.version_max = SSL_PROTOCOL_VERSION_TLS1_2; @@ -69,7 +68,6 @@ TEST(SSLConfigServiceTest, ForceNotificationNotifiesObservers) { SSLConfig initial_config; - initial_config.rev_checking_enabled = true; initial_config.false_start_enabled = false; initial_config.version_min = SSL_PROTOCOL_VERSION_TLS1; initial_config.version_max = SSL_PROTOCOL_VERSION_TLS1_2; @@ -86,9 +84,6 @@ TEST(SSLConfigServiceTest, ConfigUpdatesNotifyObservers) { SSLConfig initial_config; - initial_config.rev_checking_enabled = true; - initial_config.rev_checking_required_local_anchors = false; - initial_config.sha1_local_anchors_enabled = true; initial_config.false_start_enabled = false; initial_config.require_ecdhe = false; initial_config.version_min = SSL_PROTOCOL_VERSION_TLS1; @@ -99,18 +94,6 @@ mock_service.AddObserver(&observer); // Test that the basic boolean preferences trigger updates. - initial_config.rev_checking_enabled = false; - EXPECT_CALL(observer, OnSSLConfigChanged()).Times(1); - mock_service.SetSSLConfig(initial_config); - - initial_config.rev_checking_required_local_anchors = true; - EXPECT_CALL(observer, OnSSLConfigChanged()).Times(1); - mock_service.SetSSLConfig(initial_config); - - initial_config.sha1_local_anchors_enabled = false; - EXPECT_CALL(observer, OnSSLConfigChanged()).Times(1); - mock_service.SetSSLConfig(initial_config); - initial_config.false_start_enabled = true; EXPECT_CALL(observer, OnSSLConfigChanged()).Times(1); mock_service.SetSSLConfig(initial_config);
diff --git a/net/ssl/ssl_config_unittest.cc b/net/ssl/ssl_config_unittest.cc index 11001b4..9dde2242 100644 --- a/net/ssl/ssl_config_unittest.cc +++ b/net/ssl/ssl_config_unittest.cc
@@ -12,22 +12,13 @@ namespace { void CheckCertVerifyFlags(SSLConfig* ssl_config, - bool rev_checking_enabled, - bool rev_checking_required_local_anchors, - bool symantec_enforcement_disabled) { - ssl_config->rev_checking_enabled = rev_checking_enabled; - ssl_config->rev_checking_required_local_anchors = - rev_checking_required_local_anchors; - ssl_config->symantec_enforcement_disabled = symantec_enforcement_disabled; + bool disable_cert_verification_network_fetches) { + ssl_config->disable_cert_verification_network_fetches = + disable_cert_verification_network_fetches; int flags = ssl_config->GetCertVerifyFlags(); - EXPECT_EQ(rev_checking_enabled, - !!(flags & CertVerifier::VERIFY_REV_CHECKING_ENABLED)); - EXPECT_EQ( - rev_checking_required_local_anchors, - !!(flags & CertVerifier::VERIFY_REV_CHECKING_REQUIRED_LOCAL_ANCHORS)); - EXPECT_EQ(symantec_enforcement_disabled, - !!(flags & CertVerifier::VERIFY_DISABLE_SYMANTEC_ENFORCEMENT)); + EXPECT_EQ(disable_cert_verification_network_fetches, + !!(flags & CertVerifier::VERIFY_DISABLE_NETWORK_FETCHES)); } } // namespace @@ -35,29 +26,9 @@ TEST(SSLConfigTest, GetCertVerifyFlags) { SSLConfig ssl_config; CheckCertVerifyFlags(&ssl_config, - /*rev_checking_enabled=*/true, - /*rev_checking_required_local_anchors=*/true, - /*symantec_enforcement_disabled=*/true); - + /*disable_cert_verification_network_fetches*/ false); CheckCertVerifyFlags(&ssl_config, - /*rev_checking_enabled=*/true, - /*rev_checking_required_local_anchors=*/false, - /*symantec_enforcement_disabled=*/false); - - CheckCertVerifyFlags(&ssl_config, - /*rev_checking_enabled=*/false, - /*rev_checking_required_local_anchors=*/true, - /*symantec_enforcement_disabled=*/false); - - CheckCertVerifyFlags(&ssl_config, - /*rev_checking_enabled=*/false, - /*rev_checking_required_local_anchors=*/false, - /*symantec_enforcement_disabled=*/true); - - CheckCertVerifyFlags(&ssl_config, - /*rev_checking_enabled=*/false, - /*rev_checking_required_local_anchors=*/false, - /*symantec_enforcement_disabled=*/false); + /*disable_cert_verification_network_fetches*/ true); } } // namespace net
diff --git a/net/url_request/url_request_unittest.cc b/net/url_request/url_request_unittest.cc index 03702a71..9812f3b 100644 --- a/net/url_request/url_request_unittest.cc +++ b/net/url_request/url_request_unittest.cc
@@ -4128,13 +4128,8 @@ class TestSSLConfigService : public SSLConfigService { public: - TestSSLConfigService(bool online_rev_checking, - bool rev_checking_required_local_anchors, - bool token_binding_enabled) - : online_rev_checking_(online_rev_checking), - rev_checking_required_local_anchors_( - rev_checking_required_local_anchors), - token_binding_enabled_(token_binding_enabled), + explicit TestSSLConfigService(bool token_binding_enabled) + : token_binding_enabled_(token_binding_enabled), min_version_(kDefaultSSLVersionMin), max_version_(kDefaultSSLVersionMax) {} ~TestSSLConfigService() override = default; @@ -4145,9 +4140,6 @@ // SSLConfigService: void GetSSLConfig(SSLConfig* config) override { *config = SSLConfig(); - config->rev_checking_enabled = online_rev_checking_; - config->rev_checking_required_local_anchors = - rev_checking_required_local_anchors_; config->version_min = min_version_; config->version_max = max_version_; if (token_binding_enabled_) { @@ -4161,8 +4153,6 @@ } private: - const bool online_rev_checking_; - const bool rev_checking_required_local_anchors_; const bool token_binding_enabled_; uint16_t min_version_; uint16_t max_version_; @@ -4177,8 +4167,8 @@ TokenBindingURLRequestTest() = default; void SetUp() override { - ssl_config_service_ = - std::make_unique<TestSSLConfigService>(false, false, true); + ssl_config_service_ = std::make_unique<TestSSLConfigService>( + true /* token_binding_enabled */); default_context().set_ssl_config_service(ssl_config_service_.get()); channel_id_service_ = std::make_unique<ChannelIDService>(new DefaultChannelIDStore(NULL)); @@ -10818,8 +10808,6 @@ public: HTTPSFallbackTest() : context_(true) { ssl_config_service_ = std::make_unique<TestSSLConfigService>( - false /* online revocation checking */, - false /* require rev. checking for local anchors */, false /* token binding enabled */); context_.set_ssl_config_service(ssl_config_service_.get()); } @@ -11026,9 +11014,10 @@ void SetUp() override { context_.SetCTPolicyEnforcer(std::make_unique<DefaultCTPolicyEnforcer>()); - SetupContext(); context_.Init(); + context_.cert_verifier()->SetConfig(GetCertVerifierConfig()); + scoped_refptr<X509Certificate> root_cert = ImportCertFromFile(GetTestCertsDirectory(), "ocsp-test-root.pem"); CHECK_NE(static_cast<X509Certificate*>(NULL), root_cert.get()); @@ -11092,15 +11081,13 @@ } protected: - // SetupContext configures the URLRequestContext that will be used for making - // connetions to testserver. This can be overridden in test subclasses for - // different behaviour. - virtual void SetupContext() { - ssl_config_service_ = std::make_unique<TestSSLConfigService>( - true /* online revocation checking */, - false /* require rev. checking for local anchors */, - false /* token binding enabled */); - context_.set_ssl_config_service(ssl_config_service_.get()); + // GetCertVerifierConfig() configures the URLRequestContext that will be used + // for making connections to the testserver. This can be overridden in test + // subclasses for different behaviour. + virtual CertVerifier::Config GetCertVerifierConfig() { + CertVerifier::Config config; + config.enable_rev_checking = true; + return config; } std::unique_ptr<ScopedTestRoot> test_root_; @@ -11699,12 +11686,9 @@ class HTTPSAIATest : public HTTPSOCSPTest { public: - void SetupContext() override { - ssl_config_service_ = std::make_unique<TestSSLConfigService>( - false /* online revocation checking */, - false /* require rev. checking for local anchors */, - false /* token binding enabled */); - context_.set_ssl_config_service(ssl_config_service_.get()); + CertVerifier::Config GetCertVerifierConfig() override { + CertVerifier::Config config; + return config; } }; @@ -11744,12 +11728,10 @@ class HTTPSHardFailTest : public HTTPSOCSPTest { protected: - void SetupContext() override { - ssl_config_service_ = std::make_unique<TestSSLConfigService>( - false /* online revocation checking */, - true /* require rev. checking for local anchors */, - false /* token binding enabled */); - context_.set_ssl_config_service(ssl_config_service_.get()); + CertVerifier::Config GetCertVerifierConfig() override { + CertVerifier::Config config; + config.require_rev_checking_local_anchors = true; + return config; } }; @@ -11789,12 +11771,9 @@ class HTTPSEVCRLSetTest : public HTTPSOCSPTest { protected: - void SetupContext() override { - ssl_config_service_ = std::make_unique<TestSSLConfigService>( - false /* online revocation checking */, - false /* require rev. checking for local anchors */, - false /* token binding enabled */); - context_.set_ssl_config_service(ssl_config_service_.get()); + CertVerifier::Config GetCertVerifierConfig() override { + CertVerifier::Config config; + return config; } }; @@ -11964,12 +11943,9 @@ class HTTPSCRLSetTest : public HTTPSOCSPTest { protected: - void SetupContext() override { - ssl_config_service_ = std::make_unique<TestSSLConfigService>( - false /* online revocation checking */, - false /* require rev. checking for local anchors */, - false /* token binding enabled */); - context_.set_ssl_config_service(ssl_config_service_.get()); + CertVerifier::Config GetCertVerifierConfig() override { + CertVerifier::Config config; + return config; } void SetUp() override {
diff --git a/ppapi/BUILD.gn b/ppapi/BUILD.gn index 7d41dff..c190647 100644 --- a/ppapi/BUILD.gn +++ b/ppapi/BUILD.gn
@@ -104,6 +104,8 @@ "tests/test_tcp_socket.h", "tests/test_tcp_socket_private.cc", "tests/test_tcp_socket_private.h", + "tests/test_tcp_socket_private_crash.cc", + "tests/test_tcp_socket_private_crash.h", "tests/test_test_internals.cc", "tests/test_test_internals.h", "tests/test_trace_event.cc",
diff --git a/ppapi/tests/test_tcp_socket_private_crash.cc b/ppapi/tests/test_tcp_socket_private_crash.cc new file mode 100644 index 0000000..da272f1 --- /dev/null +++ b/ppapi/tests/test_tcp_socket_private_crash.cc
@@ -0,0 +1,45 @@ +// Copyright 2018 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 "ppapi/tests/test_tcp_socket_private_crash.h" + +#include <stddef.h> +#include <stdlib.h> + +#include <new> + +#include "ppapi/cpp/private/tcp_socket_private.h" +#include "ppapi/tests/test_utils.h" +#include "ppapi/tests/testing_instance.h" + +REGISTER_TEST_CASE(TCPSocketPrivateCrash); + +TestTCPSocketPrivateCrash::TestTCPSocketPrivateCrash(TestingInstance* instance) + : TestCase(instance) {} + +bool TestTCPSocketPrivateCrash::Init() { + return pp::TCPSocketPrivate::IsAvailable(); +} + +void TestTCPSocketPrivateCrash::RunTests(const std::string& filter) { + // No need to run this test with the various callback types since that's + // orthogonal from the functionality being tested. It would also make the + // test more complicated because it would have to keep watching the network + // process restart and telling it to crash again on crash.com. + RUN_TEST(Resolve, filter); +} + +std::string TestTCPSocketPrivateCrash::TestResolve() { + pp::TCPSocketPrivate socket(instance_); + + TestCompletionCallback cb(instance_->pp_instance(), callback_type()); + + std::string host("crash.com"); + cb.WaitForResult(socket.Connect(host.c_str(), 80, cb.GetCallback())); + ASSERT_EQ(PP_ERROR_FAILED, cb.result()); + + socket.Disconnect(); + + PASS(); +}
diff --git a/ppapi/tests/test_tcp_socket_private_crash.h b/ppapi/tests/test_tcp_socket_private_crash.h new file mode 100644 index 0000000..fedf7cf --- /dev/null +++ b/ppapi/tests/test_tcp_socket_private_crash.h
@@ -0,0 +1,25 @@ +// Copyright 2018 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 PPAPI_TESTS_TEST_TCP_SOCKET_PRIVATE_CRASH_H_ +#define PPAPI_TESTS_TEST_TCP_SOCKET_PRIVATE_CRASH_H_ + +#include <string> + +#include "ppapi/c/pp_stdint.h" +#include "ppapi/tests/test_case.h" + +class TestTCPSocketPrivateCrash : public TestCase { + public: + explicit TestTCPSocketPrivateCrash(TestingInstance* instance); + + // TestCase implementation. + virtual bool Init(); + virtual void RunTests(const std::string& filter); + + private: + std::string TestResolve(); +}; + +#endif // PPAPI_TESTS_TEST_TCP_SOCKET_PRIVATE_CRASH_H_
diff --git a/remoting/client/audio/BUILD.gn b/remoting/client/audio/BUILD.gn index 2b72fd01..892e2a02 100644 --- a/remoting/client/audio/BUILD.gn +++ b/remoting/client/audio/BUILD.gn
@@ -6,8 +6,6 @@ sources = [ "async_audio_data_supplier.cc", "async_audio_data_supplier.h", - "async_audio_frame_supplier.h", - "audio_frame_supplier.h", "audio_jitter_buffer.cc", "audio_jitter_buffer.h", "audio_playback_sink.h", @@ -17,10 +15,6 @@ "audio_player.h", "audio_player_android.cc", "audio_player_android.h", - "audio_player_buffer.cc", - "audio_player_buffer.h", - "audio_stream_consumer.cc", - "audio_stream_consumer.h", "audio_stream_format.cc", "audio_stream_format.h", ] @@ -55,7 +49,6 @@ sources = [ "audio_jitter_buffer_unittest.cc", - "audio_player_buffer_unittest.cc", "audio_player_unittest.cc", ]
diff --git a/remoting/client/audio/async_audio_frame_supplier.h b/remoting/client/audio/async_audio_frame_supplier.h deleted file mode 100644 index 083d7ef..0000000 --- a/remoting/client/audio/async_audio_frame_supplier.h +++ /dev/null
@@ -1,31 +0,0 @@ -// Copyright 2017 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 REMOTING_CLIENT_AUDIO_ASYNC_AUDIO_FRAME_SUPPLIER_H_ -#define REMOTING_CLIENT_AUDIO_ASYNC_AUDIO_FRAME_SUPPLIER_H_ - -#include <cstdint> - -#include "base/callback.h" -#include "remoting/client/audio/audio_frame_supplier.h" - -namespace remoting { - -// This interface extends the AudioFrameSupplier interface adding async support -// for audio frame requests. This allows the audio frame supplier to wait until -// a full frame is buffered before returning the audio frame to the caller. -// Audio Pipeline Context: -// Stream -> Decode -> Stream Consumer -> Buffer -> [Frame Supplier] -> Play -class AsyncAudioFrameSupplier : public AudioFrameSupplier { - public: - // |buffer| is the destination of the audio frame data, it should be at least - // |buffer_size|. |done| will be called when |buffer| has been filled. - virtual void AsyncGetAudioFrame(uint32_t buffer_size, - void* buffer, - const base::Closure& done) = 0; -}; - -} // namespace remoting - -#endif // REMOTING_CLIENT_AUDIO_ASYNC_AUDIO_FRAME_SUPPLIER_H_
diff --git a/remoting/client/audio/audio_frame_supplier.h b/remoting/client/audio/audio_frame_supplier.h deleted file mode 100644 index 07e3afa..0000000 --- a/remoting/client/audio/audio_frame_supplier.h +++ /dev/null
@@ -1,37 +0,0 @@ -// Copyright 2017 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 REMOTING_CLIENT_AUDIO_AUDIO_FRAME_SUPPLIER_H_ -#define REMOTING_CLIENT_AUDIO_AUDIO_FRAME_SUPPLIER_H_ - -#include <cstdint> - -#include "base/macros.h" -#include "remoting/proto/audio.pb.h" - -namespace remoting { - -// This class provides an interface to request audio frames of a given size -// and a way to ask about the currently buffered audio data. -// Audio Pipeline Context: -// Stream -> Decode -> Stream Consumer -> Buffer -> [Frame Supplier] -> Play -class AudioFrameSupplier { - public: - AudioFrameSupplier() = default; - virtual ~AudioFrameSupplier() = default; - virtual uint32_t GetAudioFrame(uint32_t buffer_size, void* buffer) = 0; - - // Methods to describe buffered data. - virtual AudioPacket::SamplingRate buffered_sampling_rate() const = 0; - virtual AudioPacket::Channels buffered_channels() const = 0; - virtual AudioPacket::BytesPerSample buffered_byes_per_sample() const = 0; - virtual uint32_t bytes_per_frame() const = 0; - - private: - DISALLOW_COPY_AND_ASSIGN(AudioFrameSupplier); -}; - -} // namespace remoting - -#endif // REMOTING_CLIENT_AUDIO_AUDIO_FRAME_SUPPLIER_H_
diff --git a/remoting/client/audio/audio_player_buffer.cc b/remoting/client/audio/audio_player_buffer.cc deleted file mode 100644 index 906d7367..0000000 --- a/remoting/client/audio/audio_player_buffer.cc +++ /dev/null
@@ -1,216 +0,0 @@ -// Copyright 2017 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 "remoting/client/audio/audio_player_buffer.h" - -#include <algorithm> -#include <string> - -#include "base/logging.h" -#include "base/stl_util.h" - -namespace { - -// If queue grows bigger than this we start dropping packets. -const int kMaxQueueLatencyMs = 150; -const int kFrameSizeMs = 10; -const int kMaxQueueLatencyFrames = kMaxQueueLatencyMs / kFrameSizeMs; - -}; // namespace - -namespace remoting { - -struct AudioPlayerBuffer::AudioFrameRequest { - const size_t bytes_needed_; - const void* samples_; - base::Closure callback_; - size_t bytes_extracted_; - - AudioFrameRequest(const size_t bytes_needed, - const void* samples, - const base::Closure& callback); - ~AudioFrameRequest() = default; -}; - -AudioPlayerBuffer::AudioFrameRequest::AudioFrameRequest( - const size_t bytes_needed, - const void* samples, - const base::Closure& callback) - : bytes_needed_(bytes_needed), - samples_(samples), - callback_(callback), - bytes_extracted_(0) {} - -AudioPlayerBuffer::AudioPlayerBuffer() - : queued_bytes_(0), bytes_consumed_(0), weak_factory_(this) { - DETACH_FROM_THREAD(thread_checker_); -} - -AudioPlayerBuffer::~AudioPlayerBuffer() { - DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - ResetQueue(); -} - -void AudioPlayerBuffer::AddAudioPacket(std::unique_ptr<AudioPacket> packet) { - DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - CHECK_EQ(1, packet->data_size()); - DCHECK_EQ(AudioPacket::ENCODING_RAW, packet->encoding()); - DCHECK_NE(AudioPacket::SAMPLING_RATE_INVALID, packet->sampling_rate()); - DCHECK_EQ(buffered_sampling_rate(), packet->sampling_rate()); - DCHECK_EQ(buffered_byes_per_sample(), - static_cast<int>(packet->bytes_per_sample())); - DCHECK_EQ(buffered_channels(), static_cast<int>(packet->channels())); - DCHECK_EQ(packet->data(0).size() % - (buffered_channels() * buffered_byes_per_sample()), - 0u); - - // Push the new data to the back of the queue. - queued_bytes_ += packet->data(0).size(); - queued_packets_.push_back(std::move(packet)); - - // TODO(nicholss): MIGHT WANT TO JUST CALCULATE THIS ONCE. - int max_buffer_size_ = kMaxQueueLatencyFrames * bytes_per_frame(); - - // Trim off the front of the buffer if we have enqueued too many packets. - while (queued_bytes_ > max_buffer_size_) { - queued_bytes_ -= queued_packets_.front()->data(0).size() - bytes_consumed_; - DCHECK_GE(queued_bytes_, 0); - queued_packets_.pop_front(); - bytes_consumed_ = 0; - } - - // Attempt to process a FrameRequest now we have changed queued packets. - ProcessFrameRequestQueue(); -} - -void AudioPlayerBuffer::Stop() { - DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - ResetQueue(); -} - -void AudioPlayerBuffer::AsyncGetAudioFrame(uint32_t buffer_size, - void* buffer, - const base::Closure& callback) { - DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - // Create an AudioFrameRequest and enqueue it into the buffer. - CHECK_EQ(buffer_size % bytes_per_frame(), 0u); - std::unique_ptr<AudioFrameRequest> audioFrameRequest( - new AudioFrameRequest(buffer_size, buffer, callback)); - queued_requests_.push_back(std::move(audioFrameRequest)); - ProcessFrameRequestQueue(); - return; -} - -void AudioPlayerBuffer::ResetQueue() { - DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - queued_packets_.clear(); - queued_bytes_ = 0; - bytes_consumed_ = 0; - queued_requests_.clear(); -} - -uint32_t AudioPlayerBuffer::GetAudioFrame(uint32_t buffer_size, void* buffer) { - DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - const size_t bytes_needed = bytes_per_frame(); - // Make sure we don't overrun the buffer. - CHECK_EQ(buffer_size, bytes_needed); - - char* next_frame = static_cast<char*>(buffer); - size_t bytes_extracted = 0; - - while (bytes_extracted < bytes_needed) { - // Check if we've run out of samples for this packet. - if (queued_packets_.empty()) { - memset(next_frame, 0, bytes_needed - bytes_extracted); - return 0; - } - - // Pop off the packet if we've already consumed all its bytes. - if (queued_packets_.front()->data(0).size() == bytes_consumed_) { - queued_packets_.pop_front(); - bytes_consumed_ = 0; - continue; - } - - const std::string& packet_data = queued_packets_.front()->data(0); - size_t bytes_to_copy = std::min(packet_data.size() - bytes_consumed_, - bytes_needed - bytes_extracted); - memcpy(next_frame, packet_data.data() + bytes_consumed_, bytes_to_copy); - - next_frame += bytes_to_copy; - bytes_consumed_ += bytes_to_copy; - bytes_extracted += bytes_to_copy; - queued_bytes_ -= bytes_to_copy; - DCHECK_GE(queued_bytes_, 0); - } - return bytes_extracted; -} - -// This is called when the Frame Request Queue or the Sample Queue is changed. -void AudioPlayerBuffer::ProcessFrameRequestQueue() { - DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - // Get the active request if there is one. - while (!queued_requests_.empty() && !queued_packets_.empty()) { - AudioFrameRequest* activeRequest = queued_requests_.front().get(); - - // Copy any available data into the active request up to as much requested - while (activeRequest->bytes_extracted_ < activeRequest->bytes_needed_ && - !queued_packets_.empty()) { - char* next_frame = (char*)(activeRequest->samples_); - - const std::string& packet_data = queued_packets_.front()->data(0); - size_t bytes_to_copy = std::min( - packet_data.size() - bytes_consumed_, - activeRequest->bytes_needed_ - activeRequest->bytes_extracted_); - - memcpy(next_frame, packet_data.data() + bytes_consumed_, bytes_to_copy); - - bytes_consumed_ += bytes_to_copy; - activeRequest->bytes_extracted_ += bytes_to_copy; - queued_bytes_ -= bytes_to_copy; - DCHECK_GE(queued_bytes_, 0); - // Pop off the packet if we've already consumed all its bytes. - if (queued_packets_.front()->data(0).size() == bytes_consumed_) { - queued_packets_.pop_front(); - bytes_consumed_ = 0; - } - } - - // If this request is fulfilled, call the callback and pop it off the queue. - if (activeRequest->bytes_extracted_ == activeRequest->bytes_needed_) { - activeRequest->callback_.Run(); - queued_requests_.pop_front(); - activeRequest = nullptr; - } - } -} - -uint32_t AudioPlayerBuffer::samples_per_frame() const { - return (buffered_sampling_rate() * kFrameSizeMs) / - base::Time::kMillisecondsPerSecond; -} - -AudioPacket::SamplingRate AudioPlayerBuffer::buffered_sampling_rate() const { - return AudioPacket::SAMPLING_RATE_48000; -} - -AudioPacket::Channels AudioPlayerBuffer::buffered_channels() const { - return AudioPacket::CHANNELS_STEREO; -} - -AudioPacket::BytesPerSample AudioPlayerBuffer::buffered_byes_per_sample() - const { - return AudioPacket::BYTES_PER_SAMPLE_2; -} - -uint32_t AudioPlayerBuffer::bytes_per_frame() const { - return buffered_channels() * buffered_byes_per_sample() * samples_per_frame(); -} - -base::WeakPtr<AudioStreamConsumer> -AudioPlayerBuffer::AudioStreamConsumerAsWeakPtr() { - return weak_factory_.GetWeakPtr(); -} - -} // namespace remoting
diff --git a/remoting/client/audio/audio_player_buffer.h b/remoting/client/audio/audio_player_buffer.h deleted file mode 100644 index 26a3fb6..0000000 --- a/remoting/client/audio/audio_player_buffer.h +++ /dev/null
@@ -1,82 +0,0 @@ -// Copyright 2017 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 REMOTING_IOS_AUDIO_AUDIO_PLAYER_BUFFER_H_ -#define REMOTING_IOS_AUDIO_AUDIO_PLAYER_BUFFER_H_ - -#include <cstdint> -#include <list> -#include <memory> - -#include "base/macros.h" -#include "base/memory/weak_ptr.h" -#include "base/threading/thread_checker.h" -#include "base/threading/thread_task_runner_handle.h" -#include "remoting/client/audio/async_audio_frame_supplier.h" -#include "remoting/client/audio/audio_stream_consumer.h" -#include "remoting/proto/audio.pb.h" - -namespace remoting { - -// This class consumes the decoded audio stream, buffers it into frames, and -// supplies the player with constant audio frames as they are ready. -// Audio Pipeline Context: -// Stream -> Decode -> [Stream Consumer -> Buffer -> Frame Provider] -> Play -class AudioPlayerBuffer : public AudioStreamConsumer, - public AsyncAudioFrameSupplier { - public: - // The number of channels in the audio stream (only supporting stereo audio - // for now). - static const int kChannels = 2; - static const int kSampleSizeBytes = 2; - - AudioPlayerBuffer(); - ~AudioPlayerBuffer() override; - - void Stop(); - - // Audio Stream Consumer - void AddAudioPacket(std::unique_ptr<AudioPacket> packet) override; - base::WeakPtr<AudioStreamConsumer> AudioStreamConsumerAsWeakPtr() override; - - // Async Audio Frame Supplier - void AsyncGetAudioFrame(uint32_t buffer_size, - void* buffer, - const base::Closure& callback) override; - - // Audio Frame Supplier - uint32_t GetAudioFrame(uint32_t buffer_size, void* buffer) override; - AudioPacket::SamplingRate buffered_sampling_rate() const override; - AudioPacket::Channels buffered_channels() const override; - AudioPacket::BytesPerSample buffered_byes_per_sample() const override; - uint32_t bytes_per_frame() const override; - - // Return the recommended number of samples to include in a frame. - uint32_t samples_per_frame() const; - - private: - friend class AudioPlayerBufferTest; - struct AudioFrameRequest; - - void ResetQueue(); - void ProcessFrameRequestQueue(); - - std::list<std::unique_ptr<AudioPacket>> queued_packets_; - int queued_bytes_; - - // The number of bytes from |queued_packets_| that have been consumed. - size_t bytes_consumed_; - - std::list<std::unique_ptr<AudioFrameRequest>> queued_requests_; - - THREAD_CHECKER(thread_checker_); - - base::WeakPtrFactory<AudioPlayerBuffer> weak_factory_; - - DISALLOW_COPY_AND_ASSIGN(AudioPlayerBuffer); -}; - -} // namespace remoting - -#endif // REMOTING_IOS_AUDIO_AUDIO_PLAYER_BUFFER_H_
diff --git a/remoting/client/audio/audio_player_buffer_unittest.cc b/remoting/client/audio/audio_player_buffer_unittest.cc deleted file mode 100644 index bbef75c..0000000 --- a/remoting/client/audio/audio_player_buffer_unittest.cc +++ /dev/null
@@ -1,229 +0,0 @@ -// Copyright 2017 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 <cstdint> -#include <memory> -#include <string> - -#include "base/bind.h" -#include "base/callback.h" -#include "base/compiler_specific.h" -#include "remoting/client/audio/audio_player_buffer.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace { - -const uint32_t kAudioSampleBytes = 4; // = 2 channels * 2 bytes -const uint32_t kPaddingBytes = 16; - -// TODO(garykac): Generate random audio data in the tests rather than having -// a single constant value. -const uint8_t kDefaultBufferData = 0x5A; -const uint8_t kDummyAudioData = 0x8B; - -void ConsumeAsyncAudioFrameCallback(const void* samples) { - // TODO(nicholss): we could register something in the context and the test - // class to be able to track when and if the test comes back with something. - - // uint8_t* buffer = (uint8_t*)samples; - - // Verify we haven't written beyond the end of the buffer. - // for (int i = 0; i < kPaddingBytes; i++) { - // ASSERT_EQ(kDefaultBufferData, *(buffer + audio_->bytes_per_frame() + i)); - // } -} - -std::unique_ptr<remoting::AudioPacket> CreateAudioPacketWithSamplingRate( - remoting::AudioPacket::SamplingRate rate, - int samples) { - std::unique_ptr<remoting::AudioPacket> packet(new remoting::AudioPacket()); - packet->set_encoding(remoting::AudioPacket::ENCODING_RAW); - packet->set_sampling_rate(rate); - packet->set_bytes_per_sample(remoting::AudioPacket::BYTES_PER_SAMPLE_2); - packet->set_channels(remoting::AudioPacket::CHANNELS_STEREO); - - // The data must be a multiple of 4 bytes (channels x bytes_per_sample). - std::string data; - data.resize(samples * kAudioSampleBytes, kDummyAudioData); - packet->add_data(data); - - return packet; -} - -std::unique_ptr<remoting::AudioPacket> CreatePacket48kHz(int samples) { - return CreateAudioPacketWithSamplingRate( - remoting::AudioPacket::SAMPLING_RATE_48000, samples); -} - -} // namespace - -namespace remoting { - -class AudioPlayerBufferTest : public ::testing::Test { - public: - void AddAudioPacket(std::unique_ptr<AudioPacket> packet) { - audio_->AddAudioPacket(std::move(packet)); - } - - protected: - void SetUp() override { - audio_.reset(new AudioPlayerBuffer()); - buffer_.reset(new char[audio_->bytes_per_frame() + kPaddingBytes]); - } - - void TearDown() override {} - - void ConsumeAudioFrame() { - uint8_t* buffer = reinterpret_cast<uint8_t*>(buffer_.get()); - memset(buffer, kDefaultBufferData, - audio_->bytes_per_frame() + kPaddingBytes); - - audio_->GetAudioFrame(audio_->bytes_per_frame(), - reinterpret_cast<void*>(buffer)); - - // Verify we haven't written beyond the end of the buffer. - for (uint32_t i = 0; i < kPaddingBytes; i++) { - ASSERT_EQ(kDefaultBufferData, *(buffer + audio_->bytes_per_frame() + i)); - } - } - - void ConsumeAsyncAudioFrame() { - uint8_t* buffer = reinterpret_cast<uint8_t*>(buffer_.get()); - memset(buffer, kDefaultBufferData, - audio_->bytes_per_frame() + kPaddingBytes); - - audio_->AsyncGetAudioFrame(audio_->bytes_per_frame(), - reinterpret_cast<void*>(buffer), - base::Bind(&ConsumeAsyncAudioFrameCallback, - reinterpret_cast<void*>(buffer))); - } - - // Check that the first |num_bytes| bytes are filled with audio data and - // the rest of the buffer is zero-filled. - void CheckAudioFrameBytes(uint32_t num_bytes) { - uint8_t* buffer = reinterpret_cast<uint8_t*>(buffer_.get()); - uint32_t i = 0; - for (; i < num_bytes; i++) { - ASSERT_EQ(kDummyAudioData, *(buffer + i)); - } - // Rest of audio frame must be filled with '0's. - for (; i < audio_->bytes_per_frame(); i++) { - ASSERT_EQ(0, *(buffer + i)); - } - } - - uint32_t GetNumQueuedSamples() { - return audio_->queued_bytes_ / kAudioSampleBytes; - } - - uint32_t GetNumQueuedPackets() { - return static_cast<int>(audio_->queued_packets_.size()); - } - - uint32_t GetBytesConsumed() { - return static_cast<int>(audio_->bytes_consumed_); - } - - uint32_t GetNumQueuedRequests() { - return static_cast<int>(audio_->queued_requests_.size()); - } - - std::unique_ptr<AudioPlayerBuffer> audio_; - std::unique_ptr<char[]> buffer_; -}; - -TEST_F(AudioPlayerBufferTest, Init) { - ASSERT_EQ((uint32_t)0, GetNumQueuedPackets()); - - audio_->AddAudioPacket(CreatePacket48kHz(10)); - ASSERT_EQ((uint32_t)1, GetNumQueuedPackets()); -} - -TEST_F(AudioPlayerBufferTest, MultipleSamples) { - audio_->AddAudioPacket(CreatePacket48kHz(10)); - ASSERT_EQ((uint32_t)10, GetNumQueuedSamples()); - ASSERT_EQ((uint32_t)1, GetNumQueuedPackets()); - - audio_->AddAudioPacket(CreatePacket48kHz(20)); - ASSERT_EQ((uint32_t)30, GetNumQueuedSamples()); - ASSERT_EQ((uint32_t)2, GetNumQueuedPackets()); -} - -TEST_F(AudioPlayerBufferTest, ExceedLatency) { - // Push about 4 seconds worth of samples. - for (uint32_t i = 0; i < 100; ++i) { - audio_->AddAudioPacket(CreatePacket48kHz(2000)); - } - - // Verify that we don't have more than 0.5s. - EXPECT_LT(GetNumQueuedSamples(), (uint32_t)24000); -} - -// Incoming packets: 2 frames worth -// Consume: 1 frame -TEST_F(AudioPlayerBufferTest, ConsumePartialPacket) { - uint32_t total_samples = 0; - uint32_t bytes_consumed = 0; - - // Process 2x samples. - total_samples += audio_->samples_per_frame() * 2; - audio_->AddAudioPacket(CreatePacket48kHz(audio_->samples_per_frame() * 2)); - - ASSERT_EQ(total_samples, GetNumQueuedSamples()); - ASSERT_EQ((uint32_t)1, GetNumQueuedPackets()); - ASSERT_EQ(bytes_consumed, GetBytesConsumed()); - - // Consume one frame of samples. - ConsumeAudioFrame(); - total_samples -= audio_->samples_per_frame(); - bytes_consumed += audio_->bytes_per_frame(); - ASSERT_EQ(total_samples, GetNumQueuedSamples()); - ASSERT_EQ((uint32_t)1, GetNumQueuedPackets()); - ASSERT_EQ(bytes_consumed, GetBytesConsumed()); - CheckAudioFrameBytes(audio_->bytes_per_frame()); - - // Remaining samples. - ASSERT_EQ(audio_->samples_per_frame(), total_samples); - ASSERT_EQ(audio_->samples_per_frame() * kAudioSampleBytes, bytes_consumed); - - // Consume remaining packet. - ConsumeAudioFrame(); - total_samples -= audio_->samples_per_frame(); - bytes_consumed += audio_->bytes_per_frame(); - ASSERT_EQ((uint32_t)0, GetNumQueuedSamples()); -} - -TEST_F(AudioPlayerBufferTest, SingleAsyncRequest) { - // Create a pending Audio Request. - ConsumeAsyncAudioFrame(); - ASSERT_EQ((uint32_t)1, GetNumQueuedRequests()); -} - -TEST_F(AudioPlayerBufferTest, TwoAsyncRequest) { - // Create a pending Audio Request. - ConsumeAsyncAudioFrame(); - ConsumeAsyncAudioFrame(); - ASSERT_EQ((uint32_t)2, GetNumQueuedRequests()); - - // Add just enough samples to fulfill one request. - audio_->AddAudioPacket(CreatePacket48kHz(audio_->samples_per_frame())); - - ASSERT_EQ((uint32_t)1, GetNumQueuedRequests()); -} - -TEST_F(AudioPlayerBufferTest, TwoPartFrameAsyncRequest) { - // Create a pending Audio Request. - audio_->AddAudioPacket(CreatePacket48kHz(audio_->samples_per_frame() / 2)); - - ConsumeAsyncAudioFrame(); - ASSERT_EQ((uint32_t)1, GetNumQueuedRequests()); - - // Add just enough samples to fulfill one request. - audio_->AddAudioPacket(CreatePacket48kHz(audio_->samples_per_frame() / 2)); - - ASSERT_EQ((uint32_t)0, GetNumQueuedSamples()); - ASSERT_EQ((uint32_t)0, GetNumQueuedRequests()); -} - -} // namespace remoting
diff --git a/remoting/client/audio/audio_stream_consumer.cc b/remoting/client/audio/audio_stream_consumer.cc deleted file mode 100644 index e8fb5484..0000000 --- a/remoting/client/audio/audio_stream_consumer.cc +++ /dev/null
@@ -1,18 +0,0 @@ -// Copyright 2017 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 "remoting/client/audio/audio_stream_consumer.h" - -namespace remoting { - -void AudioStreamConsumer::ProcessAudioPacket( - std::unique_ptr<AudioPacket> packet, - const base::Closure& done) { - AddAudioPacket(std::move(packet)); - if (done) { - done.Run(); - } -} - -} // namespace remoting
diff --git a/remoting/client/audio/audio_stream_consumer.h b/remoting/client/audio/audio_stream_consumer.h deleted file mode 100644 index 3f9da4b..0000000 --- a/remoting/client/audio/audio_stream_consumer.h +++ /dev/null
@@ -1,46 +0,0 @@ -// Copyright 2017 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 REMOTING_CLIENT_AUDIO_AUDIO_STREAM_CONSUMER_H_ -#define REMOTING_CLIENT_AUDIO_AUDIO_STREAM_CONSUMER_H_ - -#include "base/callback.h" -#include "base/macros.h" -#include "base/memory/weak_ptr.h" -#include "remoting/proto/audio.pb.h" -#include "remoting/protocol/audio_stub.h" - -namespace remoting { - -// This is the interface that consumes the audio stream from the decoder. -// The decoder is not guaranteed to produce a constant flow of audio, this -// interface sits between the audio decoder and the |AudioFrameSupplier|. -// Audio Pipeline Context: -// Stream -> Decode -> [Stream Consumer] -> Buffer -> Frame Supplier -> Play -class AudioStreamConsumer : public protocol::AudioStub { - public: - AudioStreamConsumer() = default; - ~AudioStreamConsumer() override {} - - // Adds a audio packet from the audio stream to the audio consumer. - // What happens to the packet is up to implmentation but typically it is - // expected that it will be buffered and then given to the player when - // requested. - virtual void AddAudioPacket(std::unique_ptr<AudioPacket> packet) = 0; - // Get a weak refrence to the audio consumer. - virtual base::WeakPtr<AudioStreamConsumer> AudioStreamConsumerAsWeakPtr() = 0; - - // AudioStub implementation. Delegates to AddAudioPacket. Used for - // integration with |protocol::AudioStub| API users but AddAudioPacket - // is preferred. - void ProcessAudioPacket(std::unique_ptr<AudioPacket> packet, - const base::Closure& done) override; - - private: - DISALLOW_COPY_AND_ASSIGN(AudioStreamConsumer); -}; - -} // namespace remoting - -#endif // REMOTING_CLIENT_AUDIO_AUDIO_STREAM_CONSUMER_H_
diff --git a/remoting/ios/audio/BUILD.gn b/remoting/ios/audio/BUILD.gn index 4bd0dd9..fb57d01 100644 --- a/remoting/ios/audio/BUILD.gn +++ b/remoting/ios/audio/BUILD.gn
@@ -10,11 +10,6 @@ sources = [ "audio_playback_sink_ios.cc", "audio_playback_sink_ios.h", - "audio_player_ios.h", - "audio_player_ios.mm", - "audio_player_ios_wrapper.h", - "audio_stream_consumer_proxy.cc", - "audio_stream_consumer_proxy.h", ] deps = [
diff --git a/remoting/ios/audio/audio_player_ios.h b/remoting/ios/audio/audio_player_ios.h deleted file mode 100644 index 6ba70117e..0000000 --- a/remoting/ios/audio/audio_player_ios.h +++ /dev/null
@@ -1,102 +0,0 @@ -// Copyright 2017 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 REMOTING_IOS_AUDIO_AUDIO_PLAYER_IOS_H_ -#define REMOTING_IOS_AUDIO_AUDIO_PLAYER_IOS_H_ - -#import <AudioToolbox/AudioToolbox.h> - -#include <memory> -#include <string> - -#include "base/bind.h" -#include "base/macros.h" -#include "base/memory/ref_counted.h" -#include "base/memory/weak_ptr.h" -#include "base/single_thread_task_runner.h" -#include "remoting/base/auto_thread.h" -#include "remoting/client/audio/async_audio_frame_supplier.h" -#include "remoting/client/audio/audio_stream_consumer.h" - -namespace remoting { - -/* - For iOS, the audio subsystem uses a multi-buffer queue to produce smooth - audio playback. To allow this to work with remoting, we need to add a buffer - that is capable of enqueuing exactly the requested amount of data - asynchronously then calling us back and we will push it into the iOS audio - queue. -*/ -class AudioPlayerIos { - public: - static std::unique_ptr<AudioPlayerIos> CreateAudioPlayer( - scoped_refptr<AutoThreadTaskRunner> audio_thread_runner); - - AudioPlayerIos(std::unique_ptr<AudioStreamConsumer> audio_stream_consumer, - std::unique_ptr<AsyncAudioFrameSupplier> audio_frame_supplier, - scoped_refptr<base::SingleThreadTaskRunner> audio_task_runner); - - // Call on the audio thread. - ~AudioPlayerIos(); - - // Must be called once on the UI thread before destroying the object on - // audio thread. - // TODO(yuweih): This is a dirty fix for thread safety issue. The cleaner fix - // could be turn AudioPlayerIos into shell-core model then invalidate UI - // resources in the shell. - void Invalidate(); - - base::WeakPtr<AudioStreamConsumer> GetAudioStreamConsumer(); - void Start(); - void Stop(); - - private: - static const uint32_t kOutputBuffers = 8; - - enum AudioPlayerState { - UNALLOCATED, - STOPPING, - STOPPED, - PRIMING, - PLAYING, - UNDERRUN, - UNKNOWN - }; - - static void AudioEngineOutputBufferCallback(void* instance, - AudioQueueRef outAQ, - AudioQueueBufferRef samples); - - // Audio Thread versions of public functions. - void StartOnAudioThread(); - void StopOnAudioThread(); - - // Audio Thread private functions. - void Prime(AudioQueueBufferRef output_buffer, bool was_dequeued); - void Pump(AudioQueueBufferRef output_buffer); - void PrimeQueue(); - void StartPlayback(); - void AsyncGetAudioFrameCallback(const void* context, const void* samples); - bool GenerateOutputBuffers(uint32_t bytesPerFrame); - bool GenerateOutputQueue(void* context); - AudioStreamBasicDescription GenerateStreamFormat(); - - AudioPlayerState state_; - uint32_t priming_frames_needed_count_; - AudioQueueRef output_queue_; - AudioQueueBufferRef output_buffers_[kOutputBuffers]; - std::unique_ptr<AudioStreamConsumer> audio_stream_consumer_; - std::unique_ptr<AsyncAudioFrameSupplier> audio_frame_supplier_; - uint32_t enqueued_frames_count_; - // Task runner on which the |audio_frame_supplier_| is running. - scoped_refptr<base::SingleThreadTaskRunner> audio_task_runner_; - - base::WeakPtrFactory<AudioPlayerIos> weak_factory_; - - DISALLOW_COPY_AND_ASSIGN(AudioPlayerIos); -}; - -} // namespace remoting - -#endif // REMOTING_IOS_AUDIO_AUDIO_PLAYER_IOS_H_
diff --git a/remoting/ios/audio/audio_player_ios.mm b/remoting/ios/audio/audio_player_ios.mm deleted file mode 100644 index bc77ecc..0000000 --- a/remoting/ios/audio/audio_player_ios.mm +++ /dev/null
@@ -1,258 +0,0 @@ -// Copyright 2017 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. - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - -#import <AudioToolbox/AudioToolbox.h> -#import <Foundation/Foundation.h> - -#include "base/logging.h" -#include "base/memory/ptr_util.h" -#include "remoting/base/auto_thread.h" -#include "remoting/client/audio/audio_player_buffer.h" -#include "remoting/ios/audio/audio_player_ios.h" -#include "remoting/ios/audio/audio_stream_consumer_proxy.h" - -namespace remoting { - -std::unique_ptr<AudioPlayerIos> AudioPlayerIos::CreateAudioPlayer( - scoped_refptr<AutoThreadTaskRunner> audio_thread_runner) { - AudioPlayerBuffer* buffer = new AudioPlayerBuffer(); - - std::unique_ptr<AsyncAudioFrameSupplier> supplier = - (std::unique_ptr<AsyncAudioFrameSupplier>)base::WrapUnique(buffer); - - std::unique_ptr<AudioStreamConsumer> consumer_proxy = - AudioStreamConsumerProxy::Create(audio_thread_runner, - buffer->AudioStreamConsumerAsWeakPtr()); - - return std::make_unique<AudioPlayerIos>( - std::move(consumer_proxy), std::move(supplier), audio_thread_runner); -} - -// public - -AudioPlayerIos::AudioPlayerIos( - std::unique_ptr<AudioStreamConsumer> audio_stream_consumer, - std::unique_ptr<AsyncAudioFrameSupplier> audio_frame_supplier, - scoped_refptr<base::SingleThreadTaskRunner> audio_task_runner) - : state_(UNALLOCATED), - enqueued_frames_count_(0), - audio_task_runner_(audio_task_runner), - weak_factory_(this) { - audio_stream_consumer_ = std::move(audio_stream_consumer); - audio_frame_supplier_ = std::move(audio_frame_supplier); -} - -AudioPlayerIos::~AudioPlayerIos() { - DCHECK(audio_task_runner_->BelongsToCurrentThread()); - DCHECK(!audio_stream_consumer_) - << "Invalidate() must be called once on the UI thread."; - StopOnAudioThread(); - // Disposing of an audio queue also disposes of its resources, including its - // buffers. - AudioQueueDispose(output_queue_, true /* Immediate */); - for (uint32_t i = 0; i < kOutputBuffers; i++) { - output_buffers_[i] = nullptr; - } -} - -void AudioPlayerIos::Invalidate() { - audio_stream_consumer_.release(); -} - -base::WeakPtr<AudioStreamConsumer> AudioPlayerIos::GetAudioStreamConsumer() { - return audio_stream_consumer_->AudioStreamConsumerAsWeakPtr(); -} - -void AudioPlayerIos::Start() { - audio_task_runner_->PostTask(FROM_HERE, - base::Bind(&AudioPlayerIos::StartOnAudioThread, - weak_factory_.GetWeakPtr())); -} - -void AudioPlayerIos::Stop() { - audio_task_runner_->PostTask(FROM_HERE, - base::Bind(&AudioPlayerIos::StopOnAudioThread, - weak_factory_.GetWeakPtr())); -} - -void AudioPlayerIos::Prime(AudioQueueBufferRef output_buffer, - bool was_dequeued) { - DCHECK(audio_task_runner_->BelongsToCurrentThread()); - if (state_ == STOPPING) { - return; - } - if (was_dequeued) { - --enqueued_frames_count_; - } - - audio_frame_supplier_->AsyncGetAudioFrame( - audio_frame_supplier_->bytes_per_frame(), - reinterpret_cast<void*>(output_buffer->mAudioData), - base::Bind(&AudioPlayerIos::AsyncGetAudioFrameCallback, - weak_factory_.GetWeakPtr(), - reinterpret_cast<void*>(output_buffer), - reinterpret_cast<void*>(output_buffer->mAudioData))); - - if (state_ == PLAYING && enqueued_frames_count_ == 0) { - state_ = UNDERRUN; - StopOnAudioThread(); - // We have a bunch of pending requests so we are not stopped, but really in - // PRIMING. Avoid re-priming the queue. - state_ = PRIMING; - priming_frames_needed_count_ = kOutputBuffers; - } -} - -void AudioPlayerIos::Pump(AudioQueueBufferRef output_buffer) { - DCHECK(audio_task_runner_->BelongsToCurrentThread()); - OSStatus err = AudioQueueEnqueueBuffer(output_queue_, output_buffer, 0, nil); - if (err) { - LOG(FATAL) << "AudioQueueEnqueueBuffer: " << err; - } else { - ++enqueued_frames_count_; - } - - if (state_ == PRIMING) { - --priming_frames_needed_count_; - if (priming_frames_needed_count_ == 0) { - audio_task_runner_->PostTask(FROM_HERE, - base::Bind(&AudioPlayerIos::StartPlayback, - weak_factory_.GetWeakPtr())); - } - } -} - -// private - -// static, AudioQueue output queue callback. -void AudioPlayerIos::AudioEngineOutputBufferCallback( - void* instance, - AudioQueueRef outAQ, - AudioQueueBufferRef samples) { - AudioPlayerIos* player = (AudioPlayerIos*)instance; - player->Prime(samples, true); -} - -void AudioPlayerIos::StartOnAudioThread() { - DCHECK(audio_task_runner_->BelongsToCurrentThread()); - switch (state_) { - case STOPPING: - // Nothing to do. - return; - case UNALLOCATED: - GenerateOutputQueue((void*)this); - GenerateOutputBuffers(audio_frame_supplier_->bytes_per_frame()); - state_ = STOPPED; - FALLTHROUGH; - case STOPPED: - PrimeQueue(); - return; - case PRIMING: - // Nothing to do. - return; - case PLAYING: - // Nothing to do. - return; - case UNDERRUN: - // Nothing to do. - return; - default: - LOG(FATAL) << "Audio Player: Unknown State."; - } -} - -void AudioPlayerIos::StopOnAudioThread() { - DCHECK(audio_task_runner_->BelongsToCurrentThread()); - state_ = STOPPING; - if (output_queue_) { - AudioQueueStop(output_queue_, YES); - } - state_ = STOPPED; -} - -// Should only be called while |state_| is STOPPED -void AudioPlayerIos::PrimeQueue() { - DCHECK(audio_task_runner_->BelongsToCurrentThread()); - if (state_ != STOPPED) { - return; - } - state_ = PRIMING; - priming_frames_needed_count_ = kOutputBuffers; - for (uint32_t i = 0; i < kOutputBuffers; i++) { - Prime(output_buffers_[i], false); - } -} - -void AudioPlayerIos::StartPlayback() { - DCHECK(audio_task_runner_->BelongsToCurrentThread()); - OSStatus err; - err = AudioQueueStart(output_queue_, nil); - if (err) { - LOG(FATAL) << "AudioQueueStart: " << err; - state_ = UNKNOWN; - return; - } - state_ = PLAYING; - return; -} - -void AudioPlayerIos::AsyncGetAudioFrameCallback(const void* context, - const void* samples) { - DCHECK(audio_task_runner_->BelongsToCurrentThread()); - AudioQueueBufferRef output_buffer = (AudioQueueBufferRef)context; - output_buffer->mAudioDataByteSize = audio_frame_supplier_->bytes_per_frame(); - Pump(output_buffer); -} - -bool AudioPlayerIos::GenerateOutputBuffers(uint32_t bytesPerFrame) { - DCHECK(audio_task_runner_->BelongsToCurrentThread()); - OSStatus err; - for (uint32_t i = 0; i < kOutputBuffers; i++) { - err = AudioQueueAllocateBuffer(output_queue_, bytesPerFrame, - &output_buffers_[i]); - if (err) { - LOG(FATAL) << "AudioQueueAllocateBuffer[" << i << "] : " << err; - return false; - } - } - return true; -} - -bool AudioPlayerIos::GenerateOutputQueue(void* context) { - DCHECK(audio_task_runner_->BelongsToCurrentThread()); - // Set up stream format fields - AudioStreamBasicDescription streamFormat = GenerateStreamFormat(); - OSStatus err; - err = AudioQueueNewOutput(&streamFormat, AudioEngineOutputBufferCallback, - context, CFRunLoopGetCurrent(), - kCFRunLoopCommonModes, 0, &output_queue_); - if (err) { - LOG(FATAL) << "AudioQueueNewOutput: " << err; - return false; - } - return true; -} - -AudioStreamBasicDescription AudioPlayerIos::GenerateStreamFormat() { - // Set up stream format fields - // TODO(nicholss): does this all needs to be generated dynamicly? - AudioStreamBasicDescription streamFormat; - streamFormat.mSampleRate = 48000; - streamFormat.mFormatID = kAudioFormatLinearPCM; - streamFormat.mFormatFlags = - kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked; - streamFormat.mBitsPerChannel = 16; - streamFormat.mChannelsPerFrame = 2; - streamFormat.mBytesPerPacket = 2 * streamFormat.mChannelsPerFrame; - streamFormat.mBytesPerFrame = 2 * streamFormat.mChannelsPerFrame; - streamFormat.mFramesPerPacket = 1; - streamFormat.mReserved = 0; - return streamFormat; -} - -} // namespace remoting
diff --git a/remoting/ios/audio/audio_stream_consumer_proxy.cc b/remoting/ios/audio/audio_stream_consumer_proxy.cc deleted file mode 100644 index dc806662..0000000 --- a/remoting/ios/audio/audio_stream_consumer_proxy.cc +++ /dev/null
@@ -1,88 +0,0 @@ -// Copyright 2017 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 "remoting/ios/audio/audio_stream_consumer_proxy.h" - -#include <utility> - -#include "base/bind.h" -#include "base/callback_helpers.h" -#include "base/location.h" -#include "base/logging.h" -#include "base/macros.h" -#include "base/single_thread_task_runner.h" - -namespace remoting { - -// Runs an instance of |HostWindow| on the |audio_task_runner_| thread. -class AudioStreamConsumerProxy::Core { - public: - Core(base::WeakPtr<AudioStreamConsumer> audio_stream_consumer); - ~Core(); - - void AddAudioPacket(std::unique_ptr<AudioPacket> packet); - base::WeakPtr<AudioStreamConsumer> AudioStreamConsumerAsWeakPtr(); - base::WeakPtr<Core> GetWeakPtr(); - - private: - // The wrapped |AudioStreamConsumer| instance running on the - // |audio_task_runner_| thread. - base::WeakPtr<AudioStreamConsumer> audio_stream_consumer_; - - base::WeakPtrFactory<Core> weak_factory_; - - DISALLOW_COPY_AND_ASSIGN(Core); -}; - -std::unique_ptr<AudioStreamConsumerProxy> AudioStreamConsumerProxy::Create( - scoped_refptr<base::SingleThreadTaskRunner> audio_task_runner, - base::WeakPtr<AudioStreamConsumer> audio_stream_consumer) { - std::unique_ptr<Core> core(new Core(std::move(audio_stream_consumer))); - std::unique_ptr<AudioStreamConsumerProxy> result( - new AudioStreamConsumerProxy(audio_task_runner, std::move(core))); - return result; -} - -AudioStreamConsumerProxy::AudioStreamConsumerProxy( - scoped_refptr<base::SingleThreadTaskRunner> audio_task_runner, - std::unique_ptr<Core> core) - : audio_task_runner_(audio_task_runner), - core_(std::move(core)), - weak_factory_(this) {} - -AudioStreamConsumerProxy::~AudioStreamConsumerProxy() { - audio_task_runner_->DeleteSoon(FROM_HERE, core_.release()); -} - -void AudioStreamConsumerProxy::AddAudioPacket( - std::unique_ptr<AudioPacket> packet) { - audio_task_runner_->PostTask( - FROM_HERE, base::Bind(&Core::AddAudioPacket, core_->GetWeakPtr(), - base::Passed(&packet))); -} - -base::WeakPtr<AudioStreamConsumer> -AudioStreamConsumerProxy::AudioStreamConsumerAsWeakPtr() { - return weak_factory_.GetWeakPtr(); -} - -AudioStreamConsumerProxy::Core::Core( - base::WeakPtr<AudioStreamConsumer> audio_stream_consumer) - : audio_stream_consumer_(audio_stream_consumer), weak_factory_(this) {} - -AudioStreamConsumerProxy::Core::~Core() {} - -void AudioStreamConsumerProxy::Core::AddAudioPacket( - std::unique_ptr<AudioPacket> packet) { - if (audio_stream_consumer_) { - audio_stream_consumer_->AddAudioPacket(std::move(packet)); - } -} - -base::WeakPtr<AudioStreamConsumerProxy::Core> -AudioStreamConsumerProxy::Core::GetWeakPtr() { - return weak_factory_.GetWeakPtr(); -} - -} // namespace remoting
diff --git a/remoting/ios/audio/audio_stream_consumer_proxy.h b/remoting/ios/audio/audio_stream_consumer_proxy.h deleted file mode 100644 index ba8cd2c..0000000 --- a/remoting/ios/audio/audio_stream_consumer_proxy.h +++ /dev/null
@@ -1,57 +0,0 @@ -// Copyright 2017 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 REMOTING_IOS_AUDIO_AUDIO_STREAM_CONSUMER_PROXY_H_ -#define REMOTING_IOS_AUDIO_AUDIO_STREAM_CONSUMER_PROXY_H_ - -#include <cstdint> -#include <list> -#include <memory> - -#include "base/macros.h" -#include "base/memory/weak_ptr.h" -#include "base/threading/thread_checker.h" -#include "remoting/client/audio/audio_stream_consumer.h" -#include "remoting/proto/audio.pb.h" - -namespace base { -class SingleThreadTaskRunner; -} - -namespace remoting { - -class AudioStreamConsumer; - -// Takes an instance of |AudioConsumer| and runs it on the |audio_task_runner| -// thread. -class AudioStreamConsumerProxy : public AudioStreamConsumer { - public: - static std::unique_ptr<AudioStreamConsumerProxy> Create( - scoped_refptr<base::SingleThreadTaskRunner> audio_task_runner, - base::WeakPtr<AudioStreamConsumer> audio_stream_consumer); - - ~AudioStreamConsumerProxy() override; - - // AudioStreamConsumer overrides. - void AddAudioPacket(std::unique_ptr<AudioPacket> packet) override; - base::WeakPtr<AudioStreamConsumer> AudioStreamConsumerAsWeakPtr() override; - - private: - class Core; - AudioStreamConsumerProxy( - scoped_refptr<base::SingleThreadTaskRunner> audio_task_runner, - std::unique_ptr<Core> core); - - // Task runner on which |core_| is called. - scoped_refptr<base::SingleThreadTaskRunner> audio_task_runner_; - - // All thread switching logic is implemented in the |Core| class. - std::unique_ptr<Core> core_; - - base::WeakPtrFactory<AudioStreamConsumerProxy> weak_factory_; -}; - -} // namespace remoting - -#endif // REMOTING_IOS_AUDIO_AUDIO_STREAM_CONSUMER_PROXY_H_
diff --git a/remoting/protocol/ssl_hmac_channel_authenticator.cc b/remoting/protocol/ssl_hmac_channel_authenticator.cc index e78926e5..bf905eb8 100644 --- a/remoting/protocol/ssl_hmac_channel_authenticator.cc +++ b/remoting/protocol/ssl_hmac_channel_authenticator.cc
@@ -93,6 +93,7 @@ verify_result->cert_status = net::CERT_STATUS_INVALID; return net::ERR_CERT_INVALID; } + void SetConfig(const Config& config) override {} }; // Implements net::StreamSocket interface on top of P2PStreamSocket to be passed @@ -287,11 +288,6 @@ ct_policy_enforcer_.reset(new net::DefaultCTPolicyEnforcer); net::SSLConfig ssl_config; - // Certificate verification and revocation checking are not needed - // because we use self-signed certs. Disable it so that the SSL - // layer doesn't try to initialize OCSP (OCSP works only on the IO - // thread). - ssl_config.rev_checking_enabled = false; ssl_config.require_ecdhe = true; scoped_refptr<net::X509Certificate> cert =
diff --git a/sandbox/linux/syscall_broker/broker_process.cc b/sandbox/linux/syscall_broker/broker_process.cc index c510b8a..5caced5 100644 --- a/sandbox/linux/syscall_broker/broker_process.cc +++ b/sandbox/linux/syscall_broker/broker_process.cc
@@ -103,6 +103,99 @@ return false; } +bool BrokerProcess::IsSyscallAllowed(int sysno) const { + switch (sysno) { + // In the event that there are no case statements defined, provide a + // "backstop" that returns false, so that one of the below return + // statements does not execute instead. + case 0: + return false; + +#if defined(__NR_access) + case __NR_access: +#endif +#if defined(__NR_faccessat) + case __NR_faccessat: +#endif + return !fast_check_in_client_ || + allowed_command_set_.test(COMMAND_ACCESS); + +#if defined(__NR_mkdir) + case __NR_mkdir: +#endif +#if defined(__NR_mkdirat) + case __NR_mkdirat: +#endif + return !fast_check_in_client_ || allowed_command_set_.test(COMMAND_MKDIR); + +#if defined(__NR_open) + case __NR_open: +#endif +#if defined(__NR_openat) + case __NR_openat: +#endif + return !fast_check_in_client_ || allowed_command_set_.test(COMMAND_OPEN); + +#if defined(__NR_readlink) + case __NR_readlink: +#endif +#if defined(__NR_readlinkat) + case __NR_readlinkat: +#endif + return !fast_check_in_client_ || + allowed_command_set_.test(COMMAND_READLINK); + +#if defined(__NR_rename) + case __NR_rename: +#endif +#if defined(__NR_renameat) + case __NR_renameat: +#endif + return !fast_check_in_client_ || + allowed_command_set_.test(COMMAND_RENAME); + +#if defined(__NR_rmdir) + case __NR_rmdir: +#endif + return !fast_check_in_client_ || allowed_command_set_.test(COMMAND_RMDIR); + +#if defined(__NR_stat) + case __NR_stat: +#endif +#if defined(__NR_lstat) + case __NR_lstat: +#endif +#if defined(__NR_fstatat) + case __NR_fstatat: +#endif +#if defined(__NR_newfstatat) + case __NR_newfstatat: +#endif + return !fast_check_in_client_ || allowed_command_set_.test(COMMAND_STAT); + +#if defined(__NR_stat64) + case __NR_stat64: +#endif +#if defined(__NR_lstat64) + case __NR_lstat64: +#endif + return !fast_check_in_client_ || + allowed_command_set_.test(COMMAND_STAT64); + +#if defined(__NR_unlink) + case __NR_unlink: +#endif +#if defined(__NR_unlinkat) + case __NR_unlinkat: +#endif + return !fast_check_in_client_ || + allowed_command_set_.test(COMMAND_UNLINK); + + default: + return false; + } +} + void BrokerProcess::CloseChannel() { broker_client_.reset(); }
diff --git a/sandbox/linux/syscall_broker/broker_process.h b/sandbox/linux/syscall_broker/broker_process.h index 1359930..e994a01 100644 --- a/sandbox/linux/syscall_broker/broker_process.h +++ b/sandbox/linux/syscall_broker/broker_process.h
@@ -74,6 +74,14 @@ // Return the PID of the child created by Init(). int broker_pid() const { return broker_pid_; } + // Can be used in bpf_dsl::Policy::EvaluateSyscall() implementations to + // determine if the system call |sysno| should be trapped and forwarded + // to the broker process for handling. This examines the + // |allowed_command_set_| iff |fast_check_in_client_| is true. If + // the fast checks are disabled, then all possible brokerable system + // calls are forwarded to the broker process for handling. + bool IsSyscallAllowed(int sysno) const; + // The following methods are used in place of the equivalently-named // syscalls by the trap handler. They, in turn, forward the call onto // |broker_client_| for further processing. They will all be async signal
diff --git a/sandbox/linux/syscall_broker/broker_process_unittest.cc b/sandbox/linux/syscall_broker/broker_process_unittest.cc index 8df69d0..7d04b8b 100644 --- a/sandbox/linux/syscall_broker/broker_process_unittest.cc +++ b/sandbox/linux/syscall_broker/broker_process_unittest.cc
@@ -27,6 +27,8 @@ #include "base/macros.h" #include "base/posix/eintr_wrapper.h" #include "base/posix/unix_domain_socket.h" +#include "base/stl_util.h" +#include "base/strings/stringprintf.h" #include "build/build_config.h" #include "sandbox/linux/syscall_broker/broker_client.h" #include "sandbox/linux/tests/scoped_temporary_file.h" @@ -1452,5 +1454,99 @@ TestUnlinkHelper(false); } +TEST(BrokerProcess, IsSyscallAllowed) { + const struct { + int sysno; + BrokerCommand command; + } kSyscallToCommandMap[] = { +#if defined(__NR_access) + {__NR_access, COMMAND_ACCESS}, +#endif +#if defined(__NR_faccessat) + {__NR_faccessat, COMMAND_ACCESS}, +#endif +#if defined(__NR_mkdir) + {__NR_mkdir, COMMAND_MKDIR}, +#endif +#if defined(__NR_mkdirat) + {__NR_mkdirat, COMMAND_MKDIR}, +#endif +#if defined(__NR_open) + {__NR_open, COMMAND_OPEN}, +#endif +#if defined(__NR_openat) + {__NR_openat, COMMAND_OPEN}, +#endif +#if defined(__NR_readlink) + {__NR_readlink, COMMAND_READLINK}, +#endif +#if defined(__NR_readlinkat) + {__NR_readlinkat, COMMAND_READLINK}, +#endif +#if defined(__NR_rename) + {__NR_rename, COMMAND_RENAME}, +#endif +#if defined(__NR_renameat) + {__NR_renameat, COMMAND_RENAME}, +#endif +#if defined(__NR_rmdir) + {__NR_rmdir, COMMAND_RMDIR}, +#endif +#if defined(__NR_stat) + {__NR_stat, COMMAND_STAT}, +#endif +#if defined(__NR_lstat) + {__NR_lstat, COMMAND_STAT}, +#endif +#if defined(__NR_fstatat) + {__NR_fstatat, COMMAND_STAT}, +#endif +#if defined(__NR_newfstatat) + {__NR_newfstatat, COMMAND_STAT}, +#endif +#if defined(__NR_stat64) + {__NR_stat64, COMMAND_STAT64}, +#endif +#if defined(__NR_lstat64) + {__NR_lstat64, COMMAND_STAT64}, +#endif +#if defined(__NR_unlink) + {__NR_unlink, COMMAND_UNLINK}, +#endif +#if defined(__NR_unlinkat) + {__NR_unlinkat, COMMAND_UNLINK}, +#endif + }; + + EXPECT_GT(base::size(kSyscallToCommandMap), 0u); + + for (const auto& test : kSyscallToCommandMap) { + // Test with fast_check_in_client. + { + SCOPED_TRACE(base::StringPrintf("fast check, sysno=%d", test.sysno)); + BrokerProcess process(ENOSYS, MakeBrokerCommandSet({test.command}), {}, + true, true); + EXPECT_TRUE(process.IsSyscallAllowed(test.sysno)); + for (const auto& other : kSyscallToCommandMap) { + SCOPED_TRACE(base::StringPrintf("others test, sysno=%d", other.sysno)); + EXPECT_EQ(other.command == test.command, + process.IsSyscallAllowed(other.sysno)); + } + } + + // Test without fast_check_in_client. + { + SCOPED_TRACE(base::StringPrintf("no fast check, sysno=%d", test.sysno)); + BrokerProcess process(ENOSYS, MakeBrokerCommandSet({test.command}), {}, + false, true); + EXPECT_TRUE(process.IsSyscallAllowed(test.sysno)); + for (const auto& other : kSyscallToCommandMap) { + SCOPED_TRACE(base::StringPrintf("others test, sysno=%d", other.sysno)); + EXPECT_TRUE(process.IsSyscallAllowed(other.sysno)); + } + } + } +} + } // namespace syscall_broker } // namespace sandbox
diff --git a/services/network/BUILD.gn b/services/network/BUILD.gn index ed36470..bc00fb74 100644 --- a/services/network/BUILD.gn +++ b/services/network/BUILD.gn
@@ -10,6 +10,8 @@ component("network_service") { sources = [ + "cert_verifier_config_type_converter.cc", + "cert_verifier_config_type_converter.h", "chunked_data_pipe_upload_data_stream.cc", "chunked_data_pipe_upload_data_stream.h", "conditional_cache_deletion_helper.cc", @@ -32,6 +34,8 @@ "empty_url_loader_client.h", "expect_ct_reporter.cc", "expect_ct_reporter.h", + "host_resolver.cc", + "host_resolver.h", "http_cache_data_counter.cc", "http_cache_data_counter.h", "http_cache_data_remover.cc", @@ -230,6 +234,7 @@ "cross_origin_read_blocking_unittest.cc", "data_pipe_element_reader_unittest.cc", "expect_ct_reporter_unittest.cc", + "host_resolver_unittest.cc", "http_cache_data_counter_unittest.cc", "http_cache_data_remover_unittest.cc", "ignore_errors_cert_verifier_unittest.cc",
diff --git a/services/network/cert_verifier_config_type_converter.cc b/services/network/cert_verifier_config_type_converter.cc new file mode 100644 index 0000000..bcbb045 --- /dev/null +++ b/services/network/cert_verifier_config_type_converter.cc
@@ -0,0 +1,26 @@ +// Copyright 2018 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 "services/network/cert_verifier_config_type_converter.h" + +namespace mojo { + +net::CertVerifier::Config +TypeConverter<net::CertVerifier::Config, network::mojom::SSLConfigPtr>::Convert( + const network::mojom::SSLConfigPtr& mojo_config) { + DCHECK(mojo_config); + + net::CertVerifier::Config net_config; + net_config.enable_rev_checking = mojo_config->rev_checking_enabled; + net_config.require_rev_checking_local_anchors = + mojo_config->rev_checking_required_local_anchors; + net_config.enable_sha1_local_anchors = + mojo_config->sha1_local_anchors_enabled; + net_config.disable_symantec_enforcement = + mojo_config->symantec_enforcement_disabled; + + return net_config; +} + +} // namespace mojo
diff --git a/services/network/cert_verifier_config_type_converter.h b/services/network/cert_verifier_config_type_converter.h new file mode 100644 index 0000000..5a05579 --- /dev/null +++ b/services/network/cert_verifier_config_type_converter.h
@@ -0,0 +1,24 @@ +// Copyright 2018 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 SERVICES_NETWORK_CERT_VERIFIER_CONFIG_TYPE_CONVERTER_H_ +#define SERVICES_NETWORK_CERT_VERIFIER_CONFIG_TYPE_CONVERTER_H_ + +#include "mojo/public/cpp/bindings/type_converter.h" +#include "net/cert/cert_verifier.h" +#include "services/network/public/mojom/ssl_config.mojom.h" + +namespace mojo { + +// Converts a network::mojom::SSLConfigPtr to a net::CertVerifier::Config. +// Tested in SSLConfigServiceMojo's unittests. +template <> +struct TypeConverter<net::CertVerifier::Config, network::mojom::SSLConfigPtr> { + static net::CertVerifier::Config Convert( + const network::mojom::SSLConfigPtr& mojo_config); +}; + +} // namespace mojo + +#endif // SERVICES_NETWORK_CERT_VERIFIER_CONFIG_TYPE_CONVERTER_H_
diff --git a/services/network/host_resolver.cc b/services/network/host_resolver.cc new file mode 100644 index 0000000..8bbd2f7 --- /dev/null +++ b/services/network/host_resolver.cc
@@ -0,0 +1,96 @@ +// Copyright 2018 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 "services/network/host_resolver.h" + +#include <utility> + +#include "base/bind.h" +#include "base/lazy_instance.h" +#include "base/optional.h" +#include "net/base/host_port_pair.h" +#include "net/base/net_errors.h" +#include "net/dns/host_resolver.h" +#include "net/log/net_log.h" +#include "services/network/resolve_host_request.h" + +namespace network { +namespace { +static base::LazyInstance<HostResolver::ResolveHostCallback>::Leaky + resolve_host_callback; +} + +HostResolver::HostResolver( + mojom::HostResolverRequest resolver_request, + ConnectionShutdownCallback connection_shutdown_callback, + net::HostResolver* internal_resolver, + net::NetLog* net_log) + : binding_(this, std::move(resolver_request)), + connection_shutdown_callback_(std::move(connection_shutdown_callback)), + internal_resolver_(internal_resolver), + net_log_(net_log) { + binding_.set_connection_error_handler( + base::BindOnce(&HostResolver::OnConnectionError, base::Unretained(this))); +} + +HostResolver::HostResolver(net::HostResolver* internal_resolver, + net::NetLog* net_log) + : binding_(this), + internal_resolver_(internal_resolver), + net_log_(net_log) {} + +HostResolver::~HostResolver() { + if (binding_) + binding_.Close(); +} + +void HostResolver::ResolveHost(const net::HostPortPair& host, + mojom::ResolveHostHandleRequest control_handle, + mojom::ResolveHostClientPtr response_client) { + if (resolve_host_callback.Get()) + resolve_host_callback.Get().Run(host.host()); + auto request = + std::make_unique<ResolveHostRequest>(internal_resolver_, host, net_log_); + + int rv = + request->Start(std::move(control_handle), std::move(response_client), + base::BindOnce(&HostResolver::OnResolveHostComplete, + base::Unretained(this), request.get())); + if (rv != net::ERR_IO_PENDING) + return; + + // Store the request with the resolver so it can be cancelled on resolver + // shutdown. + bool insertion_result = requests_.emplace(std::move(request)).second; + DCHECK(insertion_result); +} + +size_t HostResolver::GetNumOutstandingRequestsForTesting() const { + return requests_.size(); +} + +void HostResolver::SetResolveHostCallbackForTesting( + ResolveHostCallback callback) { + resolve_host_callback.Get() = std::move(callback); +} + +void HostResolver::OnResolveHostComplete(ResolveHostRequest* request, + int error) { + DCHECK_NE(net::ERR_IO_PENDING, error); + + auto found_request = requests_.find(request); + DCHECK(found_request != requests_.end()); + requests_.erase(found_request); +} + +void HostResolver::OnConnectionError() { + DCHECK(connection_shutdown_callback_); + + requests_.clear(); + + // Invoke last as callback may delete |this|. + std::move(connection_shutdown_callback_).Run(this); +} + +} // namespace network
diff --git a/services/network/host_resolver.h b/services/network/host_resolver.h new file mode 100644 index 0000000..7d4901a --- /dev/null +++ b/services/network/host_resolver.h
@@ -0,0 +1,75 @@ +// Copyright 2018 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 SERVICES_NETWORK_HOST_RESOLVER_H_ +#define SERVICES_NETWORK_HOST_RESOLVER_H_ + +#include <memory> +#include <set> + +#include "base/callback.h" +#include "base/component_export.h" +#include "base/containers/unique_ptr_adapters.h" +#include "base/macros.h" +#include "mojo/public/cpp/bindings/binding.h" +#include "services/network/public/mojom/host_resolver.mojom.h" + +namespace net { +class HostResolver; +class HostPortPair; +class NetLog; +} // namespace net + +namespace network { +class ResolveHostRequest; + +class COMPONENT_EXPORT(NETWORK_SERVICE) HostResolver + : public mojom::HostResolver { + public: + using ConnectionShutdownCallback = base::OnceCallback<void(HostResolver*)>; + + // Constructs and binds to the given mojom::HostResolver pipe. On pipe close, + // cancels all outstanding requests (whether made through the pipe or by + // directly calling ResolveHost()) with ERR_FAILED. Also on pipe close, calls + // |connection_shutdown_callback| and passes |this| to notify that the + // resolver has cancelled all requests and may be cleaned up. + HostResolver(mojom::HostResolverRequest resolver_request, + ConnectionShutdownCallback connection_shutdown_callback, + net::HostResolver* internal_resolver, + net::NetLog* net_log); + // Constructor for when the resolver will not be bound to a + // mojom::HostResolver pipe, eg because it is handling ResolveHost requests + // made directly on NetworkContext. + HostResolver(net::HostResolver* internal_resolver, net::NetLog* net_log); + ~HostResolver() override; + + void ResolveHost(const net::HostPortPair& host, + mojom::ResolveHostHandleRequest control_handle, + mojom::ResolveHostClientPtr response_client) override; + + size_t GetNumOutstandingRequestsForTesting() const; + + // Sets a global callback when a ResolveHost call arrives. + using ResolveHostCallback = + base::RepeatingCallback<void(const std::string& host)>; + static void SetResolveHostCallbackForTesting(ResolveHostCallback callback); + + private: + void OnResolveHostComplete(ResolveHostRequest* request, int error); + void OnConnectionError(); + + mojo::Binding<mojom::HostResolver> binding_; + ConnectionShutdownCallback connection_shutdown_callback_; + std::set<std::unique_ptr<ResolveHostRequest>, base::UniquePtrComparator> + requests_; + + net::HostResolver* const internal_resolver_; + net::NetLog* const net_log_; + + DISALLOW_COPY_AND_ASSIGN(HostResolver); +}; + +} // namespace network + +#endif // SERVICES_NETWORK_HOST_RESOLVER_H_
diff --git a/services/network/host_resolver_unittest.cc b/services/network/host_resolver_unittest.cc new file mode 100644 index 0000000..48766d9 --- /dev/null +++ b/services/network/host_resolver_unittest.cc
@@ -0,0 +1,562 @@ +// Copyright 2018 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 <memory> +#include <string> +#include <utility> + +#include "base/logging.h" +#include "base/optional.h" +#include "base/run_loop.h" +#include "base/test/bind_test_util.h" +#include "base/test/scoped_task_environment.h" +#include "mojo/public/cpp/bindings/binding.h" +#include "mojo/public/cpp/bindings/interface_request.h" +#include "net/base/address_list.h" +#include "net/base/host_port_pair.h" +#include "net/base/ip_address.h" +#include "net/base/net_errors.h" +#include "net/dns/mock_host_resolver.h" +#include "net/log/net_log.h" +#include "services/network/host_resolver.h" +#include "services/network/public/mojom/host_resolver.mojom.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace network { +namespace { + +class HostResolverTest : public testing::Test { + public: + HostResolverTest() + : scoped_task_environment_( + base::test::ScopedTaskEnvironment::MainThreadType::IO) {} + + protected: + base::test::ScopedTaskEnvironment scoped_task_environment_; +}; + +net::IPEndPoint CreateExpectedEndPoint(const std::string& address, + uint16_t port) { + net::IPAddress ip_address; + CHECK(ip_address.AssignFromIPLiteral(address)); + return net::IPEndPoint(ip_address, port); +} + +class TestResolveHostClient : public mojom::ResolveHostClient { + public: + // If |run_loop| is non-null, will call RunLoop::Quit() on completion. + TestResolveHostClient(mojom::ResolveHostClientPtr* interface_ptr, + base::RunLoop* run_loop) + : binding_(this, mojo::MakeRequest(interface_ptr)), + complete_(false), + result_error_(net::ERR_UNEXPECTED), + run_loop_(run_loop) {} + + void CloseBinding() { binding_.Close(); } + + void OnComplete(int error, + const base::Optional<net::AddressList>& addresses) override { + DCHECK(!complete_); + + complete_ = true; + result_error_ = error; + result_addresses_ = addresses; + if (run_loop_) + run_loop_->Quit(); + } + + bool complete() const { return complete_; } + + int result_error() const { + DCHECK(complete_); + return result_error_; + } + + const base::Optional<net::AddressList>& result_addresses() const { + DCHECK(complete_); + return result_addresses_; + } + + private: + mojo::Binding<mojom::ResolveHostClient> binding_; + + bool complete_; + int result_error_; + base::Optional<net::AddressList> result_addresses_; + base::RunLoop* const run_loop_; +}; + +TEST_F(HostResolverTest, Sync) { + auto inner_resolver = std::make_unique<net::MockHostResolver>(); + inner_resolver->set_synchronous_mode(true); + net::NetLog net_log; + + HostResolver resolver(inner_resolver.get(), &net_log); + + base::RunLoop run_loop; + mojom::ResolveHostClientPtr response_client_ptr; + TestResolveHostClient response_client(&response_client_ptr, &run_loop); + + mojom::ResolveHostHandlePtr control_handle; + resolver.ResolveHost(net::HostPortPair("localhost", 160), + mojo::MakeRequest(&control_handle), + std::move(response_client_ptr)); + run_loop.Run(); + + EXPECT_EQ(net::OK, response_client.result_error()); + EXPECT_THAT(response_client.result_addresses().value().endpoints(), + testing::ElementsAre(CreateExpectedEndPoint("127.0.0.1", 160))); + EXPECT_EQ(0u, resolver.GetNumOutstandingRequestsForTesting()); +} + +TEST_F(HostResolverTest, Async) { + auto inner_resolver = std::make_unique<net::MockHostResolver>(); + inner_resolver->set_synchronous_mode(false); + net::NetLog net_log; + + HostResolver resolver(inner_resolver.get(), &net_log); + + base::RunLoop run_loop; + mojom::ResolveHostClientPtr response_client_ptr; + TestResolveHostClient response_client(&response_client_ptr, &run_loop); + + mojom::ResolveHostHandlePtr control_handle; + resolver.ResolveHost(net::HostPortPair("localhost", 160), + mojo::MakeRequest(&control_handle), + std::move(response_client_ptr)); + + bool control_handle_closed = false; + auto connection_error_callback = + base::BindLambdaForTesting([&]() { control_handle_closed = true; }); + control_handle.set_connection_error_handler(connection_error_callback); + run_loop.Run(); + + EXPECT_EQ(net::OK, response_client.result_error()); + EXPECT_THAT(response_client.result_addresses().value().endpoints(), + testing::ElementsAre(CreateExpectedEndPoint("127.0.0.1", 160))); + EXPECT_TRUE(control_handle_closed); + EXPECT_EQ(0u, resolver.GetNumOutstandingRequestsForTesting()); +} + +TEST_F(HostResolverTest, Failure_Sync) { + auto inner_resolver = std::make_unique<net::MockHostResolver>(); + inner_resolver->rules()->AddSimulatedFailure("example.com"); + inner_resolver->set_synchronous_mode(true); + net::NetLog net_log; + + HostResolver resolver(inner_resolver.get(), &net_log); + + base::RunLoop run_loop; + mojom::ResolveHostClientPtr response_client_ptr; + TestResolveHostClient response_client(&response_client_ptr, &run_loop); + + mojom::ResolveHostHandlePtr control_handle; + resolver.ResolveHost(net::HostPortPair("example.com", 160), + mojo::MakeRequest(&control_handle), + std::move(response_client_ptr)); + run_loop.Run(); + + EXPECT_EQ(net::ERR_NAME_NOT_RESOLVED, response_client.result_error()); + EXPECT_FALSE(response_client.result_addresses()); + EXPECT_EQ(0u, resolver.GetNumOutstandingRequestsForTesting()); +} + +TEST_F(HostResolverTest, Failure_Async) { + auto inner_resolver = std::make_unique<net::MockHostResolver>(); + inner_resolver->rules()->AddSimulatedFailure("example.com"); + inner_resolver->set_synchronous_mode(false); + net::NetLog net_log; + + HostResolver resolver(inner_resolver.get(), &net_log); + + base::RunLoop run_loop; + mojom::ResolveHostClientPtr response_client_ptr; + TestResolveHostClient response_client(&response_client_ptr, &run_loop); + + mojom::ResolveHostHandlePtr control_handle; + resolver.ResolveHost(net::HostPortPair("example.com", 160), + mojo::MakeRequest(&control_handle), + std::move(response_client_ptr)); + + bool control_handle_closed = false; + auto connection_error_callback = + base::BindLambdaForTesting([&]() { control_handle_closed = true; }); + control_handle.set_connection_error_handler(connection_error_callback); + run_loop.Run(); + + EXPECT_EQ(net::ERR_NAME_NOT_RESOLVED, response_client.result_error()); + EXPECT_FALSE(response_client.result_addresses()); + EXPECT_TRUE(control_handle_closed); + EXPECT_EQ(0u, resolver.GetNumOutstandingRequestsForTesting()); +} + +TEST_F(HostResolverTest, NoControlHandle) { + net::NetLog net_log; + std::unique_ptr<net::HostResolver> inner_resolver = + net::HostResolver::CreateDefaultResolver(&net_log); + + HostResolver resolver(inner_resolver.get(), &net_log); + + base::RunLoop run_loop; + mojom::ResolveHostClientPtr response_client_ptr; + TestResolveHostClient response_client(&response_client_ptr, &run_loop); + + // Resolve "localhost" because it should always resolve fast and locally, even + // when using a real HostResolver. + resolver.ResolveHost(net::HostPortPair("localhost", 80), nullptr, + std::move(response_client_ptr)); + run_loop.Run(); + + EXPECT_EQ(net::OK, response_client.result_error()); + EXPECT_THAT( + response_client.result_addresses().value().endpoints(), + testing::UnorderedElementsAre(CreateExpectedEndPoint("127.0.0.1", 80), + CreateExpectedEndPoint("::1", 80))); + EXPECT_EQ(0u, resolver.GetNumOutstandingRequestsForTesting()); +} + +TEST_F(HostResolverTest, CloseControlHandle) { + net::NetLog net_log; + std::unique_ptr<net::HostResolver> inner_resolver = + net::HostResolver::CreateDefaultResolver(&net_log); + + HostResolver resolver(inner_resolver.get(), &net_log); + + base::RunLoop run_loop; + mojom::ResolveHostClientPtr response_client_ptr; + TestResolveHostClient response_client(&response_client_ptr, &run_loop); + + // Resolve "localhost" because it should always resolve fast and locally, even + // when using a real HostResolver. + mojom::ResolveHostHandlePtr control_handle; + resolver.ResolveHost(net::HostPortPair("localhost", 160), + mojo::MakeRequest(&control_handle), + std::move(response_client_ptr)); + control_handle = nullptr; + run_loop.Run(); + + EXPECT_EQ(net::OK, response_client.result_error()); + EXPECT_THAT( + response_client.result_addresses().value().endpoints(), + testing::UnorderedElementsAre(CreateExpectedEndPoint("127.0.0.1", 160), + CreateExpectedEndPoint("::1", 160))); + EXPECT_EQ(0u, resolver.GetNumOutstandingRequestsForTesting()); +} + +TEST_F(HostResolverTest, Cancellation) { + // Use a HangingHostResolver, so the test can ensure the request won't be + // completed before the cancellation arrives. + auto inner_resolver = std::make_unique<net::HangingHostResolver>(); + net::NetLog net_log; + + HostResolver resolver(inner_resolver.get(), &net_log); + + ASSERT_EQ(0, inner_resolver->num_cancellations()); + + base::RunLoop run_loop; + mojom::ResolveHostClientPtr response_client_ptr; + TestResolveHostClient response_client(&response_client_ptr, &run_loop); + + mojom::ResolveHostHandlePtr control_handle; + resolver.ResolveHost(net::HostPortPair("localhost", 80), + mojo::MakeRequest(&control_handle), + std::move(response_client_ptr)); + bool control_handle_closed = false; + auto connection_error_callback = + base::BindLambdaForTesting([&]() { control_handle_closed = true; }); + control_handle.set_connection_error_handler(connection_error_callback); + + control_handle->Cancel(net::ERR_ABORTED); + run_loop.Run(); + + // On cancellation, should receive an ERR_FAILED result, and the internal + // resolver request should have been cancelled. + EXPECT_EQ(net::ERR_ABORTED, response_client.result_error()); + EXPECT_FALSE(response_client.result_addresses()); + EXPECT_EQ(1, inner_resolver->num_cancellations()); + EXPECT_TRUE(control_handle_closed); + EXPECT_EQ(0u, resolver.GetNumOutstandingRequestsForTesting()); +} + +TEST_F(HostResolverTest, Cancellation_SubsequentRequest) { + net::NetLog net_log; + std::unique_ptr<net::HostResolver> inner_resolver = + net::HostResolver::CreateDefaultResolver(&net_log); + + HostResolver resolver(inner_resolver.get(), &net_log); + + base::RunLoop run_loop; + mojom::ResolveHostClientPtr response_client_ptr; + TestResolveHostClient response_client(&response_client_ptr, nullptr); + + mojom::ResolveHostHandlePtr control_handle; + resolver.ResolveHost(net::HostPortPair("localhost", 80), + mojo::MakeRequest(&control_handle), + std::move(response_client_ptr)); + + control_handle->Cancel(net::ERR_ABORTED); + run_loop.RunUntilIdle(); + + // Not using a hanging resolver, so could be ERR_ABORTED or OK depending on + // timing of the cancellation. + EXPECT_TRUE(response_client.result_error() == net::ERR_ABORTED || + response_client.result_error() == net::OK); + EXPECT_EQ(0u, resolver.GetNumOutstandingRequestsForTesting()); + + // Subsequent requests should be unaffected by the cancellation. + base::RunLoop run_loop2; + mojom::ResolveHostClientPtr response_client_ptr2; + TestResolveHostClient response_client2(&response_client_ptr2, &run_loop2); + resolver.ResolveHost(net::HostPortPair("localhost", 80), nullptr, + std::move(response_client_ptr2)); + run_loop2.Run(); + + EXPECT_EQ(net::OK, response_client2.result_error()); + EXPECT_THAT( + response_client2.result_addresses().value().endpoints(), + testing::UnorderedElementsAre(CreateExpectedEndPoint("127.0.0.1", 80), + CreateExpectedEndPoint("::1", 80))); + EXPECT_EQ(0u, resolver.GetNumOutstandingRequestsForTesting()); +} + +TEST_F(HostResolverTest, DestroyResolver) { + // Use a HangingHostResolver, so the test can ensure the request won't be + // completed before the cancellation arrives. + auto inner_resolver = std::make_unique<net::HangingHostResolver>(); + net::NetLog net_log; + + auto resolver = + std::make_unique<HostResolver>(inner_resolver.get(), &net_log); + + ASSERT_EQ(0, inner_resolver->num_cancellations()); + + base::RunLoop run_loop; + mojom::ResolveHostClientPtr response_client_ptr; + TestResolveHostClient response_client(&response_client_ptr, &run_loop); + + mojom::ResolveHostHandlePtr control_handle; + resolver->ResolveHost(net::HostPortPair("localhost", 80), + mojo::MakeRequest(&control_handle), + std::move(response_client_ptr)); + bool control_handle_closed = false; + auto connection_error_callback = + base::BindLambdaForTesting([&]() { control_handle_closed = true; }); + control_handle.set_connection_error_handler(connection_error_callback); + + resolver = nullptr; + run_loop.Run(); + + // On context destruction, should receive an ERR_FAILED result, and the + // internal resolver request should have been cancelled. + EXPECT_EQ(net::ERR_FAILED, response_client.result_error()); + EXPECT_FALSE(response_client.result_addresses()); + EXPECT_EQ(1, inner_resolver->num_cancellations()); + EXPECT_TRUE(control_handle_closed); +} + +TEST_F(HostResolverTest, CloseClient) { + // Use a HangingHostResolver, so the test can ensure the request won't be + // completed before the cancellation arrives. + auto inner_resolver = std::make_unique<net::HangingHostResolver>(); + net::NetLog net_log; + + HostResolver resolver(inner_resolver.get(), &net_log); + + ASSERT_EQ(0, inner_resolver->num_cancellations()); + + base::RunLoop run_loop; + mojom::ResolveHostClientPtr response_client_ptr; + TestResolveHostClient response_client(&response_client_ptr, &run_loop); + + mojom::ResolveHostHandlePtr control_handle; + resolver.ResolveHost(net::HostPortPair("localhost", 80), + mojo::MakeRequest(&control_handle), + std::move(response_client_ptr)); + bool control_handle_closed = false; + auto connection_error_callback = + base::BindLambdaForTesting([&]() { control_handle_closed = true; }); + control_handle.set_connection_error_handler(connection_error_callback); + + response_client.CloseBinding(); + run_loop.RunUntilIdle(); + + // Response pipe is closed, so no results to check. Internal request should be + // cancelled. + EXPECT_FALSE(response_client.complete()); + EXPECT_EQ(1, inner_resolver->num_cancellations()); + EXPECT_TRUE(control_handle_closed); + EXPECT_EQ(0u, resolver.GetNumOutstandingRequestsForTesting()); +} + +TEST_F(HostResolverTest, CloseClient_SubsequentRequest) { + net::NetLog net_log; + std::unique_ptr<net::HostResolver> inner_resolver = + net::HostResolver::CreateDefaultResolver(&net_log); + + HostResolver resolver(inner_resolver.get(), &net_log); + + base::RunLoop run_loop; + mojom::ResolveHostClientPtr response_client_ptr; + TestResolveHostClient response_client(&response_client_ptr, nullptr); + + mojom::ResolveHostHandlePtr control_handle; + resolver.ResolveHost(net::HostPortPair("localhost", 80), nullptr, + std::move(response_client_ptr)); + + response_client.CloseBinding(); + run_loop.RunUntilIdle(); + + // Not using a hanging resolver, so could be incomplete or OK depending on + // timing of the cancellation. + EXPECT_TRUE(!response_client.complete() || + response_client.result_error() == net::OK); + EXPECT_EQ(0u, resolver.GetNumOutstandingRequestsForTesting()); + + // Subsequent requests should be unaffected by the cancellation. + base::RunLoop run_loop2; + mojom::ResolveHostClientPtr response_client_ptr2; + TestResolveHostClient response_client2(&response_client_ptr2, &run_loop2); + resolver.ResolveHost(net::HostPortPair("localhost", 80), nullptr, + std::move(response_client_ptr2)); + run_loop2.Run(); + + EXPECT_EQ(net::OK, response_client2.result_error()); + EXPECT_THAT( + response_client2.result_addresses().value().endpoints(), + testing::UnorderedElementsAre(CreateExpectedEndPoint("127.0.0.1", 80), + CreateExpectedEndPoint("::1", 80))); + EXPECT_EQ(0u, resolver.GetNumOutstandingRequestsForTesting()); +} + +TEST_F(HostResolverTest, Binding) { + mojom::HostResolverPtr resolver_ptr; + HostResolver* shutdown_resolver = nullptr; + HostResolver::ConnectionShutdownCallback shutdown_callback = + base::BindLambdaForTesting( + [&](HostResolver* resolver) { shutdown_resolver = resolver; }); + + net::NetLog net_log; + std::unique_ptr<net::HostResolver> inner_resolver = + net::HostResolver::CreateDefaultResolver(&net_log); + + HostResolver resolver(mojo::MakeRequest(&resolver_ptr), + std::move(shutdown_callback), inner_resolver.get(), + &net_log); + + base::RunLoop run_loop; + mojom::ResolveHostClientPtr response_client_ptr; + TestResolveHostClient response_client(&response_client_ptr, &run_loop); + // Resolve "localhost" because it should always resolve fast and locally, even + // when using a real HostResolver. + mojom::ResolveHostHandlePtr control_handle; + resolver_ptr->ResolveHost(net::HostPortPair("localhost", 160), + mojo::MakeRequest(&control_handle), + std::move(response_client_ptr)); + run_loop.Run(); + + EXPECT_EQ(net::OK, response_client.result_error()); + EXPECT_THAT( + response_client.result_addresses().value().endpoints(), + testing::UnorderedElementsAre(CreateExpectedEndPoint("127.0.0.1", 160), + CreateExpectedEndPoint("::1", 160))); + EXPECT_EQ(0u, resolver.GetNumOutstandingRequestsForTesting()); + EXPECT_FALSE(shutdown_resolver); +} + +TEST_F(HostResolverTest, CloseBinding) { + mojom::HostResolverPtr resolver_ptr; + HostResolver* shutdown_resolver = nullptr; + HostResolver::ConnectionShutdownCallback shutdown_callback = + base::BindLambdaForTesting( + [&](HostResolver* resolver) { shutdown_resolver = resolver; }); + + // Use a HangingHostResolver, so the test can ensure the request won't be + // completed before the cancellation arrives. + auto inner_resolver = std::make_unique<net::HangingHostResolver>(); + net::NetLog net_log; + + HostResolver resolver(mojo::MakeRequest(&resolver_ptr), + std::move(shutdown_callback), inner_resolver.get(), + &net_log); + + ASSERT_EQ(0, inner_resolver->num_cancellations()); + + base::RunLoop run_loop; + mojom::ResolveHostClientPtr response_client_ptr; + TestResolveHostClient response_client(&response_client_ptr, &run_loop); + mojom::ResolveHostHandlePtr control_handle; + resolver_ptr->ResolveHost(net::HostPortPair("localhost", 160), + mojo::MakeRequest(&control_handle), + std::move(response_client_ptr)); + bool control_handle_closed = false; + auto connection_error_callback = + base::BindLambdaForTesting([&]() { control_handle_closed = true; }); + control_handle.set_connection_error_handler(connection_error_callback); + + resolver_ptr = nullptr; + run_loop.Run(); + + // Request should be cancelled. + EXPECT_EQ(net::ERR_FAILED, response_client.result_error()); + EXPECT_FALSE(response_client.result_addresses()); + EXPECT_TRUE(control_handle_closed); + EXPECT_EQ(1, inner_resolver->num_cancellations()); + EXPECT_EQ(0u, resolver.GetNumOutstandingRequestsForTesting()); + + // Callback should have been called. + EXPECT_EQ(&resolver, shutdown_resolver); +} + +TEST_F(HostResolverTest, CloseBinding_SubsequentRequest) { + mojom::HostResolverPtr resolver_ptr; + HostResolver* shutdown_resolver = nullptr; + HostResolver::ConnectionShutdownCallback shutdown_callback = + base::BindLambdaForTesting( + [&](HostResolver* resolver) { shutdown_resolver = resolver; }); + + net::NetLog net_log; + std::unique_ptr<net::HostResolver> inner_resolver = + net::HostResolver::CreateDefaultResolver(&net_log); + + HostResolver resolver(mojo::MakeRequest(&resolver_ptr), + std::move(shutdown_callback), inner_resolver.get(), + &net_log); + + base::RunLoop run_loop; + mojom::ResolveHostClientPtr response_client_ptr; + TestResolveHostClient response_client(&response_client_ptr, nullptr); + resolver_ptr->ResolveHost(net::HostPortPair("localhost", 160), nullptr, + std::move(response_client_ptr)); + + resolver_ptr = nullptr; + run_loop.RunUntilIdle(); + + // Not using a hanging resolver, so could be ERR_FAILED or OK depending on + // timing of the cancellation. + EXPECT_TRUE(response_client.result_error() == net::ERR_FAILED || + response_client.result_error() == net::OK); + EXPECT_EQ(0u, resolver.GetNumOutstandingRequestsForTesting()); + + // Callback should have been called. + EXPECT_EQ(&resolver, shutdown_resolver); + + // Subsequent requests should be unaffected by the cancellation. + base::RunLoop run_loop2; + mojom::ResolveHostClientPtr response_client_ptr2; + TestResolveHostClient response_client2(&response_client_ptr2, &run_loop2); + resolver.ResolveHost(net::HostPortPair("localhost", 80), nullptr, + std::move(response_client_ptr2)); + run_loop2.Run(); + + EXPECT_EQ(net::OK, response_client2.result_error()); + EXPECT_THAT( + response_client2.result_addresses().value().endpoints(), + testing::UnorderedElementsAre(CreateExpectedEndPoint("127.0.0.1", 80), + CreateExpectedEndPoint("::1", 80))); + EXPECT_EQ(0u, resolver.GetNumOutstandingRequestsForTesting()); +} + +} // namespace +} // namespace network
diff --git a/services/network/ignore_errors_cert_verifier.cc b/services/network/ignore_errors_cert_verifier.cc index b6a67488..0df80e72 100644 --- a/services/network/ignore_errors_cert_verifier.cc +++ b/services/network/ignore_errors_cert_verifier.cc
@@ -133,6 +133,10 @@ out_req, net_log); } +void IgnoreErrorsCertVerifier::SetConfig(const Config& config) { + verifier_->SetConfig(config); +} + void IgnoreErrorsCertVerifier::set_whitelist(const SPKIHashSet& whitelist) { whitelist_ = whitelist; }
diff --git a/services/network/ignore_errors_cert_verifier.h b/services/network/ignore_errors_cert_verifier.h index ce0984c..ad895ec 100644 --- a/services/network/ignore_errors_cert_verifier.h +++ b/services/network/ignore_errors_cert_verifier.h
@@ -64,6 +64,7 @@ net::CompletionOnceCallback callback, std::unique_ptr<Request>* out_req, const net::NetLogWithSource& net_log) override; + void SetConfig(const Config& config) override; private: friend class IgnoreErrorsCertVerifierTest;
diff --git a/services/network/network_context.cc b/services/network/network_context.cc index 1ab794a..5ef646cf 100644 --- a/services/network/network_context.cc +++ b/services/network/network_context.cc
@@ -67,6 +67,7 @@ #include "services/network/cookie_manager.h" #include "services/network/cors/cors_url_loader_factory.h" #include "services/network/expect_ct_reporter.h" +#include "services/network/host_resolver.h" #include "services/network/http_server_properties_pref_delegate.h" #include "services/network/ignore_errors_cert_verifier.h" #include "services/network/mojo_net_log.h" @@ -138,6 +139,11 @@ return g_cert_verifier_for_testing->Verify( params, crl_set, verify_result, std::move(callback), out_req, net_log); } + void SetConfig(const Config& config) override { + if (!g_cert_verifier_for_testing) + return; + g_cert_verifier_for_testing->SetConfig(config); + } }; // Predicate function to determine if the given |domain| matches the @@ -522,7 +528,12 @@ } size_t NetworkContext::GetNumOutstandingResolveHostRequestsForTesting() const { - return resolve_host_requests_.size(); + size_t sum = 0; + if (internal_host_resolver_) + sum += internal_host_resolver_->GetNumOutstandingRequestsForTesting(); + for (const auto& host_resolver : host_resolvers_) + sum += host_resolver->GetNumOutstandingRequestsForTesting(); + return sum; } void NetworkContext::ClearNetworkingHistorySince( @@ -805,21 +816,21 @@ void NetworkContext::ResolveHost(const net::HostPortPair& host, mojom::ResolveHostHandleRequest control_handle, mojom::ResolveHostClientPtr response_client) { - auto request = std::make_unique<ResolveHostRequest>( - url_request_context_->host_resolver(), host, network_service_->net_log()); + if (!internal_host_resolver_) { + internal_host_resolver_ = std::make_unique<HostResolver>( + url_request_context_->host_resolver(), network_service_->net_log()); + } - int rv = - request->Start(std::move(control_handle), std::move(response_client), - base::BindOnce(&NetworkContext::OnResolveHostComplete, - base::Unretained(this), request.get())); - if (rv != net::ERR_IO_PENDING) - return; + internal_host_resolver_->ResolveHost(host, std::move(control_handle), + std::move(response_client)); +} - // Store the request with the context so it can be cancelled on context - // shutdown. - bool insertion_result = - resolve_host_requests_.insert(std::move(request)).second; - DCHECK(insertion_result); +void NetworkContext::CreateHostResolver(mojom::HostResolverRequest request) { + host_resolvers_.emplace(std::make_unique<HostResolver>( + std::move(request), + base::BindOnce(&NetworkContext::OnHostResolverShutdown, + base::Unretained(this)), + url_request_context_->host_resolver(), network_service_->net_log())); } void NetworkContext::AddHSTSForTesting(const std::string& host, @@ -1010,9 +1021,12 @@ builder->EnableHttpCache(cache_params); } - builder->set_ssl_config_service(std::make_unique<SSLConfigServiceMojo>( - std::move(params_->initial_ssl_config), - std::move(params_->ssl_config_client_request))); + std::unique_ptr<SSLConfigServiceMojo> ssl_config_service = + std::make_unique<SSLConfigServiceMojo>( + std::move(params_->initial_ssl_config), + std::move(params_->ssl_config_client_request)); + SSLConfigServiceMojo* ssl_config_service_raw = ssl_config_service.get(); + builder->set_ssl_config_service(std::move(ssl_config_service)); if (!params_->initial_proxy_config && !params_->proxy_config_client_request.is_pending()) { @@ -1146,6 +1160,12 @@ auto result = URLRequestContextOwner(std::move(pref_service), builder->Build()); + // Subscribe the CertVerifier to configuration changes that are exposed via + // the mojom::SSLConfig, but which are not part of the + // net::SSLConfig[Service] interfaces. + ssl_config_service_raw->SetCertVerifierForConfiguring( + result.url_request_context->cert_verifier()); + // Attach some things to the URLRequestContextBuilder's // TransportSecurityState. Since no requests have been made yet, safe to do // this even after the call to Build(). @@ -1248,13 +1268,10 @@ std::move(callback).Run(); } -void NetworkContext::OnResolveHostComplete(ResolveHostRequest* request, - int error) { - DCHECK_NE(net::ERR_IO_PENDING, error); - - auto found_request = resolve_host_requests_.find(request); - DCHECK(found_request != resolve_host_requests_.end()); - resolve_host_requests_.erase(found_request); +void NetworkContext::OnHostResolverShutdown(HostResolver* resolver) { + auto found_resolver = host_resolvers_.find(resolver); + DCHECK(found_resolver != host_resolvers_.end()); + host_resolvers_.erase(found_resolver); } void NetworkContext::OnHttpCacheSizeComputed(
diff --git a/services/network/network_context.h b/services/network/network_context.h index e44cb4fe..d79690e 100644 --- a/services/network/network_context.h +++ b/services/network/network_context.h
@@ -56,10 +56,10 @@ namespace network { class CookieManager; class ExpectCTReporter; +class HostResolver; class NetworkService; class P2PSocketManager; class ProxyLookupRequest; -class ResolveHostRequest; class ResourceScheduler; class ResourceSchedulerClient; class URLRequestContextBuilderMojo; @@ -210,6 +210,7 @@ void ResolveHost(const net::HostPortPair& host, mojom::ResolveHostHandleRequest control_handle, mojom::ResolveHostClientPtr response_client) override; + void CreateHostResolver(mojom::HostResolverRequest request) override; void AddHSTSForTesting(const std::string& host, base::Time expiry, bool include_subdomains, @@ -255,7 +256,7 @@ void OnHttpCacheCleared(ClearHttpCacheCallback callback, HttpCacheDataRemover* remover); - void OnResolveHostComplete(ResolveHostRequest* request, int error); + void OnHostResolverShutdown(HostResolver* resolver); // Invoked when the computation for ComputeHttpCacheSize() has been completed, // to report result to user via |callback| and clean things up. @@ -344,8 +345,10 @@ require_ct_delegate_; std::unique_ptr<certificate_transparency::TreeStateTracker> ct_tree_tracker_; - std::set<std::unique_ptr<ResolveHostRequest>, base::UniquePtrComparator> - resolve_host_requests_; + // Created on-demand. Null if unused. + std::unique_ptr<HostResolver> internal_host_resolver_; + std::set<std::unique_ptr<HostResolver>, base::UniquePtrComparator> + host_resolvers_; DISALLOW_COPY_AND_ASSIGN(NetworkContext); };
diff --git a/services/network/network_context_unittest.cc b/services/network/network_context_unittest.cc index 121ecd64..ae04f85 100644 --- a/services/network/network_context_unittest.cc +++ b/services/network/network_context_unittest.cc
@@ -41,6 +41,7 @@ #include "mojo/public/cpp/system/data_pipe_utils.h" #include "net/base/cache_type.h" #include "net/base/hash_value.h" +#include "net/base/host_port_pair.h" #include "net/base/ip_endpoint.h" #include "net/base/net_errors.h" #include "net/base/test_completion_callback.h" @@ -80,6 +81,7 @@ #include "services/network/network_context.h" #include "services/network/network_service.h" #include "services/network/public/cpp/features.h" +#include "services/network/public/mojom/host_resolver.mojom.h" #include "services/network/public/mojom/network_service.mojom.h" #include "services/network/public/mojom/proxy_config.mojom.h" #include "services/network/test/test_url_loader_client.h" @@ -2880,6 +2882,118 @@ network_context->GetNumOutstandingResolveHostRequestsForTesting()); } +TEST_F(NetworkContextTest, CreateHostResolver) { + std::unique_ptr<NetworkContext> network_context = + CreateContextWithParams(CreateContextParams()); + + mojom::HostResolverPtr resolver; + network_context->CreateHostResolver(mojo::MakeRequest(&resolver)); + + base::RunLoop run_loop; + mojom::ResolveHostClientPtr response_client_ptr; + TestResolveHostClient response_client(&response_client_ptr, &run_loop); + + resolver->ResolveHost(net::HostPortPair("localhost", 80), nullptr, + std::move(response_client_ptr)); + run_loop.Run(); + + EXPECT_EQ(net::OK, response_client.result_error()); + EXPECT_THAT( + response_client.result_addresses().value().endpoints(), + testing::UnorderedElementsAre(CreateExpectedEndPoint("127.0.0.1", 80), + CreateExpectedEndPoint("::1", 80))); + EXPECT_EQ(0u, + network_context->GetNumOutstandingResolveHostRequestsForTesting()); +} + +TEST_F(NetworkContextTest, CreateHostResolver_CloseResolver) { + std::unique_ptr<NetworkContext> network_context = + CreateContextWithParams(CreateContextParams()); + + // Override the HostResolver with a hanging one, so the test can ensure the + // request won't be completed before the cancellation arrives. + auto internal_resolver = std::make_unique<net::HangingHostResolver>(); + network_context->url_request_context()->set_host_resolver( + internal_resolver.get()); + + mojom::HostResolverPtr resolver; + network_context->CreateHostResolver(mojo::MakeRequest(&resolver)); + + ASSERT_EQ(0, internal_resolver->num_cancellations()); + + base::RunLoop run_loop; + mojom::ResolveHostClientPtr response_client_ptr; + TestResolveHostClient response_client(&response_client_ptr, &run_loop); + + mojom::ResolveHostHandlePtr control_handle; + resolver->ResolveHost(net::HostPortPair("localhost", 80), + mojo::MakeRequest(&control_handle), + std::move(response_client_ptr)); + bool control_handle_closed = false; + auto connection_error_callback = + base::BindLambdaForTesting([&]() { control_handle_closed = true; }); + control_handle.set_connection_error_handler(connection_error_callback); + + resolver = nullptr; + run_loop.Run(); + + // On resolver destruction, should receive an ERR_FAILED result, and the + // internal resolver request should have been cancelled. + EXPECT_EQ(net::ERR_FAILED, response_client.result_error()); + EXPECT_FALSE(response_client.result_addresses()); + EXPECT_EQ(1, internal_resolver->num_cancellations()); + EXPECT_TRUE(control_handle_closed); +} + +TEST_F(NetworkContextTest, CreateHostResolver_CloseContext) { + std::unique_ptr<NetworkContext> network_context = + CreateContextWithParams(CreateContextParams()); + + // Override the HostResolver with a hanging one, so the test can ensure the + // request won't be completed before the cancellation arrives. + auto internal_resolver = std::make_unique<net::HangingHostResolver>(); + network_context->url_request_context()->set_host_resolver( + internal_resolver.get()); + + mojom::HostResolverPtr resolver; + network_context->CreateHostResolver(mojo::MakeRequest(&resolver)); + + ASSERT_EQ(0, internal_resolver->num_cancellations()); + + base::RunLoop run_loop; + mojom::ResolveHostClientPtr response_client_ptr; + TestResolveHostClient response_client(&response_client_ptr, &run_loop); + + mojom::ResolveHostHandlePtr control_handle; + resolver->ResolveHost(net::HostPortPair("localhost", 80), + mojo::MakeRequest(&control_handle), + std::move(response_client_ptr)); + // Run a bit to ensure the resolve request makes it to the resolver. Otherwise + // the resolver will be destroyed and close its pipe before it even knows + // about the request to send a failure. + scoped_task_environment_.RunUntilIdle(); + + bool control_handle_closed = false; + auto connection_error_callback = + base::BindLambdaForTesting([&]() { control_handle_closed = true; }); + control_handle.set_connection_error_handler(connection_error_callback); + bool resolver_closed = false; + auto resolver_closed_callback = + base::BindLambdaForTesting([&]() { resolver_closed = true; }); + resolver.set_connection_error_handler(resolver_closed_callback); + + network_context = nullptr; + run_loop.Run(); + + // On context destruction, should receive an ERR_FAILED result, and the + // internal resolver request should have been cancelled. + EXPECT_EQ(net::ERR_FAILED, response_client.result_error()); + EXPECT_FALSE(response_client.result_addresses()); + EXPECT_EQ(1, internal_resolver->num_cancellations()); + EXPECT_TRUE(control_handle_closed); + EXPECT_TRUE(resolver_closed); +} + TEST_F(NetworkContextTest, PrivacyModeDisabledByDefault) { std::unique_ptr<NetworkContext> network_context = CreateContextWithParams(CreateContextParams());
diff --git a/services/network/p2p/socket_manager.cc b/services/network/p2p/socket_manager.cc index 8b7e29d1..bde4835f 100644 --- a/services/network/p2p/socket_manager.cc +++ b/services/network/p2p/socket_manager.cc
@@ -250,8 +250,8 @@ return; } std::unique_ptr<P2PSocket> socket( - P2PSocket::Create(nullptr /*this*/, std::move(client), std::move(request), - type, url_request_context_->net_log(), + P2PSocket::Create(this, std::move(client), std::move(request), type, + url_request_context_->net_log(), proxy_resolving_socket_factory_.get(), &throttler_)); if (!socket)
diff --git a/services/network/proxy_resolver_factory_mojo_unittest.cc b/services/network/proxy_resolver_factory_mojo_unittest.cc index f1fd78bd..5f45c73 100644 --- a/services/network/proxy_resolver_factory_mojo_unittest.cc +++ b/services/network/proxy_resolver_factory_mojo_unittest.cc
@@ -489,7 +489,9 @@ // net::HostResolver overrides. std::unique_ptr<HostResolver::ResolveHostRequest> CreateRequest( const net::HostPortPair& host, - const net::NetLogWithSource& source_net_log) override { + const net::NetLogWithSource& source_net_log, + const base::Optional<ResolveHostParameters>& optional_parameters) + override { // TODO(crbug.com/821021): Implement. NOTIMPLEMENTED(); return nullptr;
diff --git a/services/network/public/mojom/host_resolver.mojom b/services/network/public/mojom/host_resolver.mojom index 93bda9ae..e059a41 100644 --- a/services/network/public/mojom/host_resolver.mojom +++ b/services/network/public/mojom/host_resolver.mojom
@@ -5,6 +5,7 @@ module network.mojom; import "net/interfaces/address_list.mojom"; +import "services/network/public/mojom/network_param.mojom"; // Control handle used to control outstanding NetworkContext::ResolveHost // requests. Handle is optional for all requests, and may be closed at any time @@ -30,5 +31,27 @@ OnComplete(int32 result, net.interfaces.AddressList? resolved_addresses); }; -// TODO(crbug.com/821021): Create a separate HostResolver interface, so host -// resolution can be done without direct access to NetworkContext. +// Interface that can be passed to code/processes without direct access to +// NetworkContext to make ResolveHost requests. If destroyed, all outstanding +// ResolveHost requests from the destroyed interface will be cancelled. +interface HostResolver { + // Resolves the given hostname (or IP address literal). Results are a network + // error code, and on success (network error code OK), an AddressList. All + // results are sent via the passed |response_client|. + // + // Results in ERR_NAME_NOT_RESOLVED if hostname is invalid, or if it is an + // incompatible IP literal (e.g. IPv6 is disabled and it is an IPv6 literal). + // + // If passed an optional |control_handle|, the outstanding request can be + // controlled, eg cancelled, via the handle. + // + // All outstanding requests are cancelled if the HostResolver or parent + // NetworkContext are destroyed. Such requests will receive ERR_FAILED via + // |response_client|. + // + // TODO(crbug.com/821021): Implement more complex functionality to meet full + // capabilities of Resolve() and DnsClient/MDnsClient functionality. + ResolveHost(HostPortPair host, + ResolveHostHandle&? control_handle, + ResolveHostClient response_client); +};
diff --git a/services/network/public/mojom/network_context.mojom b/services/network/public/mojom/network_context.mojom index 610f5bf..5694efe 100644 --- a/services/network/public/mojom/network_context.mojom +++ b/services/network/public/mojom/network_context.mojom
@@ -545,28 +545,30 @@ // used on URLLoaders. ResetURLLoaderFactories(); - // Resolves the given hostname (or IP address literal). All results are sent - // via the passed |response_client|. Results are a network error code, and on - // success (network error code OK), an AddressList. - // - // Results in ERR_NAME_NOT_RESOLVED if hostname is invalid, or if it is an - // incompatible IP literal (e.g. IPv6 is disabled and it is an IPv6 literal). - // - // If passed an optional |control_handle|, the outstanding request can be - // controlled, eg cancelled, via the handle. + // Resolves the given hostname (or IP address literal). See documentation at + // HostResolver::ResolveHost. // // All outstanding requests are cancelled if the NetworkContext is destroyed. // Such requests will receive ERR_FAILED via |response_client|. // - // TODO(crbug.com/821021): Implement more complex functionality to meet full - // capabilities of Resolve() and DnsClient/MDnsClient functionality. - // - // TODO(crbug.com/821021): Create (or move) a version of this API in some sort - // of separate (and possibly restrictable) HostResolver mojo interface that - // can be shared with processes without access to NetworkContext. - ResolveHost(HostPortPair host, - ResolveHostHandle&? control_handle, - ResolveHostClient response_client); + // TODO(crbug.com/821021): Consider deleting this if most/all usage goes + // through CreateHostResolver, but most likely most usage except proxy + // resolver will directly use this method. + ResolveHost(HostPortPair host, + ResolveHostHandle&? control_handle, + ResolveHostClient response_client); + + // Creates a HostResolver interface that can be passed to code/processes + // without direct access to NetworkContext to make ResolveHost requests. + // + // If this NetworkContext is destroyed, all outstanding requests from child + // HostResolvers will be cancelled. Such requests will receive ERR_FAILED via + // |response_client|. + // + // TODO(crbug.com/821021): If necessary as usage and functionality is added to + // the contained ResolveHost method, consider adding the ability for this to + // be a restricted resolver with some functionality disabled (eg maybe MDNS). + CreateHostResolver(HostResolver& host_resolver); [Sync] // Adds explicitly-specified data as if it was processed from an
diff --git a/services/network/public/mojom/network_service_test.mojom b/services/network/public/mojom/network_service_test.mojom index b2dbd7c..000451ba 100644 --- a/services/network/public/mojom/network_service_test.mojom +++ b/services/network/public/mojom/network_service_test.mojom
@@ -55,4 +55,7 @@ [Sync] SetShouldRequireCT(ShouldRequireCT required) => (); + + // Causes the next host resolve to the given hostname to crash the process. + CrashOnResolveHost(string host); };
diff --git a/services/network/resolve_host_request.cc b/services/network/resolve_host_request.cc index 04f58f09..eb4e055 100644 --- a/services/network/resolve_host_request.cc +++ b/services/network/resolve_host_request.cc
@@ -22,7 +22,8 @@ DCHECK(net_log); internal_request_ = resolver->CreateRequest( - host, net::NetLogWithSource::Make(net_log, net::NetLogSourceType::NONE)); + host, net::NetLogWithSource::Make(net_log, net::NetLogSourceType::NONE), + base::nullopt); } ResolveHostRequest::~ResolveHostRequest() {
diff --git a/services/network/session_cleanup_cookie_store.cc b/services/network/session_cleanup_cookie_store.cc index 548f78c3..7396b34 100644 --- a/services/network/session_cleanup_cookie_store.cc +++ b/services/network/session_cleanup_cookie_store.cc
@@ -52,9 +52,12 @@ persistent_store_->DeleteAllInList(session_only_cookies); } -void SessionCleanupCookieStore::Load(const LoadedCallback& loaded_callback) { - persistent_store_->Load(base::BindRepeating( - &SessionCleanupCookieStore::OnLoad, this, loaded_callback)); +void SessionCleanupCookieStore::Load(const LoadedCallback& loaded_callback, + const net::NetLogWithSource& net_log) { + persistent_store_->Load( + base::BindRepeating(&SessionCleanupCookieStore::OnLoad, this, + loaded_callback), + net_log); } void SessionCleanupCookieStore::LoadCookiesForKey(
diff --git a/services/network/session_cleanup_cookie_store.h b/services/network/session_cleanup_cookie_store.h index f3b422e..6c8b9456 100644 --- a/services/network/session_cleanup_cookie_store.h +++ b/services/network/session_cleanup_cookie_store.h
@@ -17,6 +17,7 @@ #include "base/memory/ref_counted.h" #include "net/cookies/cookie_monster.h" #include "net/extras/sqlite/sqlite_persistent_cookie_store.h" +#include "net/log/net_log_with_source.h" namespace net { class CanonicalCookie; @@ -43,7 +44,8 @@ const scoped_refptr<net::SQLitePersistentCookieStore>& cookie_store); // net::CookieMonster::PersistentCookieStore: - void Load(const LoadedCallback& loaded_callback) override; + void Load(const LoadedCallback& loaded_callback, + const net::NetLogWithSource& net_log) override; void LoadCookiesForKey(const std::string& key, const LoadedCallback& callback) override; void AddCookie(const net::CanonicalCookie& cc) override;
diff --git a/services/network/session_cleanup_cookie_store_unittest.cc b/services/network/session_cleanup_cookie_store_unittest.cc index e2afd9a..2d2791e 100644 --- a/services/network/session_cleanup_cookie_store_unittest.cc +++ b/services/network/session_cleanup_cookie_store_unittest.cc
@@ -39,9 +39,10 @@ CanonicalCookieVector Load() { base::RunLoop run_loop; CanonicalCookieVector cookies; - store_->Load(base::BindRepeating(&SessionCleanupCookieStoreTest::OnLoaded, - base::Unretained(this), &run_loop, - &cookies)); + store_->Load( + base::BindRepeating(&SessionCleanupCookieStoreTest::OnLoaded, + base::Unretained(this), &run_loop, &cookies), + net::NetLogWithSource()); run_loop.Run(); return cookies; }
diff --git a/services/network/ssl_config_service_mojo.cc b/services/network/ssl_config_service_mojo.cc index 36c6512..4fa16e5 100644 --- a/services/network/ssl_config_service_mojo.cc +++ b/services/network/ssl_config_service_mojo.cc
@@ -6,6 +6,7 @@ #include "base/strings/string_piece.h" #include "mojo/public/cpp/bindings/type_converter.h" +#include "services/network/cert_verifier_config_type_converter.h" #include "services/network/ssl_config_type_converter.h" namespace network { @@ -34,25 +35,44 @@ mojom::SSLConfigPtr initial_config, mojom::SSLConfigClientRequest ssl_config_client_request) : binding_(this), + client_cert_pooling_policy_( initial_config ? initial_config->client_cert_pooling_policy : std::vector<std::string>()) { - if (initial_config) + if (initial_config) { + cert_verifier_config_ = + mojo::ConvertTo<net::CertVerifier::Config>(initial_config->Clone()); ssl_config_ = mojo::ConvertTo<net::SSLConfig>(std::move(initial_config)); + } if (ssl_config_client_request) binding_.Bind(std::move(ssl_config_client_request)); } SSLConfigServiceMojo::~SSLConfigServiceMojo() = default; +void SSLConfigServiceMojo::SetCertVerifierForConfiguring( + net::CertVerifier* cert_verifier) { + cert_verifier_ = cert_verifier; + if (cert_verifier_) { + cert_verifier_->SetConfig(cert_verifier_config_); + } +} + void SSLConfigServiceMojo::OnSSLConfigUpdated(mojom::SSLConfigPtr ssl_config) { bool force_notification = client_cert_pooling_policy_ != ssl_config->client_cert_pooling_policy; client_cert_pooling_policy_ = ssl_config->client_cert_pooling_policy; net::SSLConfig old_config = ssl_config_; - ssl_config_ = mojo::ConvertTo<net::SSLConfig>(std::move(ssl_config)); + ssl_config_ = mojo::ConvertTo<net::SSLConfig>(ssl_config->Clone()); ProcessConfigUpdate(old_config, ssl_config_, force_notification); + + net::CertVerifier::Config old_cert_verifier_config = cert_verifier_config_; + cert_verifier_config_ = + mojo::ConvertTo<net::CertVerifier::Config>(std::move(ssl_config)); + if (cert_verifier_ && (old_cert_verifier_config != cert_verifier_config_)) { + cert_verifier_->SetConfig(cert_verifier_config_); + } } void SSLConfigServiceMojo::GetSSLConfig(net::SSLConfig* ssl_config) {
diff --git a/services/network/ssl_config_service_mojo.h b/services/network/ssl_config_service_mojo.h index 28bd7dc..8fee4bd 100644 --- a/services/network/ssl_config_service_mojo.h +++ b/services/network/ssl_config_service_mojo.h
@@ -7,6 +7,7 @@ #include "base/component_export.h" #include "mojo/public/cpp/bindings/binding.h" +#include "net/cert/cert_verifier.h" #include "net/ssl/ssl_config.h" #include "net/ssl/ssl_config_service.h" #include "services/network/public/mojom/ssl_config.mojom.h" @@ -25,6 +26,12 @@ mojom::SSLConfigClientRequest ssl_config_client_request); ~SSLConfigServiceMojo() override; + // Sets |cert_verifier| to be configured by certificate-related settings + // provided by the mojom::SSLConfigClient via OnSSLConfigUpdated. Once set, + // |cert_verifier| must outlive the SSLConfigServiceMojo or be cleared by + // passing nullptr as |cert_verifier| prior to destruction. + void SetCertVerifierForConfiguring(net::CertVerifier* cert_verifier); + // mojom::SSLConfigClient implementation: void OnSSLConfigUpdated(const mojom::SSLConfigPtr ssl_config) override; @@ -37,6 +44,9 @@ mojo::Binding<mojom::SSLConfigClient> binding_; net::SSLConfig ssl_config_; + net::CertVerifier::Config cert_verifier_config_; + + net::CertVerifier* cert_verifier_; // The list of domains and subdomains from enterprise policy where connection // coalescing is allowed when client certs are in use if the hosts being
diff --git a/services/network/ssl_config_service_mojo_unittest.cc b/services/network/ssl_config_service_mojo_unittest.cc index 1bd8f08..5e8a2e8 100644 --- a/services/network/ssl_config_service_mojo_unittest.cc +++ b/services/network/ssl_config_service_mojo_unittest.cc
@@ -8,6 +8,7 @@ #include "base/stl_util.h" #include "base/test/scoped_task_environment.h" #include "mojo/public/cpp/bindings/interface_request.h" +#include "net/cert/cert_verifier.h" #include "net/ssl/ssl_config.h" #include "net/ssl/ssl_config_service.h" #include "net/url_request/url_request_context.h" @@ -15,6 +16,7 @@ #include "services/network/network_service.h" #include "services/network/public/mojom/network_service.mojom.h" #include "services/network/public/mojom/ssl_config.mojom.h" +#include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" namespace network { @@ -72,12 +74,69 @@ std::unique_ptr<base::RunLoop> run_loop_; }; +class TestCertVerifierConfigObserver : public net::CertVerifier { + public: + TestCertVerifierConfigObserver() = default; + ~TestCertVerifierConfigObserver() override { + EXPECT_EQ(observed_changes_, changes_to_wait_for_); + } + + // CertVerifier implementation: + int Verify(const net::CertVerifier::RequestParams& params, + net::CRLSet* crl_set, + net::CertVerifyResult* verify_result, + net::CompletionOnceCallback callback, + std::unique_ptr<net::CertVerifier::Request>* out_req, + const net::NetLogWithSource& net_log) override { + ADD_FAILURE() << "Verify should not be called by tests"; + return net::ERR_FAILED; + } + void SetConfig(const Config& config) override { + ++observed_changes_; + verifier_config_during_change_ = config; + if (run_loop_) + run_loop_->Quit(); + } + + // Waits for a SSLConfig change. The first time it's called, waits for the + // first change, if one hasn't been observed already, the second time, waits + // for the second, etc. Must be called once for each change that happens, and + // fails it more than once change happens between calls, or during a call. + void WaitForChange() { + EXPECT_FALSE(run_loop_); + ++changes_to_wait_for_; + if (changes_to_wait_for_ == observed_changes_) + return; + EXPECT_LT(observed_changes_, changes_to_wait_for_); + + run_loop_ = std::make_unique<base::RunLoop>(); + run_loop_->Run(); + run_loop_.reset(); + EXPECT_EQ(observed_changes_, changes_to_wait_for_); + } + + const net::CertVerifier::Config& verifier_config_during_change() const { + return verifier_config_during_change_; + } + + int observed_changes() const { return observed_changes_; } + + private: + int observed_changes_ = 0; + int changes_to_wait_for_ = 0; + net::CertVerifier::Config verifier_config_during_change_; + std::unique_ptr<base::RunLoop> run_loop_; +}; + class NetworkServiceSSLConfigServiceTest : public testing::Test { public: NetworkServiceSSLConfigServiceTest() : scoped_task_environment_( base::test::ScopedTaskEnvironment::MainThreadType::IO), network_service_(NetworkService::CreateForTesting()) {} + ~NetworkServiceSSLConfigServiceTest() override { + NetworkContext::SetCertVerifierForTesting(nullptr); + } // Creates a NetworkContext using the specified NetworkContextParams, and // stores it in |network_context_|. @@ -143,6 +202,49 @@ observer.ssl_config_during_change(), expected_net_config)); } + // Runs two conversion tests for |mojo_config|. Uses it as an initial + // net::CertVerifier::Config for a NetworkContext, making sure it matches + // |expected_net_config|. Then switches to the default configuration and then + // back to |mojo_config|, to make sure it works as a new configuration. The + // expected configuration must not be the default configuration. + void RunCertConversionTests( + const mojom::SSLConfig& mojo_config, + const net::CertVerifier::Config& expected_net_config) { + TestCertVerifierConfigObserver observer; + NetworkContext::SetCertVerifierForTesting(&observer); + + EXPECT_NE(net::CertVerifier::Config(), expected_net_config); + + // Set up |mojo_config| as the initial configuration of a NetworkContext. + mojom::NetworkContextParamsPtr network_context_params = + mojom::NetworkContextParams::New(); + network_context_params->initial_ssl_config = mojo_config.Clone(); + SetUpNetworkContext(std::move(network_context_params)); + + // Make sure the initial configuration is set. + observer.WaitForChange(); + EXPECT_EQ(observer.verifier_config_during_change(), expected_net_config); + // Sanity check. + EXPECT_NE(observer.verifier_config_during_change(), + net::CertVerifier::Config()); + + // Reset the configuration to the default ones, and check the results. + ssl_config_client_->OnSSLConfigUpdated(mojom::SSLConfig::New()); + observer.WaitForChange(); + EXPECT_EQ(observer.verifier_config_during_change(), + net::CertVerifier::Config()); + // Sanity check. + EXPECT_NE(observer.verifier_config_during_change(), expected_net_config); + + // Set the configuration to |mojo_config| again, and check the results. + ssl_config_client_->OnSSLConfigUpdated(mojo_config.Clone()); + observer.WaitForChange(); + EXPECT_EQ(observer.verifier_config_during_change(), expected_net_config); + + // Reset the CertVerifier for subsequent invocations. + NetworkContext::SetCertVerifierForTesting(nullptr); + } + protected: base::test::ScopedTaskEnvironment scoped_task_environment_; std::unique_ptr<NetworkService> network_service_; @@ -180,56 +282,75 @@ EXPECT_EQ(net::kDefaultTLS13Variant, GetSSLConfig().tls13_variant); } +// Check that passing in the default mojom::SSLConfig matches the default +// net::CertVerifier::Config. +TEST_F(NetworkServiceSSLConfigServiceTest, DefaultCertConfig) { + TestCertVerifierConfigObserver observer; + NetworkContext::SetCertVerifierForTesting(&observer); + + mojom::NetworkContextParamsPtr network_context_params = + mojom::NetworkContextParams::New(); + network_context_params->initial_ssl_config = mojom::SSLConfig::New(); + SetUpNetworkContext(std::move(network_context_params)); + + observer.WaitForChange(); + + net::CertVerifier::Config default_config; + EXPECT_EQ(observer.verifier_config_during_change(), default_config); + + NetworkContext::SetCertVerifierForTesting(nullptr); +} + TEST_F(NetworkServiceSSLConfigServiceTest, RevCheckingEnabled) { - net::SSLConfig expected_net_config; + net::CertVerifier::Config expected_net_config; // Use the opposite of the default value. - expected_net_config.rev_checking_enabled = - !expected_net_config.rev_checking_enabled; + expected_net_config.enable_rev_checking = + !expected_net_config.enable_rev_checking; mojom::SSLConfigPtr mojo_config = mojom::SSLConfig::New(); - mojo_config->rev_checking_enabled = expected_net_config.rev_checking_enabled; + mojo_config->rev_checking_enabled = expected_net_config.enable_rev_checking; - RunConversionTests(*mojo_config, expected_net_config); + RunCertConversionTests(*mojo_config, expected_net_config); } TEST_F(NetworkServiceSSLConfigServiceTest, RevCheckingRequiredLocalTrustAnchors) { - net::SSLConfig expected_net_config; + net::CertVerifier::Config expected_net_config; // Use the opposite of the default value. - expected_net_config.rev_checking_required_local_anchors = - !expected_net_config.rev_checking_required_local_anchors; + expected_net_config.require_rev_checking_local_anchors = + !expected_net_config.require_rev_checking_local_anchors; mojom::SSLConfigPtr mojo_config = mojom::SSLConfig::New(); mojo_config->rev_checking_required_local_anchors = - expected_net_config.rev_checking_required_local_anchors; + expected_net_config.require_rev_checking_local_anchors; - RunConversionTests(*mojo_config, expected_net_config); + RunCertConversionTests(*mojo_config, expected_net_config); } TEST_F(NetworkServiceSSLConfigServiceTest, Sha1LocalAnchorsEnabled) { - net::SSLConfig expected_net_config; + net::CertVerifier::Config expected_net_config; // Use the opposite of the default value. - expected_net_config.sha1_local_anchors_enabled = - !expected_net_config.sha1_local_anchors_enabled; + expected_net_config.enable_sha1_local_anchors = + !expected_net_config.enable_sha1_local_anchors; mojom::SSLConfigPtr mojo_config = mojom::SSLConfig::New(); mojo_config->sha1_local_anchors_enabled = - expected_net_config.sha1_local_anchors_enabled; + expected_net_config.enable_sha1_local_anchors; - RunConversionTests(*mojo_config, expected_net_config); + RunCertConversionTests(*mojo_config, expected_net_config); } TEST_F(NetworkServiceSSLConfigServiceTest, SymantecEnforcementDisabled) { - net::SSLConfig expected_net_config; + net::CertVerifier::Config expected_net_config; // Use the opposite of the default value. - expected_net_config.symantec_enforcement_disabled = - !expected_net_config.symantec_enforcement_disabled; + expected_net_config.disable_symantec_enforcement = + !expected_net_config.disable_symantec_enforcement; mojom::SSLConfigPtr mojo_config = mojom::SSLConfig::New(); mojo_config->symantec_enforcement_disabled = - expected_net_config.symantec_enforcement_disabled; + expected_net_config.disable_symantec_enforcement; - RunConversionTests(*mojo_config, expected_net_config); + RunCertConversionTests(*mojo_config, expected_net_config); } TEST_F(NetworkServiceSSLConfigServiceTest, SSLVersion) {
diff --git a/services/network/ssl_config_type_converter.cc b/services/network/ssl_config_type_converter.cc index 556f22a..3ef67f43 100644 --- a/services/network/ssl_config_type_converter.cc +++ b/services/network/ssl_config_type_converter.cc
@@ -44,15 +44,6 @@ net::SSLConfig net_config; - net_config.rev_checking_enabled = mojo_config->rev_checking_enabled; - net_config.rev_checking_required_local_anchors = - mojo_config->rev_checking_required_local_anchors; - - net_config.sha1_local_anchors_enabled = - mojo_config->sha1_local_anchors_enabled; - net_config.symantec_enforcement_disabled = - mojo_config->symantec_enforcement_disabled; - net_config.version_min = MojoSSLVersionToNetSSLVersion(mojo_config->version_min); net_config.version_max =
diff --git a/services/network/test/test_network_context.h b/services/network/test/test_network_context.h index 826f3a6..9610378 100644 --- a/services/network/test/test_network_context.h +++ b/services/network/test/test_network_context.h
@@ -16,6 +16,7 @@ #include "net/base/ip_endpoint.h" #include "net/traffic_annotation/network_traffic_annotation.h" #include "services/network/public/mojom/cookie_manager.mojom.h" +#include "services/network/public/mojom/host_resolver.mojom.h" #include "services/network/public/mojom/network_service.mojom.h" #include "services/network/public/mojom/proxy_resolving_socket.mojom.h" #include "services/network/public/mojom/restricted_cookie_manager.mojom.h" @@ -107,6 +108,7 @@ void ResolveHost(const net::HostPortPair& host, mojom::ResolveHostHandleRequest control_handle, mojom::ResolveHostClientPtr response_client) override {} + void CreateHostResolver(mojom::HostResolverRequest request) override {} void AddHSTSForTesting(const std::string& host, base::Time expiry, bool include_subdomains,
diff --git a/services/service_manager/sandbox/linux/bpf_gpu_policy_linux.cc b/services/service_manager/sandbox/linux/bpf_gpu_policy_linux.cc index 0a07fdf..c2b81743 100644 --- a/services/service_manager/sandbox/linux/bpf_gpu_policy_linux.cc +++ b/services/service_manager/sandbox/linux/bpf_gpu_policy_linux.cc
@@ -55,29 +55,6 @@ case __NR_prctl: case __NR_sysinfo: return Allow(); -#if !defined(__aarch64__) - case __NR_access: - case __NR_open: -#endif // !defined(__aarch64__) - case __NR_faccessat: - case __NR_openat: -#if defined(__NR_stat) - case __NR_stat: -#endif -#if defined(__NR_stat64) - case __NR_stat64: -#endif -#if defined(__NR_fstatat) - case __NR_fstatat: -#endif -#if defined(__NR_newfstatat) - case __NR_newfstatat: -#endif - { - auto* broker_process = SandboxLinux::GetInstance()->broker_process(); - DCHECK(broker_process); - return Trap(BrokerProcess::SIGSYS_Handler, broker_process); - } case __NR_sched_getaffinity: case __NR_sched_setaffinity: return sandbox::RestrictSchedTarget(GetPolicyPid(), sysno); @@ -85,6 +62,11 @@ if (SyscallSets::IsEventFd(sysno)) return Allow(); + auto* broker_process = SandboxLinux::GetInstance()->broker_process(); + if (broker_process->IsSyscallAllowed(sysno)) { + return Trap(BrokerProcess::SIGSYS_Handler, broker_process); + } + // Default on the baseline policy. return BPFBasePolicy::EvaluateSyscall(sysno); }
diff --git a/services/service_manager/sandbox/linux/bpf_network_policy_linux.cc b/services/service_manager/sandbox/linux/bpf_network_policy_linux.cc index 49c378f..b7474d5 100644 --- a/services/service_manager/sandbox/linux/bpf_network_policy_linux.cc +++ b/services/service_manager/sandbox/linux/bpf_network_policy_linux.cc
@@ -33,70 +33,13 @@ NetworkProcessPolicy::~NetworkProcessPolicy() {} ResultExpr NetworkProcessPolicy::EvaluateSyscall(int sysno) const { - switch (sysno) { -#if defined(__NR_access) - case __NR_access: -#endif -#if defined(__NR_faccessat) - case __NR_faccessat: -#endif -#if defined(__NR_mkdir) - case __NR_mkdir: -#endif -#if defined(__NR_mkdirat) - case __NR_mkdirat: -#endif -#if defined(__NR_open) - case __NR_open: -#endif -#if defined(__NR_openat) - case __NR_openat: -#endif -#if defined(__NR_readlink) - case __NR_readlink: -#endif -#if defined(__NR_readlinkat) - case __NR_readlinkat: -#endif -#if defined(__NR_rmdir) - case __NR_rmdir: -#endif -#if defined(__NR_rename) - case __NR_rename: -#endif -#if defined(__NR_renameat) - case __NR_renameat: -#endif -#if defined(__NR_stat) - case __NR_stat: -#endif -#if defined(__NR_stat64) - case __NR_stat64: -#endif -#if defined(__NR_lstat) - case __NR_lstat: -#endif -#if defined(__NR_lstat64) - case __NR_lstat64: -#endif -#if defined(__NR_fstatat) - case __NR_fstatat: -#endif -#if defined(__NR_newfstatat) - case __NR_newfstatat: -#endif -#if defined(__NR_unlink) - case __NR_unlink: -#endif -#if defined(__NR_unlinkat) - case __NR_unlinkat: -#endif - return Trap(BrokerProcess::SIGSYS_Handler, - SandboxLinux::GetInstance()->broker_process()); - default: - // TODO(tsepez): FIX this. - return Allow(); + auto* broker_process = SandboxLinux::GetInstance()->broker_process(); + if (broker_process->IsSyscallAllowed(sysno)) { + return Trap(BrokerProcess::SIGSYS_Handler, broker_process); } + + // TODO(tsepez): FIX this. + return Allow(); } } // namespace service_manager
diff --git a/services/ui/ws2/server_window.cc b/services/ui/ws2/server_window.cc index b3daa28..da35c726 100644 --- a/services/ui/ws2/server_window.cc +++ b/services/ui/ws2/server_window.cc
@@ -471,7 +471,7 @@ if (!IsTopLevel()) return; - return static_cast<TopLevelEventHandler*>(event_handler_.get()) + static_cast<TopLevelEventHandler*>(event_handler_.get()) ->OnCaptureOwnerChanged(); }
diff --git a/styleguide/java/java.md b/styleguide/java/java.md index 7b8b2ef7..62647ecbc 100644 --- a/styleguide/java/java.md +++ b/styleguide/java/java.md
@@ -58,6 +58,22 @@ } ``` +* Avoid adding messages to exceptions that do not aid in debugging. + +For example: +```java +try { + somethingThatThrowsIOException(); +} catch (IOException e) { + // Bad - message does not tell you more than the stack trace does: + throw new RuntimeException("Failed to parse a file.", e); + // Good - conveys that this block failed along with the "caused by" exception. + throw new RuntimeException(e); + // Good - adds useful information. + throw new RuntimeException(String.format("Failed to parse %s", fileName), e); +} +``` + ### Logging * Use `org.chromium.base.Log` instead of `android.util.Log`. * It provides `%s` support, and ensures log stripping works correctly.
diff --git a/testing/buildbot/chromium.clang.json b/testing/buildbot/chromium.clang.json index c346162e..5ba2e05 100644 --- a/testing/buildbot/chromium.clang.json +++ b/testing/buildbot/chromium.clang.json
@@ -1,702 +1,6 @@ { "AAAAA1 AUTOGENERATED FILE DO NOT EDIT": {}, "AAAAA2 See generate_buildbot_json.py to make changes": {}, - "CFI Linux (icall)": { - "gtest_tests": [ - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "accessibility_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "angle_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "app_shell_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "aura_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "base_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "blink_common_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "blink_fuzzer_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "blink_heap_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "blink_platform_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "boringssl_crypto_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "boringssl_ssl_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true, - "shards": 10 - }, - "test": "browser_tests" - }, - { - "args": [ - "--enable-features=NetworkService", - "--test-launcher-filter-file=../../testing/buildbot/filters/mojo.fyi.network_browser_tests.filter" - ], - "name": "network_service_browser_tests", - "swarming": { - "can_use_on_swarming_builders": true, - "shards": 15 - }, - "test": "browser_tests" - }, - { - "args": [ - "--enable-features=VizDisplayCompositor" - ], - "name": "viz_browser_tests", - "swarming": { - "can_use_on_swarming_builders": true, - "shards": 10 - }, - "test": "browser_tests" - }, - { - "args": [ - "--enable-features=WebUIPolymer2", - "--test-launcher-filter-file=../../testing/buildbot/filters/webui_polymer2_browser_tests.filter" - ], - "name": "webui_polymer2_browser_tests", - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "browser_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "cacheinvalidation_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "capture_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "cast_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "cc_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "chrome_app_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "chromedriver_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "components_browsertests" - }, - { - "args": [ - "--enable-features=NetworkService" - ], - "name": "network_service_components_browsertests", - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "components_browsertests" - }, - { - "args": [ - "--disable-site-isolation-trials" - ], - "name": "not_site_per_process_components_browsertests", - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "components_browsertests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "components_unittests" - }, - { - "args": [ - "--disable-site-isolation-trials" - ], - "name": "not_site_per_process_components_unittests", - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "components_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "compositor_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "content_browsertests" - }, - { - "args": [ - "--enable-features=NetworkService", - "--test-launcher-filter-file=../../testing/buildbot/filters/mojo.fyi.network_content_browsertests.filter" - ], - "name": "network_service_content_browsertests", - "swarming": { - "can_use_on_swarming_builders": true, - "shards": 2 - }, - "test": "content_browsertests" - }, - { - "args": [ - "--disable-site-isolation-trials" - ], - "name": "not_site_per_process_content_browsertests", - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "content_browsertests" - }, - { - "args": [ - "--enable-features=TracingPerfettoBackend", - "--gtest_filter=TracingControllerTest.*" - ], - "name": "perfetto_content_browsertests", - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "content_browsertests" - }, - { - "args": [ - "--enable-features=VizDisplayCompositor" - ], - "name": "viz_content_browsertests", - "swarming": { - "can_use_on_swarming_builders": true, - "shards": 10 - }, - "test": "content_browsertests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "content_unittests" - }, - { - "args": [ - "--disable-site-isolation-trials" - ], - "name": "not_site_per_process_content_unittests", - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "content_unittests" - }, - { - "args": [ - "--enable-features=VizDisplayCompositor" - ], - "name": "viz_content_unittests", - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "content_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "cronet_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "cronet_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "crypto_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "dbus_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "device_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "display_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "events_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "extensions_browsertests" - }, - { - "args": [ - "--enable-features=NetworkService" - ], - "name": "network_service_extensions_browsertests", - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "extensions_browsertests" - }, - { - "args": [ - "--disable-site-isolation-trials" - ], - "name": "not_site_per_process_extensions_browsertests", - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "extensions_browsertests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "extensions_unittests" - }, - { - "args": [ - "--disable-site-isolation-trials" - ], - "name": "not_site_per_process_extensions_unittests", - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "extensions_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "filesystem_service_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "gcm_unit_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "gfx_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "gin_unittests" - }, - { - "args": [ - "--use-gpu-in-tests", - "--no-xvfb" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "10de:1cb3", - "os": "Ubuntu", - "pool": "Chrome-GPU" - } - ] - }, - "test": "gl_unittests", - "use_xvfb": false - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "google_apis_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "gpu_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "headless_browsertests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "headless_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true, - "shards": 3 - }, - "test": "interactive_ui_tests" - }, - { - "args": [ - "--enable-features=NetworkService" - ], - "name": "network_service_interactive_ui_tests", - "swarming": { - "can_use_on_swarming_builders": true, - "shards": 3 - }, - "test": "interactive_ui_tests" - }, - { - "args": [ - "--enable-features=WebUIPolymer2", - "--test-launcher-filter-file=../../testing/buildbot/filters/webui_polymer2_interactive_ui_tests.filter" - ], - "name": "webui_polymer2_interactive_ui_tests", - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "interactive_ui_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "ipc_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "jingle_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "latency_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "leveldb_service_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "libjingle_xmpp_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "media_blink_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "media_service_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "media_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "message_center_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "midi_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "mojo_core_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "mojo_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "nacl_helper_nonsfi_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "nacl_loader_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "native_theme_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "net_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "pdf_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "ppapi_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "printing_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "remoting_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "sandbox_linux_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "service_manager_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "services_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "shell_dialogs_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "skia_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "snapshot_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "sql_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "storage_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "sync_integration_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "traffic_annotation_auditor_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "ui_base_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "ui_touch_selection_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "unit_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "url_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "views_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "viz_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "vr_common_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "vr_pixeltests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "webkit_unit_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "wm_unittests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "wtf_unittests" - } - ] - }, "CFI Linux ToT": { "gtest_tests": [ {
diff --git a/testing/buildbot/chromium.mac.json b/testing/buildbot/chromium.mac.json index 1c52c44..1eab7c7 100644 --- a/testing/buildbot/chromium.mac.json +++ b/testing/buildbot/chromium.mac.json
@@ -2997,6 +2997,7 @@ { "alternate_swarming_dimensions": [ { + "gpu": "8086:0a2e", "os": "Mac-10.12.6" } ],
diff --git a/testing/buildbot/filters/mojo.fyi.network_browser_tests.filter b/testing/buildbot/filters/mojo.fyi.network_browser_tests.filter index 591ee4da..b4b6af9 100644 --- a/testing/buildbot/filters/mojo.fyi.network_browser_tests.filter +++ b/testing/buildbot/filters/mojo.fyi.network_browser_tests.filter
@@ -185,6 +185,9 @@ # Requires checking Origin headers on requests made after extension unload. -ExtensionUnloadBrowserTest.UnloadWithContentScripts +# https://crbug.com/721403 +-ContextMenuBrowserTest.DataSaverOpenOrigImageInNewTab + # NOTE: if adding an exclusion for an existing failure (e.g. additional test for # feature X that is already not working), please add it beside the existing # failures. Otherwise please reach out to network-service-dev@.
diff --git a/testing/buildbot/filters/webui_polymer2_browser_tests.filter b/testing/buildbot/filters/webui_polymer2_browser_tests.filter index 8113fc8..2d49544 100644 --- a/testing/buildbot/filters/webui_polymer2_browser_tests.filter +++ b/testing/buildbot/filters/webui_polymer2_browser_tests.filter
@@ -40,6 +40,11 @@ -PrintPreviewDestinationListTest.FireDestinationSelected -SettingsAdvancedPageBrowserTest.Load +# Tests that fail only on official builds. +-CrSettingsChromeCleanupPageTest.All +-CrSettingsIncompatibleApplicationsPageTest.All +-CrSettingsMetricsReportingTest.All + # Most of the a11y tests are failing because they use /deep/. Should be # addressed as part of crbug.com/860069 -CrExtensionsA11yTest.* @@ -175,7 +180,6 @@ CrSettingsCertificateManagerTest.* CrSettingsChangePasswordPageTest.* CrSettingsCheckboxTest.* -CrSettingsChromeCleanupPageTest.* CrSettingsDateTimePageTest.* CrSettingsDefaultBrowserTest.* CrSettingsDevicePageTest.DevicePageTest @@ -192,10 +196,8 @@ CrSettingsFocusRowBehavior.* CrSettingsGoogleAssistantPageTest.* CrSettingsImportDataDialogTest.* -CrSettingsIncompatibleApplicationsPageTest.* CrSettingsLanguagesPageTest.InputMethods CrSettingsLanguagesTest.* -CrSettingsMetricsReportingTest.* CrSettingsMultideviceFeatureItemTest.* CrSettingsMultideviceFeatureToggleTest.* CrSettingsMultidevicePageTest.*
diff --git a/testing/buildbot/filters/webui_polymer2_interactive_ui_tests.filter b/testing/buildbot/filters/webui_polymer2_interactive_ui_tests.filter index 30424562..55fd583a 100644 --- a/testing/buildbot/filters/webui_polymer2_interactive_ui_tests.filter +++ b/testing/buildbot/filters/webui_polymer2_interactive_ui_tests.filter
@@ -22,3 +22,15 @@ -CrElementsActionMenuTest.All -CrElementsInputTest.All -MaterialBookmarksFocusTest.All + +# TODO(rbpotter): The following tests are flaky on debug builds. Fix them and +# remove these exclusions. +-CrElementsCheckboxTest.All +-CrElementsProfileAvatarSelectorFocusTest.All +-CrElementsToggleTest.All +-CrSettingsAnimatedPagesTest.All +-CrSettingsFocusRowBehavior.FocusTest +-CrSettingsSyncPageTest.All +-MaterialHistoryFocusTest.All +-PrintPreviewDestinationDialogInteractiveTest.FocusSearchBox +-PrintPreviewPrintHeaderInteractiveTest.FocusPrintOnReady
diff --git a/testing/buildbot/test_suite_exceptions.pyl b/testing/buildbot/test_suite_exceptions.pyl index 43917d1..1571c1c 100644 --- a/testing/buildbot/test_suite_exceptions.pyl +++ b/testing/buildbot/test_suite_exceptions.pyl
@@ -513,7 +513,6 @@ 'gl_tests': { 'remove_from': [ # chromium.clang - 'CFI Linux (icall)', 'CFI Linux ToT', # chromium.gpu.fyi 'Android FYI Release (Nexus 5X)', @@ -603,22 +602,6 @@ ], 'modifications': { # chromium.clang - 'CFI Linux (icall)': { - 'args': [ - '--use-gpu-in-tests', - '--no-xvfb', - ], - 'swarming': { - 'dimension_sets': [ - { - 'gpu': '10de:1cb3', - 'os': 'Ubuntu', - 'pool': 'Chrome-GPU', - }, - ], - }, - 'use_xvfb': False, - }, 'CFI Linux ToT': { 'args': [ '--use-gpu-in-tests', @@ -1641,6 +1624,7 @@ # TODO(crbug.com/853356): Switch this to 10.13. 'use_multi_dimension_trigger_script': True, 'alternate_swarming_dimensions': [{ + 'gpu': '8086:0a2e', 'os': 'Mac-10.12.6', }],
diff --git a/testing/buildbot/waterfalls.pyl b/testing/buildbot/waterfalls.pyl index 9e820f2..8d57650 100644 --- a/testing/buildbot/waterfalls.pyl +++ b/testing/buildbot/waterfalls.pyl
@@ -507,11 +507,6 @@ { 'name': 'chromium.clang', 'machines': { - 'CFI Linux (icall)': { - 'test_suites': { - 'gtest_tests': 'chromium_linux_and_gl_gtests', - }, - }, 'CFI Linux ToT': { 'test_suites': { 'gtest_tests': 'chromium_linux_and_gl_gtests',
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index bd20cbb1..4a8a315 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -1251,6 +1251,25 @@ ] } ], + "DataSaverSiteBreakdownUsingPageLoadMetrics": [ + { + "platforms": [ + "android", + "windows", + "mac", + "chromeos", + "linux" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "DataSaverSiteBreakdownUsingPageLoadMetrics" + ] + } + ] + } + ], "DecoupleTranslateLanguage": [ { "platforms": [
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG index 3530de9..c3d9e7d 100644 --- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG +++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG
@@ -359,7 +359,6 @@ crbug.com/591099 fast/borders/bidi-002.html [ Failure ] crbug.com/859497 fast/borders/bidi-009a.html [ Failure ] crbug.com/591099 fast/borders/inline-mask-overlay-image-outset-vertical-rl.html [ Failure ] -crbug.com/591099 fast/box-shadow/box-shadow.html [ Failure ] crbug.com/591099 fast/box-sizing/replaced.html [ Failure ] crbug.com/591099 fast/css-generated-content/first-letter-next-sibling-crash.html [ Crash ] crbug.com/591099 fast/css-generated-content/float-first-letter-siblings-convert-to-inline.html [ Crash ] @@ -454,8 +453,6 @@ crbug.com/591099 idle-callback/test-runner-run-idle-tasks.html [ Crash Pass Timeout ] crbug.com/714962 images/color-profile-background-clip-text.html [ Failure ] crbug.com/591099 images/color-profile-image-filter-all.html [ Failure ] -crbug.com/591099 images/color-profile-munsell-adobe-to-srgb.html [ Failure ] -crbug.com/591099 images/feature-policy-max-downscaling-image-edge-cases.html [ Failure ] crbug.com/714962 inspector-protocol/css/css-get-platform-fonts.js [ Failure ] crbug.com/591099 inspector-protocol/dom-snapshot/dom-snapshot-getSnapshot-pseudo-element.js [ Failure ] crbug.com/714962 inspector-protocol/dom-snapshot/dom-snapshot-getSnapshot-viewport.js [ Failure ] @@ -554,8 +551,6 @@ crbug.com/591099 virtual/exotic-color-space/ [ Skip ] crbug.com/591099 virtual/feature-policy-vibrate/ [ Skip ] crbug.com/591099 virtual/gpu-rasterization/images/color-profile-image-filter-all.html [ Failure ] -crbug.com/591099 virtual/gpu-rasterization/images/color-profile-munsell-adobe-to-srgb.html [ Failure ] -crbug.com/591099 virtual/gpu-rasterization/images/feature-policy-max-downscaling-image-edge-cases.html [ Failure ] crbug.com/591099 virtual/gpu/fast/canvas/canvas-blending-color-over-image.html [ Pass ] crbug.com/591099 virtual/gpu/fast/canvas/canvas-blending-gradient-over-pattern.html [ Pass Timeout ] crbug.com/591099 virtual/intersection-observer-v2/http/tests/intersection-observer/v2/cross-origin-effects.html [ Failure ]
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-gen-property-trees b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-gen-property-trees index 15e4215..1a61bb3 100644 --- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-gen-property-trees +++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-gen-property-trees
@@ -154,16 +154,23 @@ # These scrollbar tests should pass. Bug(none) virtual/prefer_compositing_to_lcd_text/scrollbars/ [ Pass ] -crbug.com/836912 compositing/rtl/rtl-absolute-overflow.html [ Failure ] -crbug.com/836912 compositing/rtl/rtl-and-writing-mode-scrolling.html [ Failure ] -crbug.com/836912 compositing/rtl/rtl-fixed-overflow.html [ Failure ] -crbug.com/836912 compositing/rtl/rtl-iframe-absolute-overflow.html [ Failure ] -crbug.com/836912 compositing/rtl/rtl-iframe-fixed-overflow.html [ Failure ] -crbug.com/836912 compositing/rtl/rtl-overflow-invalidation.html [ Failure ] -crbug.com/836912 compositing/scrollbars/nested-overlay-scrollbars.html [ Failure ] -crbug.com/836912 compositing/squashing/vertical-writing-mode-squashed.html [ Failure ] +crbug.com/836890 compositing/rtl/rtl-absolute-overflow.html [ Failure ] +crbug.com/836890 compositing/rtl/rtl-and-writing-mode-scrolling.html [ Failure ] +crbug.com/836890 compositing/rtl/rtl-fixed-overflow.html [ Failure ] +crbug.com/836890 compositing/rtl/rtl-iframe-absolute-overflow.html [ Failure ] +crbug.com/836890 compositing/rtl/rtl-iframe-fixed-overflow.html [ Failure ] +crbug.com/836890 compositing/rtl/rtl-overflow-invalidation.html [ Failure ] +crbug.com/836890 compositing/rtl/rtl-absolute-overflow-scrolled.html [ Failure ] +crbug.com/836890 fast/dom/rtl-scroll-to-leftmost-and-resize.html [ Failure ] +crbug.com/836890 fast/events/wheel/wheelevent-in-horizontal-scrollbar-in-rtl.html [ Failure ] +crbug.com/836890 fast/events/wheel/wheelevent-in-vertical-scrollbar-in-rtl.html [ Failure ] +crbug.com/836890 paint/invalidation/scroll/document-flipped-blocks-writing-mode-scroll.html [ Failure ] +crbug.com/836890 virtual/user-activation-v2/fast/events/wheel/wheelevent-in-horizontal-scrollbar-in-rtl.html [ Failure ] +crbug.com/836890 virtual/user-activation-v2/fast/events/wheel/wheelevent-in-vertical-scrollbar-in-rtl.html [ Failure ] +crbug.com/836890 compositing/squashing/vertical-writing-mode-squashed.html [ Failure ] +crbug.com/836890 paint/overflow/composited-scroll-vertical-rl.html [ Failure ] crbug.com/836912 compositing/squashing/no-squashing-into-another-clip-layer.html [ Pass Failure ] -crbug.com/836912 paint/overflow/composited-scroll-vertical-rl.html [ Failure ] +crbug.com/836912 compositing/scrollbars/nested-overlay-scrollbars.html [ Failure ] # These scrolling tests should pass. Bug(none) virtual/threaded/ [ Pass ]
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations index 00f48a2..f3888ae 100644 --- a/third_party/WebKit/LayoutTests/TestExpectations +++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -1765,7 +1765,7 @@ crbug.com/771233 [ Win10 ] http/tests/devtools/audits2/ [ Skip ] -crbug.com/865477 [ Mac ] virtual/gpu/fast/canvas/OffscreenCanvas-commit-copyImage.html [ Failure ] +crbug.com/865477 [ Mac ] virtual/gpu/fast/canvas/OffscreenCanvas-copyImage.html [ Failure ] crbug.com/410974 fast/scroll-behavior/scroll-customization/scrollstate-basic.html [ Pass Failure ] crbug.com/410974 fast/scroll-behavior/scroll-customization/scrollstate-consume-deltas.html [ Pass Failure ] @@ -3920,9 +3920,11 @@ # Sheriff failures 2018-08-15 crbug.com/873435 [ Mac ] fast/events/middleClickAutoscroll-in-iframe.html [ Timeout Pass ] crbug.com/869726 [ Mac ] fast/events/touch/touch-latched-scroll-node-removed.html [ Pass Failure ] +crbug.com/869726 [ Mac ] virtual/user-activation-v2/fast/events/touch/touch-latched-scroll-node-removed.html [ Pass Failure ] crbug.com/869726 [ Mac ] fast/events/wheel/wheel-latched-scroll-node-removed.html [ Pass Failure ] crbug.com/874444 [ Linux ] external/wpt/fullscreen/api/element-request-fullscreen-two-elements-manual.html [ Pass Failure ] crbug.com/874500 [ Mac ] media/media-ended.html [ Pass Timeout ] +crbug.com/874567 [ Mac ] svg/custom/getscreenctm-in-scrollable-div-area-nested.xhtml [ Pass Failure ] crbug.com/715718 external/wpt/media-source/mediasource-activesourcebuffers.html [ Failure Pass ] crbug.com/715718 external/wpt/media-source/mediasource-remove.html [ Failure Pass ] @@ -4919,7 +4921,6 @@ crbug.com/872705 [ Mac ] virtual/mouseevent_fractional/fast/events/recorded-keydown-event.html [ Timeout Pass ] # Sheriff 2018-08-10 -crbug.com/873078 [ Win7 ] device_orientation/motion/detached-frame.html [ Failure Pass ] crbug.com/872705 [ Mac ] virtual/mouseevent_fractional/fast/events/middleClickAutoscroll-click.html [ Timeout Pass ] # Sheriff 2018-08-13
diff --git a/third_party/WebKit/LayoutTests/compositing/copy-image-when-no-image-exists.html b/third_party/WebKit/LayoutTests/compositing/copy-image-when-no-image-exists.html deleted file mode 100644 index 56cd6bb..0000000 --- a/third_party/WebKit/LayoutTests/compositing/copy-image-when-no-image-exists.html +++ /dev/null
@@ -1,49 +0,0 @@ -<!-- This test checks copyImageAt() with position parameter - that actually doesn't point to an Image(Canvas). - (Negative test for crbug.com/392765) --> -<head> -<script src="../resources/js-test.js"></script> -<script> - -function main() -{ - if (!window.testRunner) { - testFailed("Requires window.testRunner"); - } else { - testRunner.waitUntilDone(); - testRunner.dumpAsText(); - window.requestAnimationFrame(runTest); - } -} - -function runTest() { - try { - testRunner.copyImageAtAndCapturePixelsAsyncThen(50, 50, completionCallback); - } catch (e) { - debug('error in runTest'); - debug(e); - testRunner.notifyDone(); - } -} -var width, height; -function completionCallback(w, h, snapshot) { - try { - width = w; - height = h; - shouldBeEqualToNumber("width", 0); - shouldBeEqualToNumber("height", 0); - } catch (e) { - debug('error in completionCallback'); - debug(e); - testRunner.notifyDone(); - return; - } - testRunner.notifyDone(); -} - -main(); -</script> -</head> -<body> -<div id="console"></div> -</body>
diff --git a/third_party/WebKit/LayoutTests/device_orientation/motion/add-child-listener.html b/third_party/WebKit/LayoutTests/device_orientation/motion/add-child-listener.html new file mode 100644 index 0000000..c67ef30 --- /dev/null +++ b/third_party/WebKit/LayoutTests/device_orientation/motion/add-child-listener.html
@@ -0,0 +1,18 @@ +<!DOCTYPE html> +<html> +<body> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> +<script> +'use strict'; + +test(function() { + var childFrame = document.createElement('iframe'); + document.body.appendChild(childFrame); + let childWindow = childFrame.contentWindow; + document.body.removeChild(childFrame); + childWindow.addEventListener('devicemotion', function() {}); +}, 'Tests that an event listener can be safely added to a child frame that has been detached from the parent.'); +</script> +</body> +</html>
diff --git a/third_party/WebKit/LayoutTests/device_orientation/motion/detached-frame.html b/third_party/WebKit/LayoutTests/device_orientation/motion/detached-frame.html deleted file mode 100644 index d25ecf52..0000000 --- a/third_party/WebKit/LayoutTests/device_orientation/motion/detached-frame.html +++ /dev/null
@@ -1,38 +0,0 @@ -<!DOCTYPE html> -<html> -<body> -<script src="../../resources/testharness.js"></script> -<script src="../../resources/testharnessreport.js"></script> -<script src="../../http/tests/resources/sensor-helpers.js"></script> -<script src="../resources/device-orientation-helpers.js"></script> -<script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script> -<script src="file:///gen/services/device/public/mojom/sensor_provider.mojom.js"></script> -<script> -'use strict'; - -sensor_test(async sensorProvider => { - const motionData = generateMotionData(1, 2, 3, - 4, 5, 6, - 7, 8, 9); - - setMockMotionData(sensorProvider, motionData); - await waitForMotion(motionData); - var childFrame = document.createElement('iframe'); - document.body.appendChild(childFrame); - - return new Promise((resolve, reject) => { - childFrame.contentWindow.addEventListener('devicemotion', event1 => { - checkMotion(event1, motionData); - document.body.removeChild(childFrame); - setTimeout(() => { - window.addEventListener('devicemotion', event2 => { - checkMotion(event2, motionData); - resolve(); - }); - }, 300); - }); - }); -}, 'Tests adding a devicemotion event listener in an iframe, removing the iframe, and then adding a devicemotion event listener in the main frame.'); -</script> -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/device_orientation/motion/fire-last-event.html b/third_party/WebKit/LayoutTests/device_orientation/motion/fire-last-event.html deleted file mode 100644 index 17e0ed8..0000000 --- a/third_party/WebKit/LayoutTests/device_orientation/motion/fire-last-event.html +++ /dev/null
@@ -1,35 +0,0 @@ -<!DOCTYPE html> -<html> -<body> -<script src="../../resources/testharness.js"></script> -<script src="../../resources/testharnessreport.js"></script> -<script src="../../http/tests/resources/sensor-helpers.js"></script> -<script src="../resources/device-orientation-helpers.js"></script> -<script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script> -<script src="file:///gen/services/device/public/mojom/sensor_provider.mojom.js"></script> -<script> -'use strict'; - -sensor_test(async sensorProvider => { - const motionData1 = generateMotionData(1, 2, 3, - 4, 5, 6, - 7, 8, 9); - const motionData2 = generateMotionData(0, 0, 0, - 0, 0, 0, - 0, 0, 0); - - return new Promise((resolve, reject) => { - setMockMotionData(sensorProvider, motionData1); - window.addEventListener('devicemotion', function mainFrameListener(event) { - checkMotion(event, motionData1); - var childFrame = document.createElement('iframe'); - document.body.appendChild(childFrame); - window.removeEventListener('devicemotion', mainFrameListener); - setMockMotionData(sensorProvider, motionData2); - waitForMotion(motionData1, childFrame.contentWindow).then(resolve, reject); - }); - }); -}, 'Tests to see if the last available event is fired.'); -</script> -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/device_orientation/motion/multiple-event-listeners.html b/third_party/WebKit/LayoutTests/device_orientation/motion/multiple-event-listeners.html index d157644..11c507a7 100644 --- a/third_party/WebKit/LayoutTests/device_orientation/motion/multiple-event-listeners.html +++ b/third_party/WebKit/LayoutTests/device_orientation/motion/multiple-event-listeners.html
@@ -33,11 +33,6 @@ // At this point only the first event listener is active. setMockMotionData(sensorProvider, motionData2); - let childFrame = document.createElement('iframe'); - document.body.appendChild(childFrame); - // Expect the cached event because Device Motion was already active - // when third listener was added. - await waitForMotion(motionData1, childFrame.contentWindow); window.removeEventListener('devicemotion', firstListener); return waitForMotion(motionData2);
diff --git a/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json b/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json index 12c201e2..0821e098 100644 --- a/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json +++ b/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json
@@ -155900,6 +155900,11 @@ {} ] ], + "html/semantics/embedded-content/the-iframe-element/src-repeated-in-ancestor-expected.txt": [ + [ + {} + ] + ], "html/semantics/embedded-content/the-iframe-element/stash.py": [ [ {} @@ -221015,6 +221020,12 @@ {} ] ], + "html/semantics/embedded-content/the-iframe-element/src-repeated-in-ancestor.html": [ + [ + "/html/semantics/embedded-content/the-iframe-element/src-repeated-in-ancestor.html", + {} + ] + ], "html/semantics/embedded-content/the-img-element/Image-constructor.html": [ [ "/html/semantics/embedded-content/the-img-element/Image-constructor.html", @@ -221149,6 +221160,12 @@ {} ] ], + "html/semantics/embedded-content/the-img-element/null-image-source.html": [ + [ + "/html/semantics/embedded-content/the-img-element/null-image-source.html", + {} + ] + ], "html/semantics/embedded-content/the-img-element/relevant-mutations.html": [ [ "/html/semantics/embedded-content/the-img-element/relevant-mutations.html", @@ -373950,6 +373967,14 @@ "fab9aa4f18b1276ad94f63626ed582599aad1a8e", "testharness" ], + "html/semantics/embedded-content/the-iframe-element/src-repeated-in-ancestor-expected.txt": [ + "11e1d076ece2204072bb3099c20d8519274b7709", + "support" + ], + "html/semantics/embedded-content/the-iframe-element/src-repeated-in-ancestor.html": [ + "09b3c11fbca43838041154993d7c257f0a3006b3", + "testharness" + ], "html/semantics/embedded-content/the-iframe-element/stash.py": [ "5513229f79ab37de67eb4d60ea9dd23cd31d133f", "support" @@ -374262,6 +374287,10 @@ "3752b0f4f5b31ca0bf55b99a400dd8cd7a12b8a7", "testharness" ], + "html/semantics/embedded-content/the-img-element/null-image-source.html": [ + "b588c43d99a64307d1fec28f8e61afef0ee1967b", + "testharness" + ], "html/semantics/embedded-content/the-img-element/relevant-mutations.html": [ "3b4171a783f97facca39bcc342df253597876412", "testharness" @@ -408583,7 +408612,7 @@ "support" ], "svg/render/reftests/blending-001.svg": [ - "5503dc3d96e7fa0c5884f6692469010fe28e4527", + "76013506ad689302596acfee7d420b8c0cbc201c", "reftest" ], "svg/render/reftests/blending-002-ref.svg": [ @@ -408591,7 +408620,7 @@ "support" ], "svg/render/reftests/blending-002.svg": [ - "f77800e686cee3007fb7c40574c61b22d65217ef", + "81ad9070df5d218686df0c2f9816525d2441eab9", "reftest" ], "svg/render/reftests/blending-svg-foreign-object-ref.html": [
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/the-iframe-element/src-repeated-in-ancestor-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/the-iframe-element/src-repeated-in-ancestor-expected.txt new file mode 100644 index 0000000..e97bed39 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/the-iframe-element/src-repeated-in-ancestor-expected.txt
@@ -0,0 +1,7 @@ +This is a testharness.js-based test. +PASS different path name +FAIL same path name, no document fragment assert_unreached: Should not navigate Reached unreachable code +FAIL same path name, different document fragment assert_unreached: Should not navigate Reached unreachable code +FAIL same path name, no document fragement (intermediary browsing context) assert_unreached: Should not navigate Reached unreachable code +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/the-iframe-element/src-repeated-in-ancestor.html b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/the-iframe-element/src-repeated-in-ancestor.html new file mode 100644 index 0000000..2f77dfe --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/the-iframe-element/src-repeated-in-ancestor.html
@@ -0,0 +1,138 @@ +<!doctype html> +<meta charset="utf-8"> +<title>Navigation should not occur when `src` matches the location of a anscestor browsing context</title> +<script> +// Avoid recursion in non-conforming browsers +if (parent !== window && parent.title == window.title) { + window.stop(); +} +</script> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<body> +<script> +/** + * This test uses the `beforeunload` event to detect navigation. Because that + * event is fired synchronously in response to "process the iframe attributes", + * a second "control" iframe may be used to verify cases where navigation + * should *not* occur. `Promise.race` ensures that tests complete as soon as + * possible. + * + * Although the specification dictates that the `beforeunload` event must be + * emitted synchronously during navigation, a number of user agents do not + * adhere to this requirement. WPT includes a dedicated test for synchronous + * emission of the event [1]. This test is authored to support non-standard + * behavior in order to avoid spuriously passing in those UAs. + * + * [1] https://github.com/web-platform-tests/wpt/pull/12343 + */ +'use strict'; + +function when(target, eventName) { + return new Promise(function(resolve, reject) { + target.addEventListener(eventName, function() { + resolve(); + }, { once: true }); + target.addEventListener('error', function() { + reject(new Error('Error while waiting for ' + eventName)); + }, { once: true }); + }); +} + +function init(doc, t) { + var iframes = [doc.createElement('iframe'), doc.createElement('iframe')]; + + iframes.forEach(function(iframe) { + iframe.src = '/common/blank.html'; + doc.body.appendChild(iframe); + + t.add_cleanup(function() { + iframe.parentNode.removeChild(iframe); + }); + }); + + return Promise.all([when(iframes[0], 'load'), when(iframes[1], 'load')]) + .then(function() { return iframes; }); +} + +// This test verifies that navigation does occur; it is intended to validate +// the utility functions. +promise_test(function(t) { + return init(document, t) + .then(function(iframes) { + var subjectNavigation = when(iframes[0].contentWindow, 'beforeunload'); + var controlNavigation = when(iframes[1].contentWindow, 'beforeunload'); + + iframes[0].src = '/common/blank.html?2'; + iframes[1].src = '/common/blank.html?3'; + + return Promise.all([subjectNavigation, controlNavigation]); + }); +}, 'different path name'); + +promise_test(function(t) { + return init(document, t) + .then(function(iframes) { + var subjectNavigation = when(iframes[0].contentWindow, 'beforeunload'); + var controlNavigation = when(iframes[1].contentWindow, 'beforeunload'); + + iframes[0].src = location.href; + iframes[1].src = '/common/blank.html?4'; + + return Promise.race([ + subjectNavigation.then(function() { + assert_unreached('Should not navigate'); + }), + controlNavigation + ]); + }); +}, 'same path name, no document fragment'); + +promise_test(function(t) { + return init(document, t) + .then(function(iframes) { + var subjectNavigation = when(iframes[0].contentWindow, 'beforeunload'); + var controlNavigation = when(iframes[1].contentWindow, 'beforeunload'); + + iframes[0].src = location.href + '#something-else'; + iframes[1].src = '/common/blank.html?5'; + + return Promise.race([ + subjectNavigation.then(function() { + assert_unreached('Should not navigate'); + }), + controlNavigation + ]); + }); +}, 'same path name, different document fragment'); + +promise_test(function(t) { + var intermediate = document.createElement('iframe'); + + document.body.appendChild(intermediate); + + t.add_cleanup(function() { + intermediate.parentNode.removeChild(intermediate); + }); + intermediate.contentDocument.open(); + intermediate.contentDocument.write('<body></body>'); + intermediate.contentDocument.close(); + + return init(intermediate.contentDocument, t) + .then(function(iframes) { + var subjectNavigation = when(iframes[0].contentWindow, 'beforeunload'); + var controlNavigation = when(iframes[1].contentWindow, 'beforeunload'); + + iframes[0].src = location.href; + iframes[1].src = '/common/blank.html?6'; + + return Promise.race([ + subjectNavigation.then(function() { + assert_unreached('Should not navigate'); + }), + controlNavigation + ]); + }); +}, 'same path name, no document fragement (intermediary browsing context)'); +</script> +</body>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/the-img-element/null-image-source.html b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/the-img-element/null-image-source.html new file mode 100644 index 0000000..8999276 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/the-img-element/null-image-source.html
@@ -0,0 +1,30 @@ +<!doctype html> +<meta charset="utf-8"> +<title>Null image source check for src, srcset and picture parent</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<div id=log></div> +<img id="src_id" src=""> +<img id="srcset_id" srcset=""> +<picture><img id="parent_picture_id"></picture> +<script> +async_test(function(t) { + img = document.getElementById('src_id'); + img.onerror = t.step_func(function(e) { + assert_equals(e.type, "error", "null image source check failed"); + t.done(); + }); +}, "img with empty src"); + +async_test(function(t) { + img = document.getElementById('srcset_id'); + img.onerror = t.unreached_func("empty srcset fires an error"); + t.step_timeout(function() { t.done(); }, 2000); +}, "img with empty srcset"); + +async_test(function(t) { + img = document.getElementById('parent_picture_id'); + img.onerror = t.unreached_func("null img with picture parent fires an error"); + t.step_timeout(function() { t.done(); }, 2000); +}, "img with picture parent"); +</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/resources/chromium/webxr-test.js b/third_party/WebKit/LayoutTests/external/wpt/resources/chromium/webxr-test.js index d760e7c7..10ed703 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/resources/chromium/webxr-test.js +++ b/third_party/WebKit/LayoutTests/external/wpt/resources/chromium/webxr-test.js
@@ -47,25 +47,29 @@ let device = new MockDevice(fakeDeviceInit, this); this.devices_.push(device); + if (this.client_) { + this.client_.onDeviceChanged(); + } + return device; } // VRService implementation. + requestDevice() { + return Promise.resolve( + {device: this.devices_[0] ? this.devices_[0].getDevicePtr() : null}); + } + setClient(client) { this.client_ = client; - for (let i = 0; i < this.devices_.length; i++) { - this.devices_[i].notifyClientOfDisplay(); - } - - return Promise.resolve(); } } -// Implements both XRDeviceImpl and VRMagicWindowProvider. Maintains a mock for +// Implements both XRDevice and VRMagicWindowProvider. Maintains a mock for // XRPresentationProvider. class MockDevice { constructor(fakeDeviceInit, service) { - this.displayClient_ = new device.mojom.VRDisplayClientPtr(); + this.sessionClient_ = new device.mojom.XRSessionClientPtr(); this.presentation_provider_ = new MockXRPresentationProvider(); this.pose_ = null; @@ -80,23 +84,13 @@ } else { this.displayInfo_ = this.getNonImmersiveDisplayInfo(); } - - if (service.client_) { - this.notifyClientOfDisplay(); - } } // Functions for setup. - // This function calls to the backend to add this device to the list. - notifyClientOfDisplay() { + getDevicePtr() { let devicePtr = new device.mojom.XRDevicePtr(); - let deviceRequest = mojo.makeRequest(devicePtr); - let deviceBinding = - new mojo.Binding(device.mojom.XRDevice, this, deviceRequest); - - let clientRequest = mojo.makeRequest(this.displayClient_); - this.service_.client_.onDisplayConnected( - devicePtr, clientRequest, this.displayInfo_); + new mojo.Binding(device.mojom.XRDevice, this, mojo.makeRequest(devicePtr)); + return devicePtr; } // Test methods. @@ -120,7 +114,7 @@ } if (changed) { - this.displayClient_.onChanged(this.displayInfo_); + this.sessionClient_.onChanged(this.displayInfo_); } } } @@ -279,8 +273,7 @@ // do not have any use for this data at present. } - // XRDeviceImpl implementation. - + // XRDevice implementation. requestSession(sessionOptions, was_activation) { return this.supportsSession(sessionOptions).then((result) => { // The JavaScript bindings convert c_style_names to camelCase names. @@ -310,11 +303,15 @@ device.mojom.XREnviromentIntegrationProvider, this, enviromentProviderRequest); + let clientRequest = mojo.makeRequest(this.sessionClient_); + return Promise.resolve({ session: { submitFrameSink: submit_frame_sink, dataProvider: dataProviderPtr, - enviromentProvider: enviromentProviderPtr + enviromentProvider: enviromentProviderPtr, + clientRequest: clientRequest, + displayInfo: this.displayInfo_ } }); } else { @@ -326,7 +323,7 @@ supportsSession(options) { return Promise.resolve({ supportsSession: - !options.exclusive || this.displayInfo_.capabilities.canPresent + !options.immersive || this.displayInfo_.capabilities.canPresent }); }; }
diff --git a/third_party/WebKit/LayoutTests/fast/canvas/OffscreenCanvas-commit-copyImage.html b/third_party/WebKit/LayoutTests/fast/canvas/OffscreenCanvas-commit-copyImage.html deleted file mode 100644 index 8fdbcfb..0000000 --- a/third_party/WebKit/LayoutTests/fast/canvas/OffscreenCanvas-commit-copyImage.html +++ /dev/null
@@ -1,78 +0,0 @@ -<html> -<body><canvas id="myCanvas" width="256" height="256"></canvas> - <div id="log"></div> -</body> -<script src="../../resources/testharness.js"></script> -<script src="../../resources/testharnessreport.js"></script> -<script> - -var t = async_test("CopyImageOnTransferredCanvas"); - -function main() { - assert_true(!!window.testRunner, "This test requires window.testRunner."); - - if (window.testRunner) { - initTest(); - } else { - t.done(); - } -} - -function initTest() { - var canv = document.getElementById("myCanvas"); - var off = canv.transferControlToOffscreen(); - var ctx = off.getContext("2d"); - - ctx.fillStyle = "#f00"; - ctx.fillRect(0, 0, 128, 128); - ctx.fillStyle = "#0f0"; - ctx.fillRect(128, 0, 128, 128); - ctx.fillStyle = "#00f"; - ctx.fillRect(0, 128, 128, 128); - ctx.fillStyle = "#ff0"; - ctx.fillRect(128, 128, 128, 128); - - requestAnimationFrame(runTest); -} - -function copyImage() { - testRunner.copyImageAtAndCapturePixelsAsyncThen(100, 100, completionCallback); -} - -function runTest() { - // We need setTimeout as a frame barrier for the image frame to be - // propagated to the placeholder canvas. - requestAnimationFrame(() => { - requestAnimationFrame(() => { - requestAnimationFrame(copyImage); - }); - }); -} - -function completionCallback(width, height, snapshot) { - t.step(function() { - assert_equals(width, 256, "The copied image has a width of 256."); - assert_equals(height, 256, "The copied image has a height of 256."); - - var data = new Uint8Array(snapshot); - - var pixelLeftTop = data.subarray(0, 4); - assert_array_equals(pixelLeftTop, [255, 0, 0, 255], "The copied image's top left is red"); - - var pixelRightTop = data.subarray(4 * 128, 4* 128 + 4); - assert_array_equals(pixelRightTop, [0, 255, 0, 255], "The copied image's top right is green"); - - var pixelLeftBottom = data.subarray(4 * 256 * 128, 4 * 256 * 128 + 4); - assert_array_equals(pixelLeftBottom, [0, 0, 255, 255], "The copied image's bottom left is blue"); - - var rightBottomPixelPosition = 4 * 256 * 128 + 4 * 128; - var pixelRightBottom = data.subarray(rightBottomPixelPosition, rightBottomPixelPosition + 4); - assert_array_equals(pixelRightBottom, [255, 255, 0, 255], "The copied image's bottom right is yellow"); - - }); - t.done(); -} - -main(); - </script> -</html>
diff --git a/third_party/WebKit/LayoutTests/fast/canvas/OffscreenCanvas-copyImage.html b/third_party/WebKit/LayoutTests/fast/canvas/OffscreenCanvas-copyImage.html new file mode 100644 index 0000000..3dbe533 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/canvas/OffscreenCanvas-copyImage.html
@@ -0,0 +1,75 @@ +<html> +<body><canvas id="myCanvas" width="256" height="256"></canvas> + <div id="log"></div> +</body> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> +<script> + +const t = async_test("CopyImageOnTransferredCanvas"); + +function main() { + assert_true(!!window.testRunner, "This test requires window.testRunner."); + + if (window.testRunner) { + initTest(); + } else { + t.done(); + } +} + +function initTest() { + const canv = document.getElementById("myCanvas"); + const off = canv.transferControlToOffscreen(); + const ctx = off.getContext("2d"); + + ctx.fillStyle = "#f00"; + ctx.fillRect(0, 0, 128, 128); + ctx.fillStyle = "#0f0"; + ctx.fillRect(128, 0, 128, 128); + ctx.fillStyle = "#00f"; + ctx.fillRect(0, 128, 128, 128); + ctx.fillStyle = "#ff0"; + ctx.fillRect(128, 128, 128, 128); + + requestAnimationFrame(runTest); +} + +function runTest() { + // We need a frame barrier for the image frame to be propagated to the + // placeholder canvas. + requestAnimationFrame(() => { + requestAnimationFrame(copyImage); + }); +} + +function copyImage() { + testRunner.copyImageAtAndCapturePixelsAsyncThen(128, 128, + t.step_func_done((width, height, snapshot) => { + assert_equals(width, 256, "The copied image has a width of 256."); + assert_equals(height, 256, "The copied image has a height of 256."); + + const data = new Uint8Array(snapshot); + + const pixelLeftTop = data.subarray(0, 4); + assert_array_equals(pixelLeftTop, [255, 0, 0, 255], + "The copied image's top left is red"); + + const pixelRightTop = data.subarray(4 * 128, 4* 128 + 4); + assert_array_equals(pixelRightTop, [0, 255, 0, 255], + "The copied image's top right is green"); + + const pixelLeftBottom = data.subarray(4 * 256 * 128, 4 * 256 * 128 + 4); + assert_array_equals(pixelLeftBottom, [0, 0, 255, 255], + "The copied image's bottom left is blue"); + + const pixelRightBottom = data.subarray(4 * 256 * 128 + 4 * 128, + 4 * 256 * 128 + 4 * 128 + 4); + assert_array_equals(pixelRightBottom, [255, 255, 0, 255], + "The copied image's bottom right is yellow"); + })); +} + +main(); + </script> +</html>
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/box-shadow/box-shadow-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/box-shadow/box-shadow-expected.png new file mode 100644 index 0000000..f9e6980f --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/box-shadow/box-shadow-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/images/color-profile-munsell-adobe-to-srgb-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/images/color-profile-munsell-adobe-to-srgb-expected.txt index 55cf09c..168756a 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/images/color-profile-munsell-adobe-to-srgb-expected.txt +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/images/color-profile-munsell-adobe-to-srgb-expected.txt
@@ -1,36 +1,36 @@ Color Actual Expected dE -------------------------------------------- -Dark Skin 115,80,64 115,80,64 0 +Dark Skin 114,80,64 115,80,64 1 Light Skin 195,150,130 195,151,130 1 -Blue Sky 94,123,157 94,123,156 1 -Foliage 89,108,65 88,108,65 1 +Blue Sky 94,122,156 94,123,156 1 +Foliage 88,108,65 88,108,65 0 Blue Flower 130,129,177 130,129,177 0 Bluish Green 100,190,171 100,190,171 0 -------------------------------------------- -Orange 216,122,37 217,122,37 1 -Purplish Blue 72,91,166 72,91,165 1 +Orange 216,121,37 217,122,37 1 +Purplish Blue 72,90,166 72,91,165 1 Moderate Red 194,84,97 194,84,98 1 -Purple 91,60,107 91,59,107 1 -Yellow Green 160,187,60 160,188,60 1 -Orange Yellow 230,163,42 230,163,42 0 +Purple 90,60,106 91,59,107 2 +Yellow Green 160,188,60 160,188,60 0 +Orange Yellow 231,163,42 230,163,42 1 -------------------------------------------- Blue 47,60,153 46,60,153 1 Green 70,149,69 71,150,69 1 -Red 177,44,56 177,44,56 0 +Red 177,45,56 177,44,56 1 Yellow 239,200,27 238,200,27 1 Magenta 187,82,147 187,82,148 1 -Cyan (*) 0,135,166 0,135,166 0 +Cyan (*) 0,135,165 0,135,166 1 -------------------------------------------- -White 243,241,236 243,242,237 1 -Neutral 8 201,201,200 201,201,201 1 +White 243,242,236 243,242,237 1 +Neutral 8 202,201,200 201,201,201 1 Neutral 6.5 160,161,160 161,161,161 1 -Neutral 5 123,122,121 122,122,121 1 +Neutral 5 123,121,120 122,122,121 2 Neutral 3.5 83,83,83 83,83,83 0 Black 50,50,50 50,49,50 1 -------------------------------------------- -Result: total RMS color error: 0.84 +Result: total RMS color error: 1.02 * Munsell Cyan is outside 255 sRGB gamut
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/images/feature-policy-max-downscaling-image-edge-cases-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/images/feature-policy-max-downscaling-image-edge-cases-expected.txt new file mode 100644 index 0000000..6910ad5f --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/images/feature-policy-max-downscaling-image-edge-cases-expected.txt
@@ -0,0 +1,23 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x525 + LayoutNGBlockFlow {HTML} at (0,0) size 800x525 + LayoutNGBlockFlow {BODY} at (8,8) size 784x509 + LayoutText {#text} at (0,0) size 0x0 +layer at (8,8) size 604x504 + LayoutIFrame {IFRAME} at (0,0) size 604x504 [border: (2px inset #EEEEEE)] + layer at (0,0) size 600x500 + LayoutView at (0,0) size 600x500 + layer at (0,0) size 600x411 + LayoutNGBlockFlow {HTML} at (0,0) size 600x411 + LayoutNGBlockFlow {BODY} at (8,8) size 584x395 + LayoutImage {IMG} at (0,0) size 256x256 + LayoutText {#text} at (256,241) size 4x19 + text run at (256,241) width 4: " " + LayoutImage {IMG} at (260,128) size 128x128 + LayoutText {#text} at (388,241) size 4x19 + text run at (388,241) width 4: " " + LayoutImage {IMG} at (392,129) size 127x127 + LayoutText {#text} at (0,0) size 0x0 + LayoutImage {IMG} at (0,261) size 129x129 + LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/virtual/gpu-rasterization/images/feature-policy-max-downscaling-image-edge-cases-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/virtual/gpu-rasterization/images/feature-policy-max-downscaling-image-edge-cases-expected.txt new file mode 100644 index 0000000..6910ad5f --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/virtual/gpu-rasterization/images/feature-policy-max-downscaling-image-edge-cases-expected.txt
@@ -0,0 +1,23 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x525 + LayoutNGBlockFlow {HTML} at (0,0) size 800x525 + LayoutNGBlockFlow {BODY} at (8,8) size 784x509 + LayoutText {#text} at (0,0) size 0x0 +layer at (8,8) size 604x504 + LayoutIFrame {IFRAME} at (0,0) size 604x504 [border: (2px inset #EEEEEE)] + layer at (0,0) size 600x500 + LayoutView at (0,0) size 600x500 + layer at (0,0) size 600x411 + LayoutNGBlockFlow {HTML} at (0,0) size 600x411 + LayoutNGBlockFlow {BODY} at (8,8) size 584x395 + LayoutImage {IMG} at (0,0) size 256x256 + LayoutText {#text} at (256,241) size 4x19 + text run at (256,241) width 4: " " + LayoutImage {IMG} at (260,128) size 128x128 + LayoutText {#text} at (388,241) size 4x19 + text run at (388,241) width 4: " " + LayoutImage {IMG} at (392,129) size 127x127 + LayoutText {#text} at (0,0) size 0x0 + LayoutImage {IMG} at (0,261) size 129x129 + LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/gamepad/gamepad-polling-access.html b/third_party/WebKit/LayoutTests/gamepad/gamepad-polling-access.html index 5edbc354..d2ae240 100644 --- a/third_party/WebKit/LayoutTests/gamepad/gamepad-polling-access.html +++ b/third_party/WebKit/LayoutTests/gamepad/gamepad-polling-access.html
@@ -4,33 +4,22 @@ <script src="../resources/testharnessreport.js"></script> <script src="resources/gamepad-helpers.js"></script> <script> -// We will convert all |buttons| and |axes| to string to avoid reused buffer -// problem. https://crbug.com/855760 -function buttonsToStr(buttons) { - return buttons.map(button => "[" + button.pressed + "," + button.touched + "," + button.value + "]") - .join(); -} -function axesToStr(axes) { - return axes.toString(); + +// TODO(crbug.com/146285): Allow more than 4 connected gamepads. +var MAX_GAMEPADS = 4; + +function disconnectGamepads() { + // Simulate disconnecting all gamepads. + for (let i = 0; i < MAX_GAMEPADS; ++i) { + gamepadController.disconnect(i); + } } -promise_test(async () => { - // Start all disconnected - gamepadController.disconnect(0); - gamepadController.disconnect(1); - gamepadController.disconnect(2); - gamepadController.disconnect(3); - assert_equals(navigator.getGamepads().length, 4, 'navigator.getGamepads().length'); - assert_equals(navigator.getGamepads().item(0), null, 'navigator.getGamepads().item(0)'); - assert_equals(navigator.getGamepads().item(1), null, 'navigator.getGamepads().item(1)'); - assert_equals(navigator.getGamepads().item(2), null, 'navigator.getGamepads().item(2)'); - assert_equals(navigator.getGamepads().item(3), null, 'navigator.getGamepads().item(3)'); - assert_equals(navigator.getGamepads()[0], null, 'navigator.getGamepads()[0]'); - assert_equals(navigator.getGamepads()[1], null, 'navigator.getGamepads()[1]'); - assert_equals(navigator.getGamepads()[2], null, 'navigator.getGamepads()[2]'); - assert_equals(navigator.getGamepads()[3], null, 'navigator.getGamepads()[3]'); - - // connect again, and check standard access +function connectOneGamepad() { + // Simulate a connected gamepad at index 0 with: + // * id 'MockStick 3000' + // * two buttons (values 1.0/pressed, 0.0/unpressed) + // * two axes (values 0.5, -1.0) gamepadController.connect(0); gamepadController.setId(0, "MockStick 3000"); gamepadController.setButtonCount(0, 2); @@ -40,51 +29,172 @@ gamepadController.setAxisData(0, 0, .5); gamepadController.setAxisData(0, 1, -1.0); gamepadController.dispatchConnected(0); +} - await ongamepadconnected(); - assert_equals(navigator.getGamepads()[0].id, 'MockStick 3000', 'navigator.getGamepads()[0].id'); - assert_equals(navigator.getGamepads()[0].buttons.length, 2, 'navigator.getGamepads()[0].buttons.length'); - assert_equals(navigator.getGamepads()[0].buttons[0].value, 1.0, 'navigator.getGamepads()[0].buttons[0].value'); - assert_true(navigator.getGamepads()[0].buttons[0].pressed, 'navigator.getGamepads()[0].buttons[0].pressed'); - assert_equals(navigator.getGamepads()[0].buttons[1].value, 0.0, 'navigator.getGamepads()[0].buttons[1].value'); - assert_false(navigator.getGamepads()[0].buttons[1].pressed, 'navigator.getGamepads()[0].buttons[1].pressed'); - assert_equals(navigator.getGamepads()[0].axes.length, 2, 'navigator.getGamepads()[0].axes.length'); - assert_equals(navigator.getGamepads()[0].axes[0], 0.5, 'navigator.getGamepads()[0].axes[0]'); - assert_equals(navigator.getGamepads()[0].axes[1], -1.0, 'navigator.getGamepads()[0].axes[1]'); +function testGamepadStateAllDisconnected() { + // To pass this test, the getGamepads array should have only null elements. + let pads = navigator.getGamepads(); + // According to the spec, the length of the array returned by getGamepads + // must be one greater than the maximum index of Gamepad objects in the + // array. It does not specify the size when there are no objects in the + // array. The current behavior in Chrome is to return an array with length + // equal to the maximum number of connected gamepads, and to fill all unused + // slots with null. + assert_equals(pads.length, MAX_GAMEPADS, 'pads.length'); + for (let i = 0; i < pads.length; ++i) { + // TODO(crbug.com/865642): Remove deprecated Gamepad.item method. + assert_equals(pads.item(i), null); + assert_equals(pads[i], null); + } +} - // Check that accessing the |axes| and |buttons| attributes fetches the - // same objects until their values change. - assert_equals(navigator.getGamepads()[0].axes, navigator.getGamepads()[0].axes, 'navigator.getGamepads()[0].axes'); - assert_equals(navigator.getGamepads()[0].buttons, navigator.getGamepads()[0].buttons, 'navigator.getGamepads()[0].buttons'); - let oldAxesStr = axesToStr(navigator.getGamepads()[0].axes); - let oldButtonsStr = buttonsToStr(navigator.getGamepads()[0].buttons); +function testGamepadStateOneConnected() { + // To pass this test, Gamepad 0 should have the values set in + // setUpOneGamepad. + let gamepad = navigator.getGamepads()[0]; + assert_equals(gamepad.id, 'MockStick 3000'); + assert_equals(gamepad.buttons.length, 2); + assert_equals(gamepad.buttons[0].value, 1.0); + assert_true(gamepad.buttons[0].pressed); + assert_equals(gamepad.buttons[1].value, 0.0); + assert_false(gamepad.buttons[1].pressed); + assert_equals(gamepad.axes.length, 2); + assert_equals(gamepad.axes[0], 0.5); + assert_equals(gamepad.axes[1], -1.0); +} - // Updates with the same values are skipped. - gamepadController.setAxisCount(0, 2); - gamepadController.setButtonCount(0, 2); - assert_equals(axesToStr(navigator.getGamepads()[0].axes), oldAxesStr, 'navigator.getGamepads()[0].axes'); - assert_equals(buttonsToStr(navigator.getGamepads()[0].buttons), oldButtonsStr, 'navigator.getGamepads()[0].buttons'); - gamepadController.setAxisData(0, 0, .5); - gamepadController.setButtonData(0, 1, 0); - assert_equals(axesToStr(navigator.getGamepads()[0].axes), oldAxesStr, 'navigator.getGamepads()[0].axes'); - assert_equals(buttonsToStr(navigator.getGamepads()[0].buttons), oldButtonsStr, 'navigator.getGamepads()[0].buttons'); +function testNoChangeReturnsSameObjects() { + // Check that accessing gamepad state fetches the same objects until their + // values change. + assert_equals(navigator.getGamepads(), + navigator.getGamepads(), 'gamepad arrays differ'); + assert_equals(navigator.getGamepads()[0], + navigator.getGamepads()[0], 'gamepad objects differ'); + assert_equals(navigator.getGamepads()[0].axes, + navigator.getGamepads()[0].axes, 'axes arrays differ'); + assert_equals(navigator.getGamepads()[0].buttons, + navigator.getGamepads()[0].buttons, 'gamepad buttons differ'); +} - // Updates with different values are not skipped. - gamepadController.setAxisData(0, 0, .6); - assert_not_equals(axesToStr(navigator.getGamepads()[0].axes), oldAxesStr, 'navigator.getGamepads()[0].axes'); - assert_equals(buttonsToStr(navigator.getGamepads()[0].buttons), oldButtonsStr, 'navigator.getGamepads()[0].buttons'); - oldAxesStr = axesToStr(navigator.getGamepads()[0].axes); +function testSameValueUpdateReturnsSameObjects() { + // Test that updates with the same value do not cause a new gamepad object + // to be returned. + let gamepadBefore = navigator.getGamepads()[0]; + gamepadController.setAxisCount(0, gamepadBefore.axes.length); + gamepadController.setButtonCount(0, gamepadBefore.buttons.length); + let gamepadAfter = navigator.getGamepads()[0]; + assert_equals( + gamepadBefore, gamepadAfter, + "expected same gamepad after same-value setAxisCount/setButtonCount"); + assert_equals( + gamepadBefore.timestamp, gamepadAfter.timestamp, + "expected same timestamp after same-value setAxisCount/setButtonCount"); + assert_equals( + gamepadBefore.axes, gamepadAfter.axes, + "expected same axes after same-value setAxisCount/setButtonCount"); + assert_equals( + gamepadBefore.buttons, gamepadAfter.buttons, + "expected same buttons after same-value setAxisCount/setButtonCount"); - gamepadController.setButtonData(0, 0, .2); - assert_equals(axesToStr(navigator.getGamepads()[0].axes), oldAxesStr, 'navigator.getGamepads()[0].axes'); - assert_not_equals(buttonsToStr(navigator.getGamepads()[0].buttons), oldButtonsStr, 'navigator.getGamepads()[0].buttons'); - oldButtonsStr = buttonsToStr(navigator.getGamepads()[0].buttons); + gamepadBefore = navigator.getGamepads()[0]; + gamepadController.setAxisData(0, 0, gamepadBefore.axes[0]); + gamepadController.setButtonData(0, 1, gamepadBefore.buttons[1].value); + gamepadAfter = navigator.getGamepads()[0]; + assert_equals( + gamepadBefore, gamepadAfter, + "expected same gamepad after same-value setAxisData/setButtonData"); + assert_equals( + gamepadBefore.timestamp, gamepadAfter.timestamp, + "expected same timestamp after same-value setAxisData/setButtonData"); + assert_equals( + gamepadBefore.axes, gamepadAfter.axes, + "expected same axes after same-value setAxisData/setButtonData"); + assert_equals( + gamepadBefore.buttons, gamepadAfter.buttons, + "expected same buttons after same-value setAxisData/setButtonData"); +} - gamepadController.setAxisData(0, 0, .9); - gamepadController.setButtonData(0, 0, .3); - assert_not_equals(axesToStr(navigator.getGamepads()[0].axes), oldAxesStr, 'navigator.getGamepads()[0].axes'); - assert_not_equals(buttonsToStr(navigator.getGamepads()[0].buttons), oldButtonsStr, 'navigator.getGamepads()[0].buttons'); +function testDifferentValueUpdateReturnsNewObjects() { + // Test that changing an axis value causes a new gamepad object to be + // returned. + // TODO(crbug.com/855760): Check that the buttons array is preserved. + gamepadBefore = navigator.getGamepads()[0]; + gamepadController.setAxisData(0, 0, gamepadBefore.axes[0] + 0.1); + gamepadAfter = navigator.getGamepads()[0]; + assert_not_equals(gamepadBefore, gamepadAfter, + "expected new gamepad after new-value setAxisData"); + assert_not_equals(gamepadBefore.timestamp, + gamepadAfter.timestamp, + "expected new timestamp after new-value setAxisData"); + assert_not_equals(gamepadBefore.axes, gamepadAfter.axes, + "expected new axes after new-value setAxisData"); + // Test that changing a button value causes a new gamepad object to be + // returned. + // TODO(crbug.com/855760): Check that the axes array is preserved. + gamepadBefore = navigator.getGamepads()[0]; + gamepadController.setButtonData(0, 0, gamepad.buttons[0].value + 0.1); + gamepadAfter = navigator.getGamepads()[0]; + assert_not_equals(gamepadBefore, gamepadAfter, + "expected new gamepad after new-value setButtonData"); + assert_not_equals(gamepadBefore.timestamp, + gamepadAfter.timestamp, + "expected new timestamp after new-value setButtonData"); + assert_not_equals(gamepadBefore.buttons, gamepadAfter.buttons, + "expected new buttons after new-value setButtonData"); + + // Test that changing a button value and an axis value causes a new gamepad + // object to be returned. + gamepadBefore = navigator.getGamepads()[0]; + gamepadController.setAxisData(0, 0, gamepad.axes[0] - 0.1); + gamepadController.setButtonData(0, 0, gamepad.buttons[0].value - 0.1); + gamepadAfter = navigator.getGamepads()[0]; + assert_not_equals( + gamepadBefore, gamepadAfter, + "expected new gamepad after new-value setAxisData/setButtonData"); + assert_not_equals( + gamepadBefore.timestamp, gamepadAfter.timestamp, + "expected new timestamp after new-value setAxisData/setButtonData"); + assert_not_equals( + gamepadBefore.axes, gamepadAfter.axes, + "expected new axes after new-value setAxisData/setButtonData"); + assert_not_equals( + gamepadBefore.buttons, gamepadAfter.buttons, + "expected new buttons after new-value setAxisData/setButtonData"); +} + +promise_test(async () => { + // First disconnect all gamepads. + disconnectGamepads(); + testGamepadStateAllDisconnected(); + + // Simulate a gamepad connection and verify the state changes as expected. + let connectPromise = ongamepadconnected(); + connectOneGamepad(); + await connectPromise; + testGamepadStateOneConnected(); + + // Chrome has different internal behavior depending on whether a gamepad + // event listener is registered. Exercise both paths to verify that the + // state changes are handled correctly in either case. + let disconnectListener = (e) => {}; + + window.addEventListener('gamepaddisconnected', disconnectListener); + testNoChangeReturnsSameObjects(); + testSameValueUpdateReturnsSameObjects(); + // TODO(crbug.com/855760): With a listener registered, Chrome will only + // create a new object if there was a gamepad disconnection. Otherwise, + // the previous gamepad object is overwritten with the new data. Re-enable + // this test once Chrome correctly creates a new gamepad object. + //testDifferentValueUpdateReturnsNewObjects(); + + window.removeEventListener('gamepaddisconnected', disconnectListener); + testNoChangeReturnsSameObjects(); + testSameValueUpdateReturnsSameObjects(); + // TODO(crbug.com/855760): With no listener registered, Chrome always reuses + // the gamepad object. Re-enable this test once Chrome correctly creates a + // new gamepad object. + //testDifferentValueUpdateReturnsNewObjects(); }, "Typical polling access to gamepads contents."); </script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger-breakpoints/debugger-disable-add-breakpoint.js b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger-breakpoints/debugger-disable-add-breakpoint.js index 9002915..c72a78dc1 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger-breakpoints/debugger-disable-add-breakpoint.js +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger-breakpoints/debugger-disable-add-breakpoint.js
@@ -53,9 +53,7 @@ function step7() { TestRunner.addResult('Debugger disabled'); - var breakpoint = Bindings.breakpointManager.findBreakpoints( - testSourceFrame.uiSourceCode(), 3)[0]; - breakpoint.remove(); + SourcesTestRunner.removeBreakpoint(testSourceFrame, 3); TestRunner.addResult('Breakpoint removed'); TestRunner.debuggerModel.addEventListener( SDK.DebuggerModel.Events.DebuggerWasEnabled, step8, this);
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger/live-edit-breakpoints.js b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger/live-edit-breakpoints.js index b5c4f9a..476a979c 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger/live-edit-breakpoints.js +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger/live-edit-breakpoints.js
@@ -34,7 +34,7 @@ ' url: ' + pathToFileName(url) + ', lineNumber: ' + lineNumber + ', project type: ' + project.type()); } - breakpoints = breakpointManager._allBreakpoints(); + breakpoints = breakpointManager.allBreakpointLocations().map(breakpointLocation => breakpointLocation.breakpoint); TestRunner.addResult(' Dumping breakpoints'); for (var i = 0; i < breakpoints.length; ++i) { var breakpoint = breakpoints[i];
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger/live-edit.js b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger/live-edit.js index da4072c..dd34400c 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger/live-edit.js +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/sources/debugger/live-edit.js
@@ -116,8 +116,8 @@ () => SourcesTestRunner.dumpDebuggerPluginBreakpoints( testSourceFrame)) .then( - () => Bindings.breakpointManager._allBreakpoints().map( - breakpoint => breakpoint.remove())) + () => Bindings.breakpointManager.allBreakpointLocations().map( + breakpointLocation => breakpointLocation.breakpoint.remove())) .then(next); } },
diff --git a/third_party/WebKit/LayoutTests/vr/events_vrdisplayactivate.html b/third_party/WebKit/LayoutTests/vr/events_vrdisplayactivate.html index 6f30f53..1b79a52 100644 --- a/third_party/WebKit/LayoutTests/vr/events_vrdisplayactivate.html +++ b/third_party/WebKit/LayoutTests/vr/events_vrdisplayactivate.html
@@ -35,8 +35,13 @@ }); } window.addEventListener("vrdisplayactivate", onDisplayActivate, false); - deviceController.forceActivate(2 /*Display mounted, although any int 0-3 is valid*/); + // Timeout here is required because addEventListener sends a call to mojo to + // register the listener on the backend, which doesn't go through until the + // javascript pauses. + setTimeout(() => { + deviceController.forceActivate(2 /*Display mounted, although any int 0-3 is valid*/); + }, 100); }, (err) => { t.step( () => { assert_unreached(err);
diff --git a/third_party/WebKit/LayoutTests/vr/events_vrdisplayconnect.html b/third_party/WebKit/LayoutTests/vr/events_vrdisplayconnect.html index e3435dd..dd6aa1a 100644 --- a/third_party/WebKit/LayoutTests/vr/events_vrdisplayconnect.html +++ b/third_party/WebKit/LayoutTests/vr/events_vrdisplayconnect.html
@@ -15,8 +15,7 @@ let watcherDone = new Event("watcherdone"); let eventWatcher = new EventWatcher(t, window, ["vrdisplayconnect", "watcherdone"]); - eventWatcher.wait_for(["vrdisplayconnect", /*Initial mock display connected*/ - "vrdisplayconnect", /*Display added w/ addVRDisplay*/ + eventWatcher.wait_for(["vrdisplayconnect", "watcherdone"]) .then( () => { t.done(); @@ -33,13 +32,10 @@ setTimeout( () => { navigator.getVRDisplays().then( (displays) => { t.step( () => { - assert_equals(displays.length, 2); - // The name FakeDevice is a default name given by the XR backend - // mocking and sent to the on connect method. As displayName is - // eventually going away, doesn't seem much point in making this - // setable. - assert_equals(displays[1].displayName, "FakeDevice"); - }, "Check added display"); + // VR only supplies one display now to be compatible with the WebXR + // implementation. + assert_equals(displays.length, 1); + }, "Check display"); window.dispatchEvent(watcherDone); }, (err) => { t.step( () => {
diff --git a/third_party/WebKit/LayoutTests/vr/getEyeParameters_null.html b/third_party/WebKit/LayoutTests/vr/getEyeParameters_null.html index 67d8a3a1..0cc58a8 100644 --- a/third_party/WebKit/LayoutTests/vr/getEyeParameters_null.html +++ b/third_party/WebKit/LayoutTests/vr/getEyeParameters_null.html
@@ -18,7 +18,6 @@ let display = displays[0]; t.step( () => { - console.log(display.getEyeParameters); assert_equals(display.getEyeParameters("left"), null); assert_equals(display.getEyeParameters("right"), null); }, "Eye parameters are null");
diff --git a/third_party/WebKit/LayoutTests/vr/getVRDisplays_one_display.html b/third_party/WebKit/LayoutTests/vr/getVRDisplays_one_display.html index d109976..7dd37e9e7 100644 --- a/third_party/WebKit/LayoutTests/vr/getVRDisplays_one_display.html +++ b/third_party/WebKit/LayoutTests/vr/getVRDisplays_one_display.html
@@ -15,7 +15,6 @@ assert_true(displays != null); assert_equals(displays.length, 1); let display = displays[0]; - assert_equals(display.displayName, 'Google, Inc. Daydream View'); assert_true(display.capabilities.canPresent); assert_approx_equals(display.depthNear, 0.01, FLOAT_EPSILON); assert_approx_equals(display.depthFar, 10000.0, FLOAT_EPSILON);
diff --git a/third_party/WebKit/LayoutTests/vr/getVRDisplays_two_display.html b/third_party/WebKit/LayoutTests/vr/getVRDisplays_two_display.html deleted file mode 100644 index 9b257f5..0000000 --- a/third_party/WebKit/LayoutTests/vr/getVRDisplays_two_display.html +++ /dev/null
@@ -1,50 +0,0 @@ -<!DOCTYPE html> -<script src="../resources/testharness.js"></script> -<script src="../resources/testharnessreport.js"></script> -<script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script> -<script src="file:///gen/device/vr/public/mojom/vr_service.mojom.js"></script> -<script src="../external/wpt/resources/chromium/webxr-test.js"></script> -<script src="resources/vr-test-utils.js "></script> -<script src="resources/test-constants.js"></script> -<script> -let fakeDisplays = fakeVRDisplays(); - -vr_test( (t) => { - return navigator.getVRDisplays().then( (displays) => { - t.step( () => { - assert_true(displays != null); - assert_equals(displays.length, 2); - }, "getVRDisplays returned correct results"); - let pixel = displays[0]; - let fake = displays[1]; - - t.step( () => { - assert_equals(pixel.displayName, "Google, Inc. Daydream View"); - assert_true(pixel.capabilities.canPresent); - assert_false(pixel.capabilities.hasPosition); - assert_false(pixel.capabilities.hasExternalDisplay); - assert_equals(pixel.capabilities.maxLayers, 1); - assert_approx_equals(pixel.depthNear, 0.01, FLOAT_EPSILON); - assert_approx_equals(pixel.depthFar, 10000.0, FLOAT_EPSILON); - }, "Pixel attributes are correct"); - - t.step( () => { - assert_equals(fake.displayName, "FakeVRDisplay"); - assert_false(fake.capabilities.canPresent); - assert_false(fake.capabilities.hasPosition); - assert_false(fake.capabilities.hasExternalDisplay); - assert_equals(fake.capabilities.maxLayers, 0); - assert_approx_equals(fake.depthNear, 0.01, FLOAT_EPSILON); - assert_approx_equals(fake.depthFar, 10000.0, FLOAT_EPSILON); - }, "Fake device attributes are correct"); - }, (err) => { - t.step( () => { - assert_unreached("getVRDisplays rejected"); - }); - }).then( () => { - t.done(); - }); -}, [fakeDisplays["Pixel"], fakeDisplays["FakeMagicWindowOnly"]], -"Test that getVRDisplays properly returns two displays"); - -</script>
diff --git a/third_party/WebKit/LayoutTests/vr/resources/vr-test-utils.js b/third_party/WebKit/LayoutTests/vr/resources/vr-test-utils.js index b669d11..4ade3cc 100644 --- a/third_party/WebKit/LayoutTests/vr/resources/vr-test-utils.js +++ b/third_party/WebKit/LayoutTests/vr/resources/vr-test-utils.js
@@ -1,5 +1,12 @@ 'use strict'; +MockVRService.prototype.setListeningForActivate = function(client) { + for (let i = 0; i < this.devices_.length; i++) { + this.devices_[i].displayClient_ = client; + } +}; + + MockDevice.prototype.setPose = function(pose) { if (pose == null) { this.pose_ = null; @@ -27,6 +34,10 @@ this.displayClient_.onActivate(reason); }; +MockDevice.prototype.getImmersiveVRDisplayInfo = function() { + return Promise.resolve({info: this.displayInfo_}); +}; + function vr_test(func, vrDisplays, name, properties) { let chain = Promise.resolve(); let firstDeviceController; @@ -147,4 +158,4 @@ } // TODO(bsheedy) add more displays like Rift/Vive }; -} +};
diff --git a/third_party/WebKit/LayoutTests/xr/events_deviceconnect.html b/third_party/WebKit/LayoutTests/xr/events_deviceconnect.html index 0038331..c73600c 100644 --- a/third_party/WebKit/LayoutTests/xr/events_deviceconnect.html +++ b/third_party/WebKit/LayoutTests/xr/events_deviceconnect.html
@@ -14,15 +14,24 @@ // The event should fire when a listener is added even if the devices are not // explicity queried with navigator.xr.requestDevice(). + // Note: This behaviour is chrome specific, the spec does not explicitly + // state when devicechange events should occur. function onDeviceChange() { navigator.xr.dispatchEvent(watcherDone); }; navigator.xr.addEventListener("devicechange", onDeviceChange, false); - XRTest.simulateDeviceConnection({ supportsImmersive:true }); + let promise = eventWatcher.wait_for(["devicechange", "watcherdone"]); - return eventWatcher.wait_for(["devicechange", "watcherdone"]); + // Timeout here is required because addEventListener sends a call to mojo to + // register the listener on the backend, which doesn't go through until the + // javascript pauses. + setTimeout(() => { + XRTest.simulateDeviceConnection({ supportsImmersive:true }); + }, 100); + + return promise; }, "Test devicechange fires when devices are connected.");
diff --git a/third_party/WebKit/LayoutTests/xr/resources/xr-internal-device-mocking.js b/third_party/WebKit/LayoutTests/xr/resources/xr-internal-device-mocking.js index ba4b678..bd429a1 100644 --- a/third_party/WebKit/LayoutTests/xr/resources/xr-internal-device-mocking.js +++ b/third_party/WebKit/LayoutTests/xr/resources/xr-internal-device-mocking.js
@@ -79,7 +79,7 @@ this.displayInfo_.stageParameters = null; } - this.displayClient_.onChanged(this.displayInfo_); + this.sessionClient_.onChanged(this.displayInfo_); }; MockDevice.prototype.getSubmitFrameCount = function() {
diff --git a/third_party/blink/public/blink_typemaps.gni b/third_party/blink/public/blink_typemaps.gni index 9173637..97e2b6d 100644 --- a/third_party/blink/public/blink_typemaps.gni +++ b/third_party/blink/public/blink_typemaps.gni
@@ -5,6 +5,7 @@ typemaps = [ "//gpu/ipc/common/mailbox_holder_for_blink.typemap", "//gpu/ipc/common/sync_token.typemap", + "//mojo/public/cpp/base/file_error.typemap", "//services/viz/public/cpp/compositing/begin_frame_args_for_blink.typemap", "//services/viz/public/cpp/compositing/compositor_frame_for_blink.typemap", "//services/viz/public/cpp/compositing/frame_sink_id.typemap",
diff --git a/third_party/blink/public/mojom/BUILD.gn b/third_party/blink/public/mojom/BUILD.gn index 5cb13269..cd9eb7b 100644 --- a/third_party/blink/public/mojom/BUILD.gn +++ b/third_party/blink/public/mojom/BUILD.gn
@@ -26,6 +26,7 @@ "fetch/fetch_api_response.mojom", "file/file_utilities.mojom", "filesystem/file_system.mojom", + "filesystem/file_writer.mojom", "frame/find_in_page.mojom", "leak_detector/leak_detector.mojom", "loader/navigation_predictor.mojom",
diff --git a/third_party/blink/public/mojom/filesystem/file_writer.mojom b/third_party/blink/public/mojom/filesystem/file_writer.mojom new file mode 100644 index 0000000..14ec83e --- /dev/null +++ b/third_party/blink/public/mojom/filesystem/file_writer.mojom
@@ -0,0 +1,24 @@ +// Copyright 2018 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. + +module blink.mojom; + +import "mojo/public/mojom/base/file_error.mojom"; +import "third_party/blink/public/mojom/blob/blob.mojom"; + +// Interface provided to the renderer to let a renderer write data to a file. +interface FileWriter { + // Write data from |blob| to the given |position| in the file being written + // to. Returns whether the operation succeeded and if so how many bytes were + // written. + // TODO(mek): This might need some way of reporting progress events back to + // the renderer. + Write(uint64 position, Blob blob) => (mojo_base.mojom.FileError result, + uint64 bytes_written); + + // Changes the length of the file to be |length|. If |length| is larger than + // the current size of the file, the file will be extended, and the extended + // part is filled with null bytes. + Truncate(uint64 length) => (mojo_base.mojom.FileError result); +};
diff --git a/third_party/blink/renderer/core/frame/visual_viewport.cc b/third_party/blink/renderer/core/frame/visual_viewport.cc index 3d340f4..1c41a40 100644 --- a/third_party/blink/renderer/core/frame/visual_viewport.cc +++ b/third_party/blink/renderer/core/frame/visual_viewport.cc
@@ -49,6 +49,7 @@ #include "third_party/blink/renderer/core/page/page.h" #include "third_party/blink/renderer/core/paint/compositing/paint_layer_compositor.h" #include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h" +#include "third_party/blink/renderer/core/paint/paint_property_tree_builder.h" #include "third_party/blink/renderer/core/probe/core_probes.h" #include "third_party/blink/renderer/core/scroll/scroll_animator_base.h" #include "third_party/blink/renderer/core/scroll/scrollbar.h" @@ -56,6 +57,9 @@ #include "third_party/blink/renderer/platform/geometry/double_rect.h" #include "third_party/blink/renderer/platform/geometry/float_size.h" #include "third_party/blink/renderer/platform/graphics/graphics_layer.h" +#include "third_party/blink/renderer/platform/graphics/paint/clip_paint_property_node.h" +#include "third_party/blink/renderer/platform/graphics/paint/effect_paint_property_node.h" +#include "third_party/blink/renderer/platform/graphics/paint/transform_paint_property_node.h" #include "third_party/blink/renderer/platform/histogram.h" #include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h" @@ -84,8 +88,11 @@ } void VisualViewport::UpdatePaintPropertyNodes( - scoped_refptr<const TransformPaintPropertyNode> transform_parent, - scoped_refptr<const ScrollPaintPropertyNode> scroll_parent) { + PaintPropertyTreeBuilderFragmentContext& context) { + auto* transform_parent = context.current.transform; + auto* scroll_parent = context.current.scroll; + auto* effect_parent = context.current_effect; + DCHECK(transform_parent); DCHECK(scroll_parent); @@ -156,6 +163,49 @@ } } + if (overlay_scrollbar_horizontal_) { + EffectPaintPropertyNode::State state; + state.local_transform_space = transform_parent; + state.direct_compositing_reasons = + CompositingReason::kActiveOpacityAnimation; + state.compositor_element_id = + GetScrollbarElementId(ScrollbarOrientation::kHorizontalScrollbar); + if (!horizontal_scrollbar_effect_node_) { + horizontal_scrollbar_effect_node_ = + EffectPaintPropertyNode::Create(*effect_parent, std::move(state)); + } else { + horizontal_scrollbar_effect_node_->Update(*effect_parent, + std::move(state)); + } + + overlay_scrollbar_horizontal_->SetLayerState( + PropertyTreeState(transform_parent, context.current.clip, + horizontal_scrollbar_effect_node_.get()), + IntPoint(overlay_scrollbar_horizontal_->GetPosition().X(), + overlay_scrollbar_horizontal_->GetPosition().Y())); + } + + if (overlay_scrollbar_vertical_) { + EffectPaintPropertyNode::State state; + state.local_transform_space = transform_parent; + state.direct_compositing_reasons = + CompositingReason::kActiveOpacityAnimation; + state.compositor_element_id = + GetScrollbarElementId(ScrollbarOrientation::kVerticalScrollbar); + if (!vertical_scrollbar_effect_node_) { + vertical_scrollbar_effect_node_ = + EffectPaintPropertyNode::Create(*effect_parent, std::move(state)); + } else { + vertical_scrollbar_effect_node_->Update(*effect_parent, std::move(state)); + } + + overlay_scrollbar_vertical_->SetLayerState( + PropertyTreeState(transform_parent, context.current.clip, + vertical_scrollbar_effect_node_.get()), + IntPoint(overlay_scrollbar_vertical_->GetPosition().X(), + overlay_scrollbar_vertical_->GetPosition().Y())); + } + if (inner_viewport_scroll_layer_) { inner_viewport_scroll_layer_->SetLayerState( PropertyTreeState(translation_transform_node_.get(), @@ -507,27 +557,6 @@ if (VisualViewportSuppliesScrollbars() && !GetPage().GetSettings().GetHideScrollbars()) { - if (!overlay_scrollbar_horizontal_->Parent()) { - inner_viewport_container_layer_->AddChild( - overlay_scrollbar_horizontal_.get()); - if (RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled()) { - // TODO(pdr): The viewport overlay scrollbars do not have the correct - // paint properties. See: https://crbug.com/836910 - overlay_scrollbar_horizontal_->SetLayerState( - PropertyTreeState(PropertyTreeState::Root()), IntPoint()); - } - } - if (!overlay_scrollbar_vertical_->Parent()) { - inner_viewport_container_layer_->AddChild( - overlay_scrollbar_vertical_.get()); - if (RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled()) { - // TODO(pdr): The viewport overlay scrollbars do not have the correct - // paint properties. See: https://crbug.com/836910 - overlay_scrollbar_vertical_->SetLayerState( - PropertyTreeState(PropertyTreeState::Root()), IntPoint()); - } - } - SetupScrollbar(kHorizontalScrollbar); SetupScrollbar(kVerticalScrollbar); } else { @@ -551,7 +580,11 @@ std::unique_ptr<ScrollingCoordinator::ScrollbarLayerGroup>& scrollbar_layer_group = is_horizontal ? scrollbar_layer_group_horizontal_ : scrollbar_layer_group_vertical_; - + if (!scrollbar_graphics_layer->Parent()) { + inner_viewport_container_layer_->AddChild(scrollbar_graphics_layer); + scrollbar_graphics_layer->SetLayerState( + PropertyTreeState(PropertyTreeState::Root()), IntPoint()); + } ScrollbarThemeOverlay& theme = ScrollbarThemeOverlay::MobileTheme(); int thumb_thickness = clampTo<int>( std::floor(GetPage().GetChromeClient().WindowToViewportScalar(
diff --git a/third_party/blink/renderer/core/frame/visual_viewport.h b/third_party/blink/renderer/core/frame/visual_viewport.h index 7fe7a393..0eefed3 100644 --- a/third_party/blink/renderer/core/frame/visual_viewport.h +++ b/third_party/blink/renderer/core/frame/visual_viewport.h
@@ -54,8 +54,10 @@ class IntSize; class LocalFrame; class Page; +class EffectPaintPropertyNode; class ScrollPaintPropertyNode; class TransformPaintPropertyNode; +struct PaintPropertyTreeBuilderFragmentContext; // Represents the visual viewport the user is currently seeing the page through. // This class corresponds to the InnerViewport on the compositor. It is a @@ -261,8 +263,7 @@ // container, page scale layer, inner viewport scroll layer) to reference // these nodes. void UpdatePaintPropertyNodes( - scoped_refptr<const TransformPaintPropertyNode> transform_parent, - scoped_refptr<const ScrollPaintPropertyNode> scroll_parent); + PaintPropertyTreeBuilderFragmentContext& context); private: explicit VisualViewport(Page&); @@ -331,6 +332,8 @@ scoped_refptr<TransformPaintPropertyNode> scale_transform_node_; scoped_refptr<TransformPaintPropertyNode> translation_transform_node_; scoped_refptr<ScrollPaintPropertyNode> scroll_node_; + scoped_refptr<EffectPaintPropertyNode> horizontal_scrollbar_effect_node_; + scoped_refptr<EffectPaintPropertyNode> vertical_scrollbar_effect_node_; // Offset of the visual viewport from the main frame's origin, in CSS pixels. ScrollOffset offset_;
diff --git a/third_party/blink/renderer/core/frame/visual_viewport_test.cc b/third_party/blink/renderer/core/frame/visual_viewport_test.cc index 24acefd..73ed9cb 100644 --- a/third_party/blink/renderer/core/frame/visual_viewport_test.cc +++ b/third_party/blink/renderer/core/frame/visual_viewport_test.cc
@@ -40,6 +40,7 @@ #include "third_party/blink/renderer/core/paint/compositing/paint_layer_compositor.h" #include "third_party/blink/renderer/core/paint/paint_layer.h" #include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h" +#include "third_party/blink/renderer/core/scroll/scrollbar_theme_overlay.h" #include "third_party/blink/renderer/core/testing/sim/sim_request.h" #include "third_party/blink/renderer/core/testing/sim/sim_test.h" #include "third_party/blink/renderer/platform/geometry/double_point.h" @@ -2232,6 +2233,49 @@ document->View()->SetTracksPaintInvalidations(false); } +// Ensure we create effect node for scrollbar properly. +TEST_P(VisualViewportTest, EnsureEffectNodeForScrollbars) { + if (!RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled()) + return; + + InitializeWithAndroidSettings(); + WebView()->Resize(IntSize(400, 400)); + NavigateTo("about:blank"); + WebView()->UpdateAllLifecyclePhases(); + + VisualViewport& visual_viewport = GetFrame()->GetPage()->GetVisualViewport(); + auto* vertical_scrollbar = visual_viewport.LayerForVerticalScrollbar(); + auto* horizontal_scrollbar = visual_viewport.LayerForHorizontalScrollbar(); + ASSERT_TRUE(vertical_scrollbar); + ASSERT_TRUE(horizontal_scrollbar); + + auto& vertical_scrollbar_state = vertical_scrollbar->GetPropertyTreeState(); + auto& horizontal_scrollbar_state = + horizontal_scrollbar->GetPropertyTreeState(); + + ScrollbarThemeOverlay& theme = ScrollbarThemeOverlay::MobileTheme(); + int scrollbar_thickness = clampTo<int>(std::floor( + GetFrame()->GetPage()->GetChromeClient().WindowToViewportScalar( + theme.ScrollbarThickness(kRegularScrollbar)))); + + EXPECT_TRUE(vertical_scrollbar_state.Effect()); + EXPECT_EQ(vertical_scrollbar_state.Effect()->GetCompositorElementId(), + visual_viewport.GetScrollbarElementId( + ScrollbarOrientation::kVerticalScrollbar)); + EXPECT_EQ(vertical_scrollbar->GetOffsetFromTransformNode(), + IntPoint(400 - scrollbar_thickness, 0)); + + EXPECT_TRUE(horizontal_scrollbar_state.Effect()); + EXPECT_EQ(horizontal_scrollbar_state.Effect()->GetCompositorElementId(), + visual_viewport.GetScrollbarElementId( + ScrollbarOrientation::kHorizontalScrollbar)); + EXPECT_EQ(horizontal_scrollbar->GetOffsetFromTransformNode(), + IntPoint(0, 400 - scrollbar_thickness)); + + EXPECT_EQ(vertical_scrollbar_state.Effect()->Parent(), + horizontal_scrollbar_state.Effect()->Parent()); +} + // Make sure we don't crash when the visual viewport's height is 0. This can // happen transiently in autoresize mode and cause a crash. This test passes if // it doesn't crash.
diff --git a/third_party/blink/renderer/core/inspector/inspector_dom_snapshot_agent.cc b/third_party/blink/renderer/core/inspector/inspector_dom_snapshot_agent.cc index cddcb5b2..350b735 100644 --- a/third_party/blink/renderer/core/inspector/inspector_dom_snapshot_agent.cc +++ b/third_party/blink/renderer/core/inspector/inspector_dom_snapshot_agent.cc
@@ -826,19 +826,19 @@ if (layout_object->IsText()) { LayoutText* layout_text = ToLayoutText(layout_object); layout_tree_node->setLayoutText(layout_text->GetText()); - if (layout_text->HasTextBoxes()) { + Vector<LayoutText::TextBoxInfo> text_boxes = layout_text->GetTextBoxInfo(); + if (!text_boxes.IsEmpty()) { std::unique_ptr<protocol::Array<protocol::DOMSnapshot::InlineTextBox>> inline_text_nodes = protocol::Array<protocol::DOMSnapshot::InlineTextBox>::create(); - for (const InlineTextBox* text_box : layout_text->TextBoxes()) { - FloatRect local_coords_text_box_rect(text_box->FrameRect()); + for (const LayoutText::TextBoxInfo& text_box : text_boxes) { FloatRect absolute_coords_text_box_rect = - layout_object->LocalToAbsoluteQuad(local_coords_text_box_rect) + layout_object->LocalToAbsoluteQuad(FloatRect(text_box.local_rect)) .BoundingBox(); inline_text_nodes->addItem( protocol::DOMSnapshot::InlineTextBox::create() - .setStartCharacterIndex(text_box->Start()) - .setNumCharacters(text_box->Len()) + .setStartCharacterIndex(text_box.dom_start_offset) + .setNumCharacters(text_box.dom_length) .setBoundingBox( BuildRectForFloatRect(absolute_coords_text_box_rect)) .build());
diff --git a/third_party/blink/renderer/core/layout/layout_object.cc b/third_party/blink/renderer/core/layout/layout_object.cc index 76c542e..073dc719 100644 --- a/third_party/blink/renderer/core/layout/layout_object.cc +++ b/third_party/blink/renderer/core/layout/layout_object.cc
@@ -1056,9 +1056,10 @@ return ToLayoutBlock(object); } -FloatRect LayoutObject::AbsoluteBoundingBoxFloatRect() const { +FloatRect LayoutObject::AbsoluteBoundingBoxFloatRect( + MapCoordinatesFlags flags) const { Vector<FloatQuad> quads; - AbsoluteQuads(quads); + AbsoluteQuads(quads, flags); size_t n = quads.size(); if (n == 0)
diff --git a/third_party/blink/renderer/core/layout/layout_object.h b/third_party/blink/renderer/core/layout/layout_object.h index 087a72af..c41cd25d 100644 --- a/third_party/blink/renderer/core/layout/layout_object.h +++ b/third_party/blink/renderer/core/layout/layout_object.h
@@ -1384,7 +1384,7 @@ virtual void AbsoluteRects(Vector<IntRect>&, const LayoutPoint&) const {} - FloatRect AbsoluteBoundingBoxFloatRect() const; + FloatRect AbsoluteBoundingBoxFloatRect(MapCoordinatesFlags = 0) const; // This returns an IntRect enclosing this object. If this object has an // integral size and the position has fractional values, the resultant // IntRect can be larger than the integral size.
diff --git a/third_party/blink/renderer/core/layout/layout_text.cc b/third_party/blink/renderer/core/layout/layout_text.cc index afd755a..49c5c716 100644 --- a/third_party/blink/renderer/core/layout/layout_text.cc +++ b/third_party/blink/renderer/core/layout/layout_text.cc
@@ -238,6 +238,32 @@ text_boxes_.DeleteLineBoxes(); } +Vector<LayoutText::TextBoxInfo> LayoutText::GetTextBoxInfo() const { + Vector<TextBoxInfo> results; + if (RuntimeEnabledFeatures::LayoutNGEnabled()) { + auto fragments = NGPaintFragment::InlineFragmentsFor(this); + if (fragments.IsInLayoutNGInlineFormattingContext()) { + for (const NGPaintFragment* fragment : fragments) { + const NGPhysicalTextFragment& text_fragment = + ToNGPhysicalTextFragment(fragment->PhysicalFragment()); + results.push_back(TextBoxInfo{ + {fragment->InlineOffsetToContainerBox().ToLayoutPoint(), + text_fragment.Size().ToLayoutSize()}, + // TODO(kojii): Compute DOM offset, not text content offset. + text_fragment.StartOffset(), + text_fragment.Length()}); + } + return results; + } + } + + for (const InlineTextBox* text_box : TextBoxes()) { + results.push_back( + TextBoxInfo{text_box->FrameRect(), text_box->Start(), text_box->Len()}); + } + return results; +} + base::Optional<FloatPoint> LayoutText::GetUpperLeftCorner() const { DCHECK(!IsBR()); if (HasLegacyTextBoxes()) {
diff --git a/third_party/blink/renderer/core/layout/layout_text.h b/third_party/blink/renderer/core/layout/layout_text.h index 8b1fef2..fcf74cef 100644 --- a/third_party/blink/renderer/core/layout/layout_text.h +++ b/third_party/blink/renderer/core/layout/layout_text.h
@@ -225,6 +225,14 @@ // All callers should call HasTextBoxes instead, and take NG into account. bool HasLegacyTextBoxes() const { return FirstTextBox(); } + // Compute the rect and offset of text boxes for this LayoutText. + struct TextBoxInfo { + LayoutRect local_rect; + unsigned dom_start_offset; + unsigned dom_length; + }; + Vector<TextBoxInfo> GetTextBoxInfo() const; + // Returns the Position in DOM that corresponds to the given offset in the // |text_| string. // TODO(layout-dev): Fix it when text-transform changes text length.
diff --git a/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc b/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc index 35cd65e..76a55ce6 100644 --- a/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc +++ b/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc
@@ -61,8 +61,7 @@ PaintPropertyTreeBuilderFragmentContext& context = full_context.fragments[0]; - visual_viewport.UpdatePaintPropertyNodes(context.current.transform, - context.current.scroll); + visual_viewport.UpdatePaintPropertyNodes(context); context.current.transform = visual_viewport.GetScrollTranslationNode(); context.absolute_position.transform = @@ -340,6 +339,11 @@ paint_offset_translation->Y()); state.flattens_inherited_transform = context_.current.should_flatten_inherited_transform; + + state.affected_by_outer_viewport_bounds_delta = + object_.Style()->GetPosition() == EPosition::kFixed && + !object_.Style()->Bottom().IsAuto(); + if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled() || RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled()) state.rendering_context_id = context_.current.rendering_context_id;
diff --git a/third_party/blink/renderer/devtools/front_end/bindings/BreakpointManager.js b/third_party/blink/renderer/devtools/front_end/bindings/BreakpointManager.js index 82ae82e..c54d808 100644 --- a/third_party/blink/renderer/devtools/front_end/bindings/BreakpointManager.js +++ b/third_party/blink/renderer/devtools/front_end/bindings/BreakpointManager.js
@@ -43,7 +43,7 @@ this._targetManager = targetManager; this._debuggerWorkspaceBinding = debuggerWorkspaceBinding; - /** @type {!Map<!Workspace.UISourceCode, !Map<number, !Map<number, !Array<!Bindings.BreakpointManager.Breakpoint>>>>} */ + /** @type {!Map<!Workspace.UISourceCode, !Map<string, !Bindings.BreakpointManager.BreakpointLocation>>} */ this._breakpointsForUISourceCode = new Map(); /** @type {!Map<string, !Bindings.BreakpointManager.Breakpoint>} */ this._breakpointByStorageId = new Map(); @@ -158,27 +158,12 @@ } /** - * @param {!Workspace.UISourceCode} uiSourceCode - * @param {number} lineNumber - * @return {!Array<!Bindings.BreakpointManager.Breakpoint>} + * @param {!Workspace.UILocation} uiLocation + * @return {?Bindings.BreakpointManager.BreakpointLocation} */ - findBreakpoints(uiSourceCode, lineNumber) { - const breakpoints = this._breakpointsForUISourceCode.get(uiSourceCode); - const lineBreakpoints = breakpoints ? breakpoints.get(lineNumber) : null; - return lineBreakpoints ? lineBreakpoints.valuesArray()[0] : []; - } - - /** - * @param {!Workspace.UISourceCode} uiSourceCode - * @param {number} lineNumber - * @param {number} columnNumber - * @return {?Bindings.BreakpointManager.Breakpoint} - */ - findBreakpoint(uiSourceCode, lineNumber, columnNumber) { - const breakpoints = this._breakpointsForUISourceCode.get(uiSourceCode); - const lineBreakpoints = breakpoints ? breakpoints.get(lineNumber) : null; - const columnBreakpoints = lineBreakpoints ? lineBreakpoints.get(columnNumber) : null; - return columnBreakpoints ? columnBreakpoints[0] : null; + findBreakpoint(uiLocation) { + const breakpoints = this._breakpointsForUISourceCode.get(uiLocation.uiSourceCode); + return breakpoints ? (breakpoints.get(uiLocation.id())) || null : null; } /** @@ -236,93 +221,23 @@ /** * @param {!Workspace.UISourceCode} uiSourceCode - * @return {!Array.<!Bindings.BreakpointManager.Breakpoint>} - */ - breakpointsForUISourceCode(uiSourceCode) { - let result = []; - const uiSourceCodeBreakpoints = this._breakpointsForUISourceCode.get(uiSourceCode); - const breakpoints = uiSourceCodeBreakpoints ? uiSourceCodeBreakpoints.valuesArray() : []; - for (let i = 0; i < breakpoints.length; ++i) { - const lineBreakpoints = breakpoints[i]; - const columnBreakpointArrays = lineBreakpoints ? lineBreakpoints.valuesArray() : []; - result = result.concat.apply(result, columnBreakpointArrays); - } - return result; - } - - /** - * @return {!Array.<!Bindings.BreakpointManager.Breakpoint>} - */ - _allBreakpoints() { - let result = []; - const uiSourceCodes = this._breakpointsForUISourceCode.keysArray(); - for (let i = 0; i < uiSourceCodes.length; ++i) - result = result.concat(this.breakpointsForUISourceCode(uiSourceCodes[i])); - return result; - } - - /** - * @param {!Workspace.UISourceCode} uiSourceCode - * @return {!Array.<!{breakpoint: !Bindings.BreakpointManager.Breakpoint, uiLocation: !Workspace.UILocation}>} + * @return {!Array<!Bindings.BreakpointManager.BreakpointLocation>} */ breakpointLocationsForUISourceCode(uiSourceCode) { - const uiSourceCodeBreakpoints = this._breakpointsForUISourceCode.get(uiSourceCode); - const lineNumbers = uiSourceCodeBreakpoints ? uiSourceCodeBreakpoints.keysArray() : []; - const result = []; - for (let i = 0; i < lineNumbers.length; ++i) { - const lineBreakpoints = uiSourceCodeBreakpoints.get(lineNumbers[i]); - const columnNumbers = lineBreakpoints.keysArray(); - for (let j = 0; j < columnNumbers.length; ++j) { - const columnBreakpoints = lineBreakpoints.get(columnNumbers[j]); - const lineNumber = parseInt(lineNumbers[i], 10); - const columnNumber = parseInt(columnNumbers[j], 10); - for (let k = 0; k < columnBreakpoints.length; ++k) { - const breakpoint = columnBreakpoints[k]; - const uiLocation = uiSourceCode.uiLocation(lineNumber, columnNumber); - result.push({breakpoint: breakpoint, uiLocation: uiLocation}); - } - } - } - return result; + const breakpoints = this._breakpointsForUISourceCode.get(uiSourceCode); + return breakpoints ? Array.from(breakpoints.values()) : []; } /** - * @return {!Array.<!{breakpoint: !Bindings.BreakpointManager.Breakpoint, uiLocation: !Workspace.UILocation}>} + * @return {!Array<!Bindings.BreakpointManager.BreakpointLocation>} */ allBreakpointLocations() { let result = []; - const uiSourceCodes = this._breakpointsForUISourceCode.keysArray(); - for (let i = 0; i < uiSourceCodes.length; ++i) - result = result.concat(this.breakpointLocationsForUISourceCode(uiSourceCodes[i])); + for (const breakpoints of this._breakpointsForUISourceCode.values()) + result = result.concat(Array.from(breakpoints.values())); return result; } - /** - * @param {boolean} toggleState - */ - toggleAllBreakpoints(toggleState) { - const breakpoints = this._allBreakpoints(); - for (let i = 0; i < breakpoints.length; ++i) - breakpoints[i].setEnabled(toggleState); - } - - removeAllBreakpoints() { - const breakpoints = this._allBreakpoints(); - for (let i = 0; i < breakpoints.length; ++i) - breakpoints[i].remove(false /* keepInStorage */); - } - - /** - * @param {!Set<!Bindings.BreakpointManager.Breakpoint>} selectedBreakpoints - */ - removeOtherBreakpoints(selectedBreakpoints) { - const allBreakpoints = this._allBreakpoints(); - allBreakpoints.forEach(breakpoint => { - if (!selectedBreakpoints.has(breakpoint)) - breakpoint.remove(false /* keepInStorage */); - }); - } - _projectRemoved(event) { const project = /** @type {!Workspace.Project} */ (event.data); const uiSourceCodes = project.uiSourceCodes(); @@ -350,19 +265,9 @@ breakpoints = new Map(); this._breakpointsForUISourceCode.set(uiLocation.uiSourceCode, breakpoints); } - let lineBreakpoints = breakpoints.get(uiLocation.lineNumber); - if (!lineBreakpoints) { - lineBreakpoints = new Map(); - breakpoints.set(uiLocation.lineNumber, lineBreakpoints); - } - let columnBreakpoints = lineBreakpoints.get(uiLocation.columnNumber); - if (!columnBreakpoints) { - columnBreakpoints = []; - lineBreakpoints.set(uiLocation.columnNumber, columnBreakpoints); - } - columnBreakpoints.push(breakpoint); - this.dispatchEventToListeners( - Bindings.BreakpointManager.Events.BreakpointAdded, {breakpoint: breakpoint, uiLocation: uiLocation}); + const breakpointLocation = {breakpoint: breakpoint, uiLocation: uiLocation}; + breakpoints.set(uiLocation.id(), breakpointLocation); + this.dispatchEventToListeners(Bindings.BreakpointManager.Events.BreakpointAdded, breakpointLocation); } /** @@ -373,20 +278,12 @@ const breakpoints = this._breakpointsForUISourceCode.get(uiLocation.uiSourceCode); if (!breakpoints) return; - - const lineBreakpoints = breakpoints.get(uiLocation.lineNumber); - if (!lineBreakpoints) + const breakpointLocation = breakpoints.get(uiLocation.id()) || null; + if (!breakpointLocation) return; - const columnBreakpoints = lineBreakpoints.get(uiLocation.columnNumber); - if (!columnBreakpoints) - return; - columnBreakpoints.remove(breakpoint); - if (!columnBreakpoints.length) - lineBreakpoints.remove(uiLocation.columnNumber); - if (!lineBreakpoints.size) - breakpoints.remove(uiLocation.lineNumber); - if (!breakpoints.size) - this._breakpointsForUISourceCode.remove(uiLocation.uiSourceCode); + breakpoints.delete(uiLocation.id()); + if (breakpoints.size === 0) + this._breakpointsForUISourceCode.delete(uiLocation.uiSourceCode); this.dispatchEventToListeners( Bindings.BreakpointManager.Events.BreakpointRemoved, {breakpoint: breakpoint, uiLocation: uiLocation}); } @@ -398,6 +295,12 @@ BreakpointRemoved: Symbol('breakpoint-removed') }; +/** @typedef {{ + * breakpoint: !Bindings.BreakpointManager.Breakpoint, + * uiLocation: !Workspace.UILocation + * }} + */ +Bindings.BreakpointManager.BreakpointLocation; /** * @unrestricted @@ -863,9 +766,8 @@ const uiLocation = this._debuggerWorkspaceBinding.rawLocationToUILocation(location); if (!uiLocation) return false; - const breakpoint = this._breakpoint._breakpointManager.findBreakpoint( - uiLocation.uiSourceCode, uiLocation.lineNumber, uiLocation.columnNumber); - if (breakpoint && breakpoint !== this._breakpoint) { + const breakpointLocation = this._breakpoint._breakpointManager.findBreakpoint(uiLocation); + if (breakpointLocation && breakpointLocation.breakpoint !== this._breakpoint) { // location clash this._breakpoint.remove(false /* keepInStorage */); return false;
diff --git a/third_party/blink/renderer/devtools/front_end/bindings/ResourceScriptMapping.js b/third_party/blink/renderer/devtools/front_end/bindings/ResourceScriptMapping.js index 3dcdfa18..92bcbcf 100644 --- a/third_party/blink/renderer/devtools/front_end/bindings/ResourceScriptMapping.js +++ b/third_party/blink/renderer/devtools/front_end/bindings/ResourceScriptMapping.js
@@ -306,7 +306,8 @@ if (!this._script) return; const debuggerModel = this._resourceScriptMapping._debuggerModel; - const breakpoints = Bindings.breakpointManager.breakpointsForUISourceCode(this._uiSourceCode); + const breakpoints = Bindings.breakpointManager.breakpointLocationsForUISourceCode(this._uiSourceCode) + .map(breakpointLocation => breakpointLocation.breakpoint); const source = this._uiSourceCode.workingCopy(); debuggerModel.setScriptSource(this._script.scriptId, source, scriptSourceWasSet.bind(this));
diff --git a/third_party/blink/renderer/devtools/front_end/persistence/Persistence.js b/third_party/blink/renderer/devtools/front_end/persistence/Persistence.js index 98a938ef..14accb9 100644 --- a/third_party/blink/renderer/devtools/front_end/persistence/Persistence.js +++ b/third_party/blink/renderer/devtools/front_end/persistence/Persistence.js
@@ -275,7 +275,8 @@ * @param {!Workspace.UISourceCode} to */ _moveBreakpoints(from, to) { - const breakpoints = this._breakpointManager.breakpointsForUISourceCode(from); + const breakpoints = this._breakpointManager.breakpointLocationsForUISourceCode(from).map( + breakpointLocation => breakpointLocation.breakpoint); for (const breakpoint of breakpoints) { breakpoint.remove(false /* keepInStorage */); this._breakpointManager.setBreakpoint(
diff --git a/third_party/blink/renderer/devtools/front_end/sources/DebuggerPausedMessage.js b/third_party/blink/renderer/devtools/front_end/sources/DebuggerPausedMessage.js index 4ad256df..f70671d 100644 --- a/third_party/blink/renderer/devtools/front_end/sources/DebuggerPausedMessage.js +++ b/third_party/blink/renderer/devtools/front_end/sources/DebuggerPausedMessage.js
@@ -108,9 +108,7 @@ messageWrapper = buildWrapper(Common.UIString('Paused before potential out-of-memory crash')); } else if (details.callFrames.length) { const uiLocation = debuggerWorkspaceBinding.rawLocationToUILocation(details.callFrames[0].location()); - const breakpoint = uiLocation ? - breakpointManager.findBreakpoint(uiLocation.uiSourceCode, uiLocation.lineNumber, uiLocation.columnNumber) : - null; + const breakpoint = uiLocation ? breakpointManager.findBreakpoint(uiLocation) : null; const defaultText = breakpoint ? Common.UIString('Paused on breakpoint') : Common.UIString('Debugger paused'); messageWrapper = buildWrapper(defaultText); } else {
diff --git a/third_party/blink/renderer/devtools/front_end/sources/JavaScriptBreakpointsSidebarPane.js b/third_party/blink/renderer/devtools/front_end/sources/JavaScriptBreakpointsSidebarPane.js index 7d7f1e1..22c9ab0 100644 --- a/third_party/blink/renderer/devtools/front_end/sources/JavaScriptBreakpointsSidebarPane.js +++ b/third_party/blink/renderer/devtools/front_end/sources/JavaScriptBreakpointsSidebarPane.js
@@ -80,7 +80,7 @@ const hasEnabled = locations.some(location => location.breakpoint.enabled()); const hasDisabled = locations.some(location => !location.breakpoint.enabled()); promises.push(this._resetEntry(/** @type {!Element}*/ (entry), uiLocation, isSelected, hasEnabled, hasDisabled)); - + entry[Sources.JavaScriptBreakpointsSidebarPane._breakpointLocationsSymbol] = locations; if (isSelected) shouldShowView = true; entry = entry.nextSibling; @@ -94,8 +94,7 @@ UI.viewManager.showView('sources.jsBreakpoints'); this._listElement.classList.toggle( 'breakpoints-list-deactivated', !Common.moduleSetting('breakpointsActive').get()); - Promise.all(promises).then(() => this._didUpdateForTest()); - return Promise.resolve(); + return Promise.all(promises).then(() => this._didUpdateForTest()); } /** @@ -135,24 +134,20 @@ /** * @param {!Event} event - * @return {?Workspace.UILocation} + * @return {!Array<!Bindings.BreakpointManager.BreakpointLocation>} */ - _uiLocationFromEvent(event) { + _breakpointLocations(event) { const node = event.target.enclosingNodeOrSelfWithClass('breakpoint-entry'); if (!node) - return null; - return node[Sources.JavaScriptBreakpointsSidebarPane._locationSymbol] || null; + return []; + return node[Sources.JavaScriptBreakpointsSidebarPane._breakpointLocationsSymbol] || []; } /** * @param {!Event} event */ _breakpointCheckboxClicked(event) { - const uiLocation = this._uiLocationFromEvent(event); - if (!uiLocation) - return; - - const breakpoints = this._breakpointManager.findBreakpoints(uiLocation.uiSourceCode, uiLocation.lineNumber); + const breakpoints = this._breakpointLocations(event).map(breakpointLocation => breakpointLocation.breakpoint); const newState = event.target.checkboxElement.checked; for (const breakpoint of breakpoints) breakpoint.setEnabled(newState); @@ -163,7 +158,12 @@ * @param {!Event} event */ _revealLocation(event) { - const uiLocation = this._uiLocationFromEvent(event); + const uiLocations = this._breakpointLocations(event).map(breakpointLocation => breakpointLocation.uiLocation); + let uiLocation = null; + for (const uiLocationCandidate of uiLocations) { + if (!uiLocation || uiLocationCandidate.columnNumber < uiLocation.columnNumber) + uiLocation = uiLocationCandidate; + } if (uiLocation) Common.Revealer.reveal(uiLocation); } @@ -172,11 +172,7 @@ * @param {!Event} event */ _breakpointContextMenu(event) { - const uiLocation = this._uiLocationFromEvent(event); - if (!uiLocation) - return; - - const breakpoints = this._breakpointManager.findBreakpoints(uiLocation.uiSourceCode, uiLocation.lineNumber); + const breakpoints = this._breakpointLocations(event).map(breakpointLocation => breakpointLocation.breakpoint); const contextMenu = new UI.ContextMenu(event); const removeEntryTitle = breakpoints.length > 1 ? Common.UIString('Remove all breakpoints in line') : @@ -192,25 +188,44 @@ if (breakpoints.some(breakpoint => !breakpoint.enabled())) { const enableTitle = Common.UIString('Enable all breakpoints'); - contextMenu.defaultSection().appendItem( - enableTitle, this._breakpointManager.toggleAllBreakpoints.bind(this._breakpointManager, true)); + contextMenu.defaultSection().appendItem(enableTitle, this._toggleAllBreakpoints.bind(this, true)); } if (breakpoints.some(breakpoint => breakpoint.enabled())) { const disableTitle = Common.UIString('Disable all breakpoints'); - contextMenu.defaultSection().appendItem( - disableTitle, this._breakpointManager.toggleAllBreakpoints.bind(this._breakpointManager, false)); + contextMenu.defaultSection().appendItem(disableTitle, this._toggleAllBreakpoints.bind(this, false)); } const removeAllTitle = Common.UIString('Remove all breakpoints'); - contextMenu.defaultSection().appendItem( - removeAllTitle, this._breakpointManager.removeAllBreakpoints.bind(this._breakpointManager)); + contextMenu.defaultSection().appendItem(removeAllTitle, this._removeAllBreakpoints.bind(this)); const removeOtherTitle = Common.UIString('Remove other breakpoints'); contextMenu.defaultSection().appendItem( - removeOtherTitle, - this._breakpointManager.removeOtherBreakpoints.bind(this._breakpointManager, new Set(breakpoints))); + removeOtherTitle, this._removeOtherBreakpoints.bind(this, new Set(breakpoints))); contextMenu.show(); } /** + * @param {boolean} toggleState + */ + _toggleAllBreakpoints(toggleState) { + for (const breakpointLocation of this._breakpointManager.allBreakpointLocations()) + breakpointLocation.breakpoint.setEnabled(toggleState); + } + + _removeAllBreakpoints() { + for (const breakpointLocation of this._breakpointManager.allBreakpointLocations()) + breakpointLocation.breakpoint.remove(false /* keepInStorage */); + } + + /** + * @param {!Set<!Bindings.BreakpointManager.Breakpoint>} selectedBreakpoints + */ + _removeOtherBreakpoints(selectedBreakpoints) { + for (const breakpointLocation of this._breakpointManager.allBreakpointLocations()) { + if (!selectedBreakpoints.has(breakpointLocation.breakpoint)) + breakpointLocation.breakpoint.remove(false /* keepInStorage */); + } + } + + /** * @override * @param {?Object} object */ @@ -225,3 +240,4 @@ Sources.JavaScriptBreakpointsSidebarPane._locationSymbol = Symbol('location'); Sources.JavaScriptBreakpointsSidebarPane._checkboxLabelSymbol = Symbol('checkbox-label'); Sources.JavaScriptBreakpointsSidebarPane._snippetElementSymbol = Symbol('snippet-element'); +Sources.JavaScriptBreakpointsSidebarPane._breakpointLocationsSymbol = Symbol('locations');
diff --git a/third_party/blink/renderer/devtools/front_end/sources_test_runner/DebuggerTestRunner.js b/third_party/blink/renderer/devtools/front_end/sources_test_runner/DebuggerTestRunner.js index 3043215..da41b42 100644 --- a/third_party/blink/renderer/devtools/front_end/sources_test_runner/DebuggerTestRunner.js +++ b/third_party/blink/renderer/devtools/front_end/sources_test_runner/DebuggerTestRunner.js
@@ -463,7 +463,11 @@ SourcesTestRunner.removeBreakpoint = function(sourceFrame, lineNumber) { const debuggerPlugin = SourcesTestRunner.debuggerPlugin(sourceFrame); - debuggerPlugin._breakpointManager.findBreakpoints(sourceFrame._uiSourceCode, lineNumber)[0].remove(); + const breakpointLocations = debuggerPlugin._breakpointManager.allBreakpointLocations(); + const breakpointLocation = breakpointLocations.find( + breakpointLocation => breakpointLocation.uiLocation.uiSourceCode === sourceFrame._uiSourceCode && + breakpointLocation.uiLocation.lineNumber === lineNumber); + breakpointLocation.breakpoint.remove(); }; SourcesTestRunner.createNewBreakpoint = function(sourceFrame, lineNumber, condition, enabled) { @@ -490,7 +494,7 @@ if (!waitUntilResolved) return; - for (const breakpoint of Bindings.breakpointManager._allBreakpoints()) { + for (const {breakpoint} of Bindings.breakpointManager.allBreakpointLocations()) { if (breakpoint._fakePrimaryLocation && breakpoint.enabled()) return SourcesTestRunner.waitBreakpointSidebarPane(); } @@ -702,7 +706,7 @@ } function checkIfReady() { - for (const breakpoint of Bindings.breakpointManager._allBreakpoints()) { + for (const {breakpoint} of Bindings.breakpointManager.allBreakpointLocations()) { if (breakpoint._fakePrimaryLocation && breakpoint.enabled()) return waitUpdate().then(checkIfReady); }
diff --git a/third_party/blink/renderer/modules/accessibility/ax_selection.cc b/third_party/blink/renderer/modules/accessibility/ax_selection.cc index 1446e00..f0b8908 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_selection.cc +++ b/third_party/blink/renderer/modules/accessibility/ax_selection.cc
@@ -71,6 +71,54 @@ return selection_; } +// static +const AXSelection AXSelection::FromSelection( + const SelectionInDOMTree& selection, + const AXSelectionBehavior selection_behavior) { + if (selection.IsNone()) + return {}; + DCHECK(selection.AssertValid()); + + const Position dom_base = selection.Base(); + const Position dom_extent = selection.Extent(); + const TextAffinity base_affinity = TextAffinity::kDownstream; + const TextAffinity extent_affinity = selection.Affinity(); + + AXPositionAdjustmentBehavior base_adjustment = + AXPositionAdjustmentBehavior::kMoveRight; + AXPositionAdjustmentBehavior extent_adjustment = + AXPositionAdjustmentBehavior::kMoveRight; + switch (selection_behavior) { + case AXSelectionBehavior::kShrinkToValidDOMRange: + if (selection.IsBaseFirst()) { + base_adjustment = AXPositionAdjustmentBehavior::kMoveRight; + extent_adjustment = AXPositionAdjustmentBehavior::kMoveLeft; + } else { + base_adjustment = AXPositionAdjustmentBehavior::kMoveLeft; + extent_adjustment = AXPositionAdjustmentBehavior::kMoveRight; + } + break; + case AXSelectionBehavior::kExtendToValidDOMRange: + if (selection.IsBaseFirst()) { + base_adjustment = AXPositionAdjustmentBehavior::kMoveLeft; + extent_adjustment = AXPositionAdjustmentBehavior::kMoveRight; + } else { + base_adjustment = AXPositionAdjustmentBehavior::kMoveRight; + extent_adjustment = AXPositionAdjustmentBehavior::kMoveLeft; + } + break; + } + + const auto ax_base = + AXPosition::FromPosition(dom_base, base_affinity, base_adjustment); + const auto ax_extent = + AXPosition::FromPosition(dom_extent, extent_affinity, extent_adjustment); + + AXSelection::Builder selection_builder; + selection_builder.SetBase(ax_base).SetExtent(ax_extent); + return selection_builder.Build(); +} + AXSelection::AXSelection() : base_(), extent_() { #if DCHECK_IS_ON() dom_tree_version_ = 0; @@ -104,9 +152,9 @@ return {}; AXPositionAdjustmentBehavior base_adjustment = - AXPositionAdjustmentBehavior::kMoveLeft; + AXPositionAdjustmentBehavior::kMoveRight; AXPositionAdjustmentBehavior extent_adjustment = - AXPositionAdjustmentBehavior::kMoveLeft; + AXPositionAdjustmentBehavior::kMoveRight; switch (selection_behavior) { case AXSelectionBehavior::kShrinkToValidDOMRange: if (base_ <= extent_) {
diff --git a/third_party/blink/renderer/modules/accessibility/ax_selection.h b/third_party/blink/renderer/modules/accessibility/ax_selection.h index 122c4e0..4571bc5 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_selection.h +++ b/third_party/blink/renderer/modules/accessibility/ax_selection.h
@@ -31,6 +31,10 @@ public: class Builder; + static const AXSelection FromSelection( + const SelectionInDOMTree&, + const AXSelectionBehavior = AXSelectionBehavior::kExtendToValidDOMRange); + AXSelection(const AXSelection&) = default; AXSelection& operator=(const AXSelection&) = default; ~AXSelection() = default;
diff --git a/third_party/blink/renderer/modules/accessibility/ax_selection_test.cc b/third_party/blink/renderer/modules/accessibility/ax_selection_test.cc index 8d23a214..bcabc2dc0 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_selection_test.cc +++ b/third_party/blink/renderer/modules/accessibility/ax_selection_test.cc
@@ -6,8 +6,10 @@ #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/renderer/core/dom/node.h" +#include "third_party/blink/renderer/core/editing/frame_selection.h" #include "third_party/blink/renderer/core/editing/position.h" #include "third_party/blink/renderer/core/editing/selection_template.h" +#include "third_party/blink/renderer/core/frame/local_frame.h" #include "third_party/blink/renderer/modules/accessibility/ax_object.h" #include "third_party/blink/renderer/modules/accessibility/ax_position.h" #include "third_party/blink/renderer/modules/accessibility/testing/accessibility_selection_test.h" @@ -20,9 +22,11 @@ TEST_F(AccessibilitySelectionTest, SetSelectionInText) { SetBodyInnerHTML(R"HTML(<p id='paragraph'>Hello</p>)HTML"); + const Node* text = GetElementById("paragraph")->firstChild(); ASSERT_NE(nullptr, text); ASSERT_TRUE(text->IsTextNode()); + const AXObject* ax_static_text = GetAXObjectByElementId("paragraph")->FirstChild(); ASSERT_NE(nullptr, ax_static_text); @@ -45,9 +49,11 @@ TEST_F(AccessibilitySelectionTest, SetSelectionInTextWithWhiteSpace) { SetBodyInnerHTML(R"HTML(<p id='paragraph'> Hello</p>)HTML"); + const Node* text = GetElementById("paragraph")->firstChild(); ASSERT_NE(nullptr, text); ASSERT_TRUE(text->IsTextNode()); + const AXObject* ax_static_text = GetAXObjectByElementId("paragraph")->FirstChild(); ASSERT_NE(nullptr, ax_static_text); @@ -75,10 +81,55 @@ // |AXSelection| to valid endpoints. // +TEST_F(AccessibilitySelectionTest, SetSelectionInARIAHidden) { + SetSelectionText(R"HTML( + <div role="main"> + <p>Before aria-hidden.</p> + ^<p aria-hidden="true">Aria-hidden 1.</p> + <p>In the middle of aria-hidden.</p> + <p aria-hidden="true">Aria-hidden 2.</p>| + <p>After aria-hidden.</p> + </div> + )HTML"); + + const SelectionInDOMTree selection = + GetFrame().Selection().GetSelectionInDOMTree(); + + const auto ax_selection_shrink = AXSelection::FromSelection( + selection, AXSelectionBehavior::kShrinkToValidDOMRange); + EXPECT_EQ("", GetSelectionText(ax_selection_shrink)); + + const auto ax_selection_extend = AXSelection::FromSelection( + selection, AXSelectionBehavior::kExtendToValidDOMRange); + EXPECT_EQ("", GetSelectionText(ax_selection_extend)); +} + // // Set selection tests. // Setting the selection from an |AXSelection| that has endpoints which are not // present in the layout tree should shring the selection to visible endpoints. // +TEST_F(AccessibilitySelectionTest, SetSelectionAroundListBullet) { + SetSelectionText(R"HTML( + <div role="main"> + <ul> + ^<li>Item 1.</li> + <li>Item 2.</li>| + </ul> + </div> + )HTML"); + + const SelectionInDOMTree selection = + GetFrame().Selection().GetSelectionInDOMTree(); + + const auto ax_selection_shrink = AXSelection::FromSelection( + selection, AXSelectionBehavior::kShrinkToValidDOMRange); + EXPECT_EQ("", GetSelectionText(ax_selection_shrink)); + + const auto ax_selection_extend = AXSelection::FromSelection( + selection, AXSelectionBehavior::kExtendToValidDOMRange); + EXPECT_EQ("", GetSelectionText(ax_selection_extend)); +} + } // namespace blink
diff --git a/third_party/blink/renderer/modules/accessibility/testing/accessibility_selection_test.cc b/third_party/blink/renderer/modules/accessibility/testing/accessibility_selection_test.cc index 9a91e8f4..13950c5b 100644 --- a/third_party/blink/renderer/modules/accessibility/testing/accessibility_selection_test.cc +++ b/third_party/blink/renderer/modules/accessibility/testing/accessibility_selection_test.cc
@@ -4,6 +4,8 @@ #include "third_party/blink/renderer/modules/accessibility/testing/accessibility_selection_test.h" +#include "third_party/blink/renderer/core/dom/character_data.h" +#include "third_party/blink/renderer/core/dom/container_node.h" #include "third_party/blink/renderer/core/dom/node.h" #include "third_party/blink/renderer/core/html/html_element.h" #include "third_party/blink/renderer/modules/accessibility/ax_object.h" @@ -144,7 +146,9 @@ // Deserializes an HTML snippet with or without selection markers to an // accessibility tree. A '^' could be present at the selection anchor offset and // a '|' at the focus offset. If multiple markers are present, the deserializer -// will DCHECK. If there are no markers, no selection will be made. +// will DCHECK. If there are no markers, no selection will be made. We don't +// allow '^' and '|' markers to appear in anything other than the contents of an +// HTML node, e.g. they are not permitted in aria-labels. class AXSelectionDeserializer final { STACK_ALLOCATED(); @@ -156,11 +160,12 @@ // Creates an accessibility tree rooted at the given HTML element from the // provided HTML snippet, selects the part of the tree indicated by the // selection markers in the snippet if present, and returns the tree's root. - AXObject* Deserialize(const std::string& html_snippet, HTMLElement& element) { + const AXSelection Deserialize(const std::string& html_snippet, + HTMLElement& element) { element.SetInnerHTMLFromString(String::FromUTF8(html_snippet.c_str())); AXObject* root = ax_object_cache_->GetOrCreate(&element); if (!root) - return nullptr; + return AXSelection::Builder().Build(); FindSelectionMarkers(*root); if (base_ && extent_) { @@ -168,33 +173,56 @@ AXSelection ax_selection = builder.SetBase(base_).SetExtent(extent_).Build(); ax_selection.Select(); + return ax_selection; } - return root; + return AXSelection::Builder().Build(); } private: void HandleCharacterData(const AXObject& text_object) { + CharacterData* const node = ToCharacterData(text_object.GetNode()); int base_offset = -1; int extent_offset = -1; - String name = text_object.ComputedName(); - for (unsigned i = 0; i < name.length(); ++i) { - const UChar character = name[i]; + StringBuilder builder; + for (unsigned i = 0; i < node->length(); ++i) { + const UChar character = node->data()[i]; if (character == '^') { - DCHECK_EQ(base_offset, -1) << text_object; + DCHECK_EQ(base_offset, -1) << "Only one '^' is allowed " << text_object; base_offset = static_cast<int>(i); continue; } if (character == '|') { - DCHECK_EQ(extent_offset, -1) << text_object; + DCHECK_EQ(extent_offset, -1) + << "Only one '|' is allowed " << text_object; extent_offset = static_cast<int>(i); continue; } + builder.Append(character); } + LOG(ERROR) << "Nektar\n" << base_offset << extent_offset; if (base_offset == -1 && extent_offset == -1) return; + // Remove the markers, otherwise they would be duplicated if the AX + // selection is re-serialized. + node->setData(builder.ToString()); + + if (node->length() == 0) { + // Since the text object contains only selection markers, this indicates + // that this is a request for a non-text selection. + if (base_offset >= 0) + base_ = AXPosition::CreatePositionBeforeObject(text_object); + if (extent_offset >= 0) + extent_ = AXPosition::CreatePositionBeforeObject(text_object); + + ContainerNode* const parent_node = node->parentNode(); + DCHECK(parent_node); + parent_node->removeChild(node); + return; + } + if (base_offset >= 0) base_ = AXPosition::CreatePositionInTextObject(text_object, base_offset); if (extent_offset >= 0) { @@ -245,16 +273,16 @@ return AXSelectionSerializer(selection).Serialize(subtree); } -AXObject* AccessibilitySelectionTest::SetSelectionText( +const AXSelection AccessibilitySelectionTest::SetSelectionText( const std::string& selection_text) const { HTMLElement* body = GetDocument().body(); if (!body) - return nullptr; + return AXSelection::Builder().Build(); return AXSelectionDeserializer(GetAXObjectCache()) .Deserialize(selection_text, *body); } -AXObject* AccessibilitySelectionTest::SetSelectionText( +const AXSelection AccessibilitySelectionTest::SetSelectionText( const std::string& selection_text, HTMLElement& element) const { return AXSelectionDeserializer(GetAXObjectCache())
diff --git a/third_party/blink/renderer/modules/accessibility/testing/accessibility_selection_test.h b/third_party/blink/renderer/modules/accessibility/testing/accessibility_selection_test.h index 9f8dcd7..0ee6a45 100644 --- a/third_party/blink/renderer/modules/accessibility/testing/accessibility_selection_test.h +++ b/third_party/blink/renderer/modules/accessibility/testing/accessibility_selection_test.h
@@ -35,12 +35,12 @@ // Sets |selection_text| as inner HTML of the document body and returns the // root of the accessibility tree at body. - AXObject* SetSelectionText(const std::string& selection_text) const; + const AXSelection SetSelectionText(const std::string& selection_text) const; // Sets |selection_text| as inner HTML of |element| and returns the root of // the accessibility subtree at |element|. - AXObject* SetSelectionText(const std::string& selection_text, - HTMLElement& element) const; + const AXSelection SetSelectionText(const std::string& selection_text, + HTMLElement& element) const; }; } // namespace blink
diff --git a/third_party/blink/renderer/modules/device_orientation/BUILD.gn b/third_party/blink/renderer/modules/device_orientation/BUILD.gn index 40cc0c9..8911217 100644 --- a/third_party/blink/renderer/modules/device_orientation/BUILD.gn +++ b/third_party/blink/renderer/modules/device_orientation/BUILD.gn
@@ -12,8 +12,6 @@ "device_motion_controller.h", "device_motion_data.cc", "device_motion_data.h", - "device_motion_dispatcher.cc", - "device_motion_dispatcher.h", "device_motion_event.cc", "device_motion_event.h", "device_motion_event_pump.cc",
diff --git a/third_party/blink/renderer/modules/device_orientation/device_motion_controller.cc b/third_party/blink/renderer/modules/device_orientation/device_motion_controller.cc index f1f4dbf2..01c1ade 100644 --- a/third_party/blink/renderer/modules/device_orientation/device_motion_controller.cc +++ b/third_party/blink/renderer/modules/device_orientation/device_motion_controller.cc
@@ -10,8 +10,8 @@ #include "third_party/blink/renderer/core/frame/hosts_using_features.h" #include "third_party/blink/renderer/core/frame/settings.h" #include "third_party/blink/renderer/modules/device_orientation/device_motion_data.h" -#include "third_party/blink/renderer/modules/device_orientation/device_motion_dispatcher.h" #include "third_party/blink/renderer/modules/device_orientation/device_motion_event.h" +#include "third_party/blink/renderer/modules/device_orientation/device_motion_event_pump.h" #include "third_party/blink/renderer/modules/device_orientation/device_orientation_controller.h" #include "third_party/blink/renderer/modules/event_modules.h" #include "third_party/blink/renderer/platform/weborigin/security_origin.h" @@ -78,21 +78,33 @@ } bool DeviceMotionController::HasLastData() { - return DeviceMotionDispatcher::Instance().LatestDeviceMotionData(); + return motion_event_pump_ + ? motion_event_pump_->LatestDeviceMotionData() != nullptr + : false; } void DeviceMotionController::RegisterWithDispatcher() { - DeviceMotionDispatcher::Instance().AddController(this); + if (!motion_event_pump_) { + LocalFrame* frame = GetDocument().GetFrame(); + if (!frame) + return; + scoped_refptr<base::SingleThreadTaskRunner> task_runner = + frame->GetTaskRunner(TaskType::kSensor); + motion_event_pump_ = new DeviceMotionEventPump(task_runner); + } + motion_event_pump_->AddController(this); } void DeviceMotionController::UnregisterWithDispatcher() { - DeviceMotionDispatcher::Instance().RemoveController(this); + if (motion_event_pump_) + motion_event_pump_->RemoveController(this); } Event* DeviceMotionController::LastEvent() const { return DeviceMotionEvent::Create( EventTypeNames::devicemotion, - DeviceMotionDispatcher::Instance().LatestDeviceMotionData()); + motion_event_pump_ ? motion_event_pump_->LatestDeviceMotionData() + : nullptr); } bool DeviceMotionController::IsNullEvent(Event* event) const { @@ -106,6 +118,7 @@ void DeviceMotionController::Trace(blink::Visitor* visitor) { DeviceSingleWindowEventController::Trace(visitor); + visitor->Trace(motion_event_pump_); Supplement<Document>::Trace(visitor); }
diff --git a/third_party/blink/renderer/modules/device_orientation/device_motion_controller.h b/third_party/blink/renderer/modules/device_orientation/device_motion_controller.h index 107bb0d..e8b62cca1e 100644 --- a/third_party/blink/renderer/modules/device_orientation/device_motion_controller.h +++ b/third_party/blink/renderer/modules/device_orientation/device_motion_controller.h
@@ -12,6 +12,7 @@ namespace blink { class Event; +class DeviceMotionEventPump; class MODULES_EXPORT DeviceMotionController final : public DeviceSingleWindowEventController, @@ -34,7 +35,7 @@ private: explicit DeviceMotionController(Document&); - // Inherited from DeviceEventControllerBase. + // Inherited from PlatformEventController. void RegisterWithDispatcher() override; void UnregisterWithDispatcher() override; bool HasLastData() override; @@ -43,6 +44,8 @@ Event* LastEvent() const override; const AtomicString& EventTypeName() const override; bool IsNullEvent(Event*) const override; + + Member<DeviceMotionEventPump> motion_event_pump_; }; } // namespace blink
diff --git a/third_party/blink/renderer/modules/device_orientation/device_motion_dispatcher.cc b/third_party/blink/renderer/modules/device_orientation/device_motion_dispatcher.cc deleted file mode 100644 index 5b46504..0000000 --- a/third_party/blink/renderer/modules/device_orientation/device_motion_dispatcher.cc +++ /dev/null
@@ -1,80 +0,0 @@ -/* - * Copyright (C) 2013 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "third_party/blink/renderer/modules/device_orientation/device_motion_dispatcher.h" - -#include "third_party/blink/renderer/modules/device_orientation/device_motion_controller.h" -#include "third_party/blink/renderer/modules/device_orientation/device_motion_data.h" -#include "third_party/blink/renderer/modules/device_orientation/device_motion_event_pump.h" - -namespace blink { - -DeviceMotionDispatcher& DeviceMotionDispatcher::Instance() { - DEFINE_STATIC_LOCAL(DeviceMotionDispatcher, device_motion_dispatcher, - (new DeviceMotionDispatcher)); - return device_motion_dispatcher; -} - -DeviceMotionDispatcher::DeviceMotionDispatcher() = default; - -DeviceMotionDispatcher::~DeviceMotionDispatcher() = default; - -void DeviceMotionDispatcher::Trace(blink::Visitor* visitor) { - visitor->Trace(last_device_motion_data_); - PlatformEventDispatcher::Trace(visitor); -} - -void DeviceMotionDispatcher::StartListening(LocalFrame* frame) { - // TODO(crbug.com/850619): ensure a valid frame is passed - if (!frame) - return; - if (!event_pump_) { - event_pump_ = std::make_unique<DeviceMotionEventPump>( - frame->GetTaskRunner(TaskType::kSensor)); - } - event_pump_->Start(frame, this); -} - -void DeviceMotionDispatcher::StopListening() { - if (event_pump_) - event_pump_->Stop(); - last_device_motion_data_.Clear(); -} - -void DeviceMotionDispatcher::DidChangeDeviceMotion(DeviceMotionData* motion) { - last_device_motion_data_ = motion; - NotifyControllers(); -} - -const DeviceMotionData* DeviceMotionDispatcher::LatestDeviceMotionData() { - return last_device_motion_data_.Get(); -} - -} // namespace blink
diff --git a/third_party/blink/renderer/modules/device_orientation/device_motion_dispatcher.h b/third_party/blink/renderer/modules/device_orientation/device_motion_dispatcher.h deleted file mode 100644 index 70e76a1..0000000 --- a/third_party/blink/renderer/modules/device_orientation/device_motion_dispatcher.h +++ /dev/null
@@ -1,77 +0,0 @@ -/* - * Copyright (C) 2013 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_DEVICE_ORIENTATION_DEVICE_MOTION_DISPATCHER_H_ -#define THIRD_PARTY_BLINK_RENDERER_MODULES_DEVICE_ORIENTATION_DEVICE_MOTION_DISPATCHER_H_ - -#include "base/memory/scoped_refptr.h" -#include "third_party/blink/public/platform/modules/device_orientation/web_device_motion_listener.h" -#include "third_party/blink/renderer/core/frame/platform_event_dispatcher.h" -#include "third_party/blink/renderer/platform/heap/handle.h" - -namespace blink { - -class DeviceMotionData; -class DeviceMotionEventPump; - -// This class listens to device motion data and notifies all registered -// controllers. -class DeviceMotionDispatcher final - : public GarbageCollectedFinalized<DeviceMotionDispatcher>, - public PlatformEventDispatcher, - public WebDeviceMotionListener { - USING_GARBAGE_COLLECTED_MIXIN(DeviceMotionDispatcher); - - public: - static DeviceMotionDispatcher& Instance(); - ~DeviceMotionDispatcher() override; - - // Note that the returned object is owned by this class. - const DeviceMotionData* LatestDeviceMotionData(); - - // Inherited from WebDeviceMotionListener. - void DidChangeDeviceMotion(DeviceMotionData*) override; - - void Trace(blink::Visitor*) override; - - private: - DeviceMotionDispatcher(); - - // Inherited from PlatformEventDispatcher. - void StartListening(LocalFrame*) override; - void StopListening() override; - - Member<DeviceMotionData> last_device_motion_data_; - std::unique_ptr<DeviceMotionEventPump> event_pump_; -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_DEVICE_ORIENTATION_DEVICE_MOTION_DISPATCHER_H_
diff --git a/third_party/blink/renderer/modules/device_orientation/device_motion_event_pump.cc b/third_party/blink/renderer/modules/device_orientation/device_motion_event_pump.cc index 06aab06b..0ef859c 100644 --- a/third_party/blink/renderer/modules/device_orientation/device_motion_event_pump.cc +++ b/third_party/blink/renderer/modules/device_orientation/device_motion_event_pump.cc
@@ -20,11 +20,9 @@ namespace blink { -template class DeviceSensorEventPump<blink::WebDeviceMotionListener>; - DeviceMotionEventPump::DeviceMotionEventPump( scoped_refptr<base::SingleThreadTaskRunner> task_runner) - : DeviceSensorEventPump<blink::WebDeviceMotionListener>(task_runner), + : DeviceSensorEventPump(task_runner), accelerometer_(this, device::mojom::blink::SensorType::ACCELEROMETER), linear_acceleration_sensor_( this, @@ -35,6 +33,22 @@ StopIfObserving(); } +DeviceMotionData* DeviceMotionEventPump::LatestDeviceMotionData() { + return data_.Get(); +} + +void DeviceMotionEventPump::Trace(blink::Visitor* visitor) { + visitor->Trace(data_); + PlatformEventDispatcher::Trace(visitor); +} + +void DeviceMotionEventPump::StartListening(LocalFrame* frame) { + // TODO(crbug.com/850619): ensure a valid frame is passed + if (!frame) + return; + Start(frame); +} + void DeviceMotionEventPump::SendStartMessage(LocalFrame* frame) { if (!sensor_provider_) { DCHECK(frame); @@ -43,7 +57,7 @@ mojo::MakeRequest(&sensor_provider_)); sensor_provider_.set_connection_error_handler( WTF::Bind(&DeviceSensorEventPump::HandleSensorProviderError, - WTF::Unretained(this))); + WrapPersistent(this))); } accelerometer_.Start(sensor_provider_.get()); @@ -51,6 +65,11 @@ gyroscope_.Start(sensor_provider_.get()); } +void DeviceMotionEventPump::StopListening() { + Stop(); + data_.Clear(); +} + void DeviceMotionEventPump::SendStopMessage() { // SendStopMessage() gets called both when the page visibility changes and if // all device motion event listeners are unregistered. Since removing the @@ -63,13 +82,13 @@ } void DeviceMotionEventPump::FireEvent(TimerBase*) { - DCHECK(listener()); - DeviceMotionData* data = GetDataFromSharedMemory(); // data is null if not all sensors are active - if (data) - listener()->DidChangeDeviceMotion(data); + if (data) { + data_ = data; + NotifyControllers(); + } } bool DeviceMotionEventPump::SensorsReadyOrErrored() const {
diff --git a/third_party/blink/renderer/modules/device_orientation/device_motion_event_pump.h b/third_party/blink/renderer/modules/device_orientation/device_motion_event_pump.h index 4d616365..87d567d 100644 --- a/third_party/blink/renderer/modules/device_orientation/device_motion_event_pump.h +++ b/third_party/blink/renderer/modules/device_orientation/device_motion_event_pump.h
@@ -6,20 +6,30 @@ #define THIRD_PARTY_BLINK_RENDERER_MODULES_DEVICE_ORIENTATION_DEVICE_MOTION_EVENT_PUMP_H_ #include "base/macros.h" -#include "third_party/blink/public/platform/modules/device_orientation/web_device_motion_listener.h" +#include "third_party/blink/renderer/core/frame/platform_event_dispatcher.h" #include "third_party/blink/renderer/modules/device_orientation/device_sensor_event_pump.h" #include "third_party/blink/renderer/modules/modules_export.h" +#include "third_party/blink/renderer/platform/heap/handle.h" namespace blink { class DeviceMotionData; class MODULES_EXPORT DeviceMotionEventPump - : public DeviceSensorEventPump<blink::WebDeviceMotionListener> { + : public GarbageCollectedFinalized<DeviceMotionEventPump>, + public DeviceSensorEventPump<WebDeviceMotionListener>, + public PlatformEventDispatcher { + USING_GARBAGE_COLLECTED_MIXIN(DeviceMotionEventPump); + public: explicit DeviceMotionEventPump(scoped_refptr<base::SingleThreadTaskRunner>); ~DeviceMotionEventPump() override; + // Note that the returned object is owned by this class. + DeviceMotionData* LatestDeviceMotionData(); + + void Trace(blink::Visitor*) override; + // DeviceSensorEventPump: void SendStartMessage(LocalFrame* frame) override; void SendStopMessage() override; @@ -35,11 +45,17 @@ private: friend class DeviceMotionEventPumpTest; + // Inherited from PlatformEventDispatcher. + void StartListening(LocalFrame*) override; + void StopListening() override; + // DeviceSensorEventPump: bool SensorsReadyOrErrored() const override; DeviceMotionData* GetDataFromSharedMemory(); + Member<DeviceMotionData> data_; + DISALLOW_COPY_AND_ASSIGN(DeviceMotionEventPump); };
diff --git a/third_party/blink/renderer/modules/device_orientation/device_motion_event_pump_unittest.cc b/third_party/blink/renderer/modules/device_orientation/device_motion_event_pump_unittest.cc index 868c4f6c..a9d5238ec 100644 --- a/third_party/blink/renderer/modules/device_orientation/device_motion_event_pump_unittest.cc +++ b/third_party/blink/renderer/modules/device_orientation/device_motion_event_pump_unittest.cc
@@ -9,8 +9,8 @@ #include "base/run_loop.h" #include "services/device/public/cpp/test/fake_sensor_and_provider.h" #include "testing/gtest/include/gtest/gtest.h" -#include "third_party/blink/public/platform/modules/device_orientation/web_device_motion_listener.h" #include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h" +#include "third_party/blink/renderer/core/frame/platform_event_controller.h" #include "third_party/blink/renderer/modules/device_orientation/device_motion_data.h" #include "third_party/blink/renderer/modules/device_orientation/device_motion_event_pump.h" #include "third_party/blink/renderer/platform/heap/persistent.h" @@ -20,16 +20,24 @@ using device::FakeSensorProvider; -class MockDeviceMotionListener : public blink::WebDeviceMotionListener { - public: - MockDeviceMotionListener() - : did_change_device_motion_(false), number_of_events_(0) { - data_ = DeviceMotionData::Create(); - } - ~MockDeviceMotionListener() override {} +class MockDeviceMotionController final + : public GarbageCollectedFinalized<MockDeviceMotionController>, + public PlatformEventController { + USING_GARBAGE_COLLECTED_MIXIN(MockDeviceMotionController); - void DidChangeDeviceMotion(DeviceMotionData* data) override { - data_ = data; + public: + explicit MockDeviceMotionController(DeviceMotionEventPump* motion_pump) + : PlatformEventController(nullptr), + did_change_device_motion_(false), + motion_pump_(motion_pump) {} + ~MockDeviceMotionController() override {} + + void Trace(Visitor* visitor) override { + PlatformEventController::Trace(visitor); + visitor->Trace(motion_pump_); + } + + void DidUpdateData() override { did_change_device_motion_ = true; ++number_of_events_; } @@ -38,27 +46,26 @@ int number_of_events() const { return number_of_events_; } - const DeviceMotionData* data() const { return data_.Get(); } + void RegisterWithDispatcher() override { motion_pump_->AddController(this); } + + bool HasLastData() override { return motion_pump_->LatestDeviceMotionData(); } + + void UnregisterWithDispatcher() override { + motion_pump_->RemoveController(this); + } + + const DeviceMotionData* data() { + return motion_pump_->LatestDeviceMotionData(); + }; + + DeviceMotionEventPump* motion_pump() { return motion_pump_.Get(); } private: bool did_change_device_motion_; int number_of_events_; - Persistent<DeviceMotionData> data_; + Member<DeviceMotionEventPump> motion_pump_; - DISALLOW_COPY_AND_ASSIGN(MockDeviceMotionListener); -}; - -class DeviceMotionEventPumpForTesting : public DeviceMotionEventPump { - public: - explicit DeviceMotionEventPumpForTesting( - scoped_refptr<base::SingleThreadTaskRunner> task_runner) - : DeviceMotionEventPump(task_runner) {} - ~DeviceMotionEventPumpForTesting() override {} - - int pump_delay_microseconds() const { return kDefaultPumpDelayMicroseconds; } - - private: - DISALLOW_COPY_AND_ASSIGN(DeviceMotionEventPumpForTesting); + DISALLOW_COPY_AND_ASSIGN(MockDeviceMotionController); }; class DeviceMotionEventPumpTest : public testing::Test { @@ -67,40 +74,43 @@ protected: void SetUp() override { - motion_pump_.reset(new DeviceMotionEventPumpForTesting( - base::ThreadTaskRunnerHandle::Get())); device::mojom::SensorProviderPtrInfo sensor_provider_ptr_info; sensor_provider_.Bind(mojo::MakeRequest(&sensor_provider_ptr_info)); - motion_pump_->SetSensorProviderForTesting( + auto* motion_pump = + new DeviceMotionEventPump(base::ThreadTaskRunnerHandle::Get()); + motion_pump->SetSensorProviderForTesting( device::mojom::blink::SensorProviderPtr( device::mojom::blink::SensorProviderPtrInfo( sensor_provider_ptr_info.PassHandle(), device::mojom::SensorProvider::Version_))); - listener_.reset(new MockDeviceMotionListener); + controller_ = new MockDeviceMotionController(motion_pump); ExpectAllThreeSensorsStateToBe( DeviceMotionEventPump::SensorState::NOT_INITIALIZED); EXPECT_EQ(DeviceMotionEventPump::PumpState::STOPPED, - motion_pump()->GetPumpStateForTesting()); + controller_->motion_pump()->GetPumpStateForTesting()); } - void FireEvent() { motion_pump_->FireEvent(nullptr); } + void FireEvent() { controller_->motion_pump()->FireEvent(nullptr); } void ExpectAccelerometerStateToBe( DeviceMotionEventPump::SensorState expected_sensor_state) { - EXPECT_EQ(expected_sensor_state, motion_pump_->accelerometer_.sensor_state); + EXPECT_EQ(expected_sensor_state, + controller_->motion_pump()->accelerometer_.sensor_state); } void ExpectLinearAccelerationSensorStateToBe( DeviceMotionEventPump::SensorState expected_sensor_state) { - EXPECT_EQ(expected_sensor_state, - motion_pump_->linear_acceleration_sensor_.sensor_state); + EXPECT_EQ( + expected_sensor_state, + controller_->motion_pump()->linear_acceleration_sensor_.sensor_state); } void ExpectGyroscopeStateToBe( DeviceMotionEventPump::SensorState expected_sensor_state) { - EXPECT_EQ(expected_sensor_state, motion_pump_->gyroscope_.sensor_state); + EXPECT_EQ(expected_sensor_state, + controller_->motion_pump()->gyroscope_.sensor_state); } void ExpectAllThreeSensorsStateToBe( @@ -110,52 +120,50 @@ ExpectGyroscopeStateToBe(expected_sensor_state); } - DeviceMotionEventPumpForTesting* motion_pump() { return motion_pump_.get(); } - - MockDeviceMotionListener* listener() { return listener_.get(); } + MockDeviceMotionController* controller() { return controller_.Get(); } FakeSensorProvider* sensor_provider() { return &sensor_provider_; } private: - std::unique_ptr<DeviceMotionEventPumpForTesting> motion_pump_; - std::unique_ptr<MockDeviceMotionListener> listener_; + Persistent<MockDeviceMotionController> controller_; + FakeSensorProvider sensor_provider_; DISALLOW_COPY_AND_ASSIGN(DeviceMotionEventPumpTest); }; TEST_F(DeviceMotionEventPumpTest, MultipleStartAndStopWithWait) { - motion_pump()->Start(nullptr, listener()); + controller()->motion_pump()->Start(nullptr); base::RunLoop().RunUntilIdle(); ExpectAllThreeSensorsStateToBe(DeviceMotionEventPump::SensorState::ACTIVE); EXPECT_EQ(DeviceMotionEventPump::PumpState::RUNNING, - motion_pump()->GetPumpStateForTesting()); + controller()->motion_pump()->GetPumpStateForTesting()); - motion_pump()->Stop(); + controller()->motion_pump()->Stop(); base::RunLoop().RunUntilIdle(); ExpectAllThreeSensorsStateToBe(DeviceMotionEventPump::SensorState::SUSPENDED); EXPECT_EQ(DeviceMotionEventPump::PumpState::STOPPED, - motion_pump()->GetPumpStateForTesting()); + controller()->motion_pump()->GetPumpStateForTesting()); - motion_pump()->Start(nullptr, listener()); + controller()->motion_pump()->Start(nullptr); base::RunLoop().RunUntilIdle(); ExpectAllThreeSensorsStateToBe(DeviceMotionEventPump::SensorState::ACTIVE); EXPECT_EQ(DeviceMotionEventPump::PumpState::RUNNING, - motion_pump()->GetPumpStateForTesting()); + controller()->motion_pump()->GetPumpStateForTesting()); - motion_pump()->Stop(); + controller()->motion_pump()->Stop(); base::RunLoop().RunUntilIdle(); ExpectAllThreeSensorsStateToBe(DeviceMotionEventPump::SensorState::SUSPENDED); EXPECT_EQ(DeviceMotionEventPump::PumpState::STOPPED, - motion_pump()->GetPumpStateForTesting()); + controller()->motion_pump()->GetPumpStateForTesting()); } TEST_F(DeviceMotionEventPumpTest, CallStop) { - motion_pump()->Stop(); + controller()->motion_pump()->Stop(); base::RunLoop().RunUntilIdle(); ExpectAllThreeSensorsStateToBe( @@ -163,26 +171,26 @@ } TEST_F(DeviceMotionEventPumpTest, CallStartAndStop) { - motion_pump()->Start(nullptr, listener()); - motion_pump()->Stop(); + controller()->motion_pump()->Start(nullptr); + controller()->motion_pump()->Stop(); base::RunLoop().RunUntilIdle(); ExpectAllThreeSensorsStateToBe(DeviceMotionEventPump::SensorState::SUSPENDED); } TEST_F(DeviceMotionEventPumpTest, CallStartMultipleTimes) { - motion_pump()->Start(nullptr, listener()); - motion_pump()->Start(nullptr, listener()); - motion_pump()->Stop(); + controller()->motion_pump()->Start(nullptr); + controller()->motion_pump()->Start(nullptr); + controller()->motion_pump()->Stop(); base::RunLoop().RunUntilIdle(); ExpectAllThreeSensorsStateToBe(DeviceMotionEventPump::SensorState::SUSPENDED); } TEST_F(DeviceMotionEventPumpTest, CallStopMultipleTimes) { - motion_pump()->Start(nullptr, listener()); - motion_pump()->Stop(); - motion_pump()->Stop(); + controller()->motion_pump()->Start(nullptr); + controller()->motion_pump()->Stop(); + controller()->motion_pump()->Stop(); base::RunLoop().RunUntilIdle(); ExpectAllThreeSensorsStateToBe(DeviceMotionEventPump::SensorState::SUSPENDED); @@ -190,20 +198,21 @@ // Test multiple DeviceSensorEventPump::Start() calls only bind sensor once. TEST_F(DeviceMotionEventPumpTest, SensorOnlyBindOnce) { - motion_pump()->Start(nullptr, listener()); - motion_pump()->Stop(); - motion_pump()->Start(nullptr, listener()); + controller()->motion_pump()->Start(nullptr); + controller()->motion_pump()->Stop(); + controller()->motion_pump()->Start(nullptr); base::RunLoop().RunUntilIdle(); ExpectAllThreeSensorsStateToBe(DeviceMotionEventPump::SensorState::ACTIVE); - motion_pump()->Stop(); + controller()->motion_pump()->Stop(); ExpectAllThreeSensorsStateToBe(DeviceMotionEventPump::SensorState::SUSPENDED); } TEST_F(DeviceMotionEventPumpTest, AllSensorsAreActive) { - motion_pump()->Start(nullptr, listener()); + controller()->RegisterWithDispatcher(); + controller()->motion_pump()->Start(nullptr); base::RunLoop().RunUntilIdle(); ExpectAllThreeSensorsStateToBe(DeviceMotionEventPump::SensorState::ACTIVE); @@ -214,9 +223,8 @@ FireEvent(); - EXPECT_TRUE(listener()->did_change_device_motion()); - - const DeviceMotionData* received_data = listener()->data(); + const DeviceMotionData* received_data = controller()->data(); + EXPECT_TRUE(controller()->did_change_device_motion()); EXPECT_TRUE(received_data->GetAccelerationIncludingGravity()->CanProvideX()); EXPECT_EQ(1, received_data->GetAccelerationIncludingGravity()->X()); @@ -239,7 +247,7 @@ EXPECT_TRUE(received_data->GetRotationRate()->CanProvideGamma()); EXPECT_EQ(gfx::RadToDeg(9.0), received_data->GetRotationRate()->Gamma()); - motion_pump()->Stop(); + controller()->motion_pump()->Stop(); ExpectAllThreeSensorsStateToBe(DeviceMotionEventPump::SensorState::SUSPENDED); } @@ -247,7 +255,8 @@ TEST_F(DeviceMotionEventPumpTest, TwoSensorsAreActive) { sensor_provider()->set_linear_acceleration_sensor_is_available(false); - motion_pump()->Start(nullptr, listener()); + controller()->RegisterWithDispatcher(); + controller()->motion_pump()->Start(nullptr); base::RunLoop().RunUntilIdle(); ExpectAccelerometerStateToBe(DeviceMotionEventPump::SensorState::ACTIVE); @@ -260,8 +269,8 @@ FireEvent(); - const DeviceMotionData* received_data = listener()->data(); - EXPECT_TRUE(listener()->did_change_device_motion()); + const DeviceMotionData* received_data = controller()->data(); + EXPECT_TRUE(controller()->did_change_device_motion()); EXPECT_TRUE(received_data->GetAccelerationIncludingGravity()->CanProvideX()); EXPECT_EQ(1, received_data->GetAccelerationIncludingGravity()->X()); @@ -281,7 +290,7 @@ EXPECT_TRUE(received_data->GetRotationRate()->CanProvideGamma()); EXPECT_EQ(gfx::RadToDeg(9.0), received_data->GetRotationRate()->Gamma()); - motion_pump()->Stop(); + controller()->motion_pump()->Stop(); ExpectAccelerometerStateToBe(DeviceMotionEventPump::SensorState::SUSPENDED); ExpectLinearAccelerationSensorStateToBe( @@ -290,7 +299,8 @@ } TEST_F(DeviceMotionEventPumpTest, SomeSensorDataFieldsNotAvailable) { - motion_pump()->Start(nullptr, listener()); + controller()->RegisterWithDispatcher(); + controller()->motion_pump()->Start(nullptr); base::RunLoop().RunUntilIdle(); ExpectAllThreeSensorsStateToBe(DeviceMotionEventPump::SensorState::ACTIVE); @@ -301,8 +311,8 @@ FireEvent(); - const DeviceMotionData* received_data = listener()->data(); - EXPECT_TRUE(listener()->did_change_device_motion()); + const DeviceMotionData* received_data = controller()->data(); + EXPECT_TRUE(controller()->did_change_device_motion()); EXPECT_FALSE(received_data->GetAccelerationIncludingGravity()->CanProvideX()); EXPECT_TRUE(received_data->GetAccelerationIncludingGravity()->CanProvideY()); @@ -322,7 +332,7 @@ EXPECT_EQ(gfx::RadToDeg(8.0), received_data->GetRotationRate()->Beta()); EXPECT_FALSE(received_data->GetRotationRate()->CanProvideGamma()); - motion_pump()->Stop(); + controller()->motion_pump()->Stop(); ExpectAllThreeSensorsStateToBe(DeviceMotionEventPump::SensorState::SUSPENDED); } @@ -333,7 +343,8 @@ sensor_provider()->set_linear_acceleration_sensor_is_available(false); sensor_provider()->set_gyroscope_is_available(false); - motion_pump()->Start(nullptr, listener()); + controller()->RegisterWithDispatcher(); + controller()->motion_pump()->Start(nullptr); base::RunLoop().RunUntilIdle(); ExpectAllThreeSensorsStateToBe( @@ -341,8 +352,8 @@ FireEvent(); - const DeviceMotionData* received_data = listener()->data(); - EXPECT_TRUE(listener()->did_change_device_motion()); + const DeviceMotionData* received_data = controller()->data(); + EXPECT_TRUE(controller()->did_change_device_motion()); EXPECT_FALSE(received_data->GetAcceleration()->CanProvideX()); EXPECT_FALSE(received_data->GetAcceleration()->CanProvideY()); @@ -356,7 +367,7 @@ EXPECT_FALSE(received_data->GetRotationRate()->CanProvideBeta()); EXPECT_FALSE(received_data->GetRotationRate()->CanProvideGamma()); - motion_pump()->Stop(); + controller()->motion_pump()->Stop(); ExpectAllThreeSensorsStateToBe( DeviceMotionEventPump::SensorState::NOT_INITIALIZED); @@ -364,28 +375,29 @@ TEST_F(DeviceMotionEventPumpTest, NotFireEventWhenSensorReadingTimeStampIsZero) { - motion_pump()->Start(nullptr, listener()); + controller()->RegisterWithDispatcher(); + controller()->motion_pump()->Start(nullptr); base::RunLoop().RunUntilIdle(); ExpectAllThreeSensorsStateToBe(DeviceMotionEventPump::SensorState::ACTIVE); FireEvent(); - EXPECT_FALSE(listener()->did_change_device_motion()); + EXPECT_FALSE(controller()->did_change_device_motion()); sensor_provider()->UpdateAccelerometerData(1, 2, 3); FireEvent(); - EXPECT_FALSE(listener()->did_change_device_motion()); + EXPECT_FALSE(controller()->did_change_device_motion()); sensor_provider()->UpdateLinearAccelerationSensorData(4, 5, 6); FireEvent(); - EXPECT_FALSE(listener()->did_change_device_motion()); + EXPECT_FALSE(controller()->did_change_device_motion()); sensor_provider()->UpdateGyroscopeData(7, 8, 9); FireEvent(); // Event is fired only after all the available sensors have data. - EXPECT_TRUE(listener()->did_change_device_motion()); + EXPECT_TRUE(controller()->did_change_device_motion()); - motion_pump()->Stop(); + controller()->motion_pump()->Stop(); ExpectAllThreeSensorsStateToBe(DeviceMotionEventPump::SensorState::SUSPENDED); } @@ -396,9 +408,10 @@ TEST_F(DeviceMotionEventPumpTest, PumpThrottlesEventRate) { // Confirm that the delay for pumping events is 60 Hz. EXPECT_GE(60, WTF::Time::kMicrosecondsPerSecond / - motion_pump()->pump_delay_microseconds()); + DeviceMotionEventPump::kDefaultPumpDelayMicroseconds); - motion_pump()->Start(nullptr, listener()); + controller()->RegisterWithDispatcher(); + controller()->motion_pump()->Start(nullptr); base::RunLoop().RunUntilIdle(); ExpectAllThreeSensorsStateToBe(DeviceMotionEventPump::SensorState::ACTIVE); @@ -412,14 +425,14 @@ FROM_HERE, loop.QuitWhenIdleClosure(), WTF::TimeDelta::FromMilliseconds(100)); loop.Run(); - motion_pump()->Stop(); + controller()->motion_pump()->Stop(); ExpectAllThreeSensorsStateToBe(DeviceMotionEventPump::SensorState::SUSPENDED); - // Check that the blink::WebDeviceMotionListener does not receive excess + // Check that the PlatformEventController does not receive excess // events. - EXPECT_TRUE(listener()->did_change_device_motion()); - EXPECT_GE(6, listener()->number_of_events()); + EXPECT_TRUE(controller()->did_change_device_motion()); + EXPECT_GE(6, controller()->number_of_events()); } } // namespace blink
diff --git a/third_party/blink/renderer/modules/filesystem/BUILD.gn b/third_party/blink/renderer/modules/filesystem/BUILD.gn index 66d0340..5b44e789 100644 --- a/third_party/blink/renderer/modules/filesystem/BUILD.gn +++ b/third_party/blink/renderer/modules/filesystem/BUILD.gn
@@ -45,6 +45,8 @@ "file_system_callbacks.cc", "file_system_callbacks.h", "file_system_client.h", + "file_system_writer.cc", + "file_system_writer.h", "file_writer.cc", "file_writer.h", "file_writer_base.cc",
diff --git a/third_party/blink/renderer/modules/filesystem/file_system_writer.cc b/third_party/blink/renderer/modules/filesystem/file_system_writer.cc new file mode 100644 index 0000000..b7e07768 --- /dev/null +++ b/third_party/blink/renderer/modules/filesystem/file_system_writer.cc
@@ -0,0 +1,87 @@ +// Copyright 2018 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 "third_party/blink/renderer/modules/filesystem/file_system_writer.h" + +#include "third_party/blink/renderer/bindings/core/v8/script_promise.h" +#include "third_party/blink/renderer/core/dom/dom_exception.h" +#include "third_party/blink/renderer/core/fileapi/blob.h" +#include "third_party/blink/renderer/platform/wtf/functional.h" + +namespace blink { + +FileSystemWriter::FileSystemWriter(mojom::blink::FileWriterPtr writer) + : writer_(std::move(writer)) { + DCHECK(writer_); +} + +ScriptPromise FileSystemWriter::write(ScriptState* script_state, + uint64_t position, + Blob* blob) { + if (!writer_ || pending_operation_) { + return ScriptPromise::RejectWithDOMException( + script_state, + DOMException::Create(DOMExceptionCode::kInvalidStateError)); + } + pending_operation_ = ScriptPromiseResolver::Create(script_state); + ScriptPromise result = pending_operation_->Promise(); + writer_->Write( + position, blob->AsMojoBlob(), + WTF::Bind(&FileSystemWriter::WriteComplete, WrapPersistent(this))); + return result; +} + +ScriptPromise FileSystemWriter::truncate(ScriptState* script_state, + uint64_t size) { + if (!writer_ || pending_operation_) { + return ScriptPromise::RejectWithDOMException( + script_state, + DOMException::Create(DOMExceptionCode::kInvalidStateError)); + } + pending_operation_ = ScriptPromiseResolver::Create(script_state); + ScriptPromise result = pending_operation_->Promise(); + writer_->Truncate(size, WTF::Bind(&FileSystemWriter::TruncateComplete, + WrapPersistent(this))); + return result; +} + +ScriptPromise FileSystemWriter::close(ScriptState* script_state) { + if (!writer_) { + return ScriptPromise::RejectWithDOMException( + script_state, + DOMException::Create(DOMExceptionCode::kInvalidStateError)); + } + writer_ = nullptr; + return ScriptPromise::CastUndefined(script_state); +} + +void FileSystemWriter::Trace(Visitor* visitor) { + ScriptWrappable::Trace(visitor); + visitor->Trace(pending_operation_); +} + +void FileSystemWriter::WriteComplete(base::File::Error result, + uint64_t bytes_written) { + DCHECK(pending_operation_); + if (result == base::File::FILE_OK) { + pending_operation_->Resolve(); + } else { + // TODO(mek): Take actual error code into account. + pending_operation_->Reject( + DOMException::Create(DOMExceptionCode::kAbortError)); + } +} + +void FileSystemWriter::TruncateComplete(base::File::Error result) { + DCHECK(pending_operation_); + if (result == base::File::FILE_OK) { + pending_operation_->Resolve(); + } else { + // TODO(mek): Take actual error code into account. + pending_operation_->Reject( + DOMException::Create(DOMExceptionCode::kAbortError)); + } +} + +} // namespace blink
diff --git a/third_party/blink/renderer/modules/filesystem/file_system_writer.h b/third_party/blink/renderer/modules/filesystem/file_system_writer.h new file mode 100644 index 0000000..f00cd9f4 --- /dev/null +++ b/third_party/blink/renderer/modules/filesystem/file_system_writer.h
@@ -0,0 +1,41 @@ +// Copyright 2018 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 THIRD_PARTY_BLINK_RENDERER_MODULES_FILESYSTEM_FILE_SYSTEM_WRITER_H_ +#define THIRD_PARTY_BLINK_RENDERER_MODULES_FILESYSTEM_FILE_SYSTEM_WRITER_H_ + +#include "third_party/blink/public/mojom/filesystem/file_writer.mojom-blink.h" +#include "third_party/blink/renderer/platform/bindings/script_wrappable.h" + +namespace blink { + +class Blob; +class ScriptPromise; +class ScriptPromiseResolver; +class ScriptState; + +class FileSystemWriter final : public ScriptWrappable { + DEFINE_WRAPPERTYPEINFO(); + + public: + explicit FileSystemWriter(mojom::blink::FileWriterPtr); + + ScriptPromise write(ScriptState*, uint64_t position, Blob*); + ScriptPromise truncate(ScriptState*, uint64_t size); + ScriptPromise close(ScriptState*); + + void Trace(Visitor*) override; + + private: + void WriteComplete(base::File::Error result, uint64_t bytes_written); + void TruncateComplete(base::File::Error result); + + mojom::blink::FileWriterPtr writer_; + + Member<ScriptPromiseResolver> pending_operation_; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_FILESYSTEM_FILE_SYSTEM_WRITER_H_
diff --git a/third_party/blink/renderer/modules/filesystem/file_system_writer.idl b/third_party/blink/renderer/modules/filesystem/file_system_writer.idl new file mode 100644 index 0000000..c4362be --- /dev/null +++ b/third_party/blink/renderer/modules/filesystem/file_system_writer.idl
@@ -0,0 +1,15 @@ +// Copyright 2018 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. + +// https://github.com/WICG/writable-files/blob/master/EXPLAINER.md +[ + NoInterfaceObject, + RuntimeEnabled=WritableFiles +] interface FileSystemWriter { + // TODO(mek): Support other types, such as ReadableStream, by using 'any'. + [CallWith=ScriptState] Promise<void> write(unsigned long long position, Blob data); + [CallWith=ScriptState] Promise<void> truncate(unsigned long long size); + + [CallWith=ScriptState] Promise<void> close(); +};
diff --git a/third_party/blink/renderer/modules/modules_idl_files.gni b/third_party/blink/renderer/modules/modules_idl_files.gni index 55ca9ce..c64345e 100644 --- a/third_party/blink/renderer/modules/modules_idl_files.gni +++ b/third_party/blink/renderer/modules/modules_idl_files.gni
@@ -138,6 +138,7 @@ "filesystem/file_entry.idl", "filesystem/file_entry_sync.idl", "filesystem/file_system_callback.idl", + "filesystem/file_system_writer.idl", "filesystem/file_writer.idl", "filesystem/file_writer_callback.idl", "filesystem/file_writer_sync.idl",
diff --git a/third_party/blink/renderer/modules/vr/vr_controller.cc b/third_party/blink/renderer/modules/vr/vr_controller.cc index f505d19..c726001e 100644 --- a/third_party/blink/renderer/modules/vr/vr_controller.cc +++ b/third_party/blink/renderer/modules/vr/vr_controller.cc
@@ -28,9 +28,10 @@ device::mojom::blink::VRServiceClientPtr client; binding_.Bind(mojo::MakeRequest(&client)); - service_->SetClient( - std::move(client), - WTF::Bind(&VRController::OnDisplaysSynced, WrapPersistent(this))); + service_->SetClient(std::move(client)); + + service_->RequestDevice( + WTF::Bind(&VRController::OnRequestDeviceReturned, WrapPersistent(this))); } VRController::~VRController() = default; @@ -41,7 +42,10 @@ // disconnected this will be an empty array. if (!service_ || display_synced_) { LogGetDisplayResult(); - resolver->Resolve(displays_); + HeapVector<Member<VRDisplay>> displays; + if (display_) + displays.push_back(display_); + resolver->Resolve(displays); return; } @@ -52,37 +56,94 @@ } void VRController::SetListeningForActivate(bool listening) { - if (service_) - service_->SetListeningForActivate(listening); + if (!service_ || !display_) { + pending_listening_for_activate_ = listening; + return; + } + + if (listening_for_activate_ && listening) { + // We're already listening so leave things as is. + return; + } + + listening_for_activate_ = listening; + + if (listening) { + service_->SetListeningForActivate(display_->GetDisplayClient()); + } else { + service_->SetListeningForActivate(nullptr); + } } -// Each time a new VRDisplay is connected we'll receive a VRDisplayPtr for it -// here. Upon calling SetClient in the constructor we should receive one call -// for each VRDisplay that was already connected at the time. -void VRController::OnDisplayConnected( - device::mojom::blink::XRDevicePtr device, - device::mojom::blink::VRDisplayClientRequest request, - device::mojom::blink::VRDisplayInfoPtr display_info) { - VRDisplay* vr_display = - new VRDisplay(navigator_vr_, std::move(device), std::move(request)); - vr_display->Update(display_info); - vr_display->OnConnected(); - vr_display->FocusChanged(); +// Called when the XRDevice has been initialized. +void VRController::OnRequestDeviceReturned( + device::mojom::blink::XRDevicePtr device) { + if (!device) { + // There are no devices connected to the system. We can't do any VR, at all. + OnGetDisplays(); + return; + } - has_presentation_capable_display_ = display_info->capabilities->canPresent; - has_display_ = true; + device->GetImmersiveVRDisplayInfo(WTF::Bind( + &VRController::OnImmersiveDisplayInfoReturned, WrapPersistent(this))); - displays_.push_back(vr_display); + display_ = new VRDisplay(navigator_vr_, std::move(device)); + + if (pending_listening_for_activate_) { + SetListeningForActivate(pending_listening_for_activate_); + pending_listening_for_activate_ = false; + } +} + +void VRController::OnNewDeviceReturned( + device::mojom::blink::XRDevicePtr device) { + if (device) { + display_->OnConnected(); + } + OnRequestDeviceReturned(std::move(device)); +} + +void VRController::OnDeviceChanged() { + if (!display_ && !display_synced_) { + // We're already underway checking if there is a device. + return; + } + + display_synced_ = false; + + if (!display_) { + service_->RequestDevice( + WTF::Bind(&VRController::OnNewDeviceReturned, WrapPersistent(this))); + } else if (!display_->canPresent()) { + // If we can't present, see if that's changed. + display_->device()->GetImmersiveVRDisplayInfo(WTF::Bind( + &VRController::OnImmersiveDisplayInfoReturned, WrapPersistent(this))); + } else { + display_synced_ = true; + } } void VRController::FocusChanged() { - for (const auto& display : displays_) - display->FocusChanged(); + if (display_) + display_->FocusChanged(); } -// Called when the VRService has called OnDisplayConnected for all active -// VRDisplays. -void VRController::OnDisplaysSynced() { +void VRController::OnImmersiveDisplayInfoReturned( + device::mojom::blink::VRDisplayInfoPtr info) { + if (!display_) { + // We must have been disposed and are shutting down. + return; + } + + has_presentation_capable_display_ = info ? true : false; + + if (info) { + display_->OnChanged(std::move(info), true /* is_immersive */); + display_->OnConnected(); + has_display_ = true; + } + display_->FocusChanged(); + display_synced_ = true; OnGetDisplays(); } @@ -102,9 +163,14 @@ void VRController::OnGetDisplays() { while (!pending_get_devices_callbacks_.IsEmpty()) { LogGetDisplayResult(); + + HeapVector<Member<VRDisplay>> displays; + if (display_) + displays.push_back(display_); + std::unique_ptr<VRGetDevicesCallback> callback = pending_get_devices_callbacks_.TakeFirst(); - callback->OnSuccess(displays_); + callback->OnSuccess(displays); } } @@ -119,10 +185,10 @@ binding_.Close(); // Shutdown all displays' message pipe - for (const auto& display : displays_) - display->Dispose(); - - displays_.clear(); + if (display_) { + display_->Dispose(); + display_ = nullptr; + } // Ensure that any outstanding getDisplays promises are resolved. OnGetDisplays(); @@ -130,7 +196,7 @@ void VRController::Trace(blink::Visitor* visitor) { visitor->Trace(navigator_vr_); - visitor->Trace(displays_); + visitor->Trace(display_); ContextLifecycleObserver::Trace(visitor); }
diff --git a/third_party/blink/renderer/modules/vr/vr_controller.h b/third_party/blink/renderer/modules/vr/vr_controller.h index d09ceb8..d49ab9c 100644 --- a/third_party/blink/renderer/modules/vr/vr_controller.h +++ b/third_party/blink/renderer/modules/vr/vr_controller.h
@@ -34,9 +34,8 @@ void GetDisplays(ScriptPromiseResolver*); void SetListeningForActivate(bool); - void OnDisplayConnected(device::mojom::blink::XRDevicePtr, - device::mojom::blink::VRDisplayClientRequest, - device::mojom::blink::VRDisplayInfoPtr) override; + // VRServiceClient override. + void OnDeviceChanged() override; void FocusChanged(); @@ -46,6 +45,14 @@ void OnDisplaysSynced(); void OnGetDisplays(); + // Initial callback for requesting the device when VR boots up. + void OnRequestDeviceReturned(device::mojom::blink::XRDevicePtr); + // Callback for subsequent request device calls. + void OnNewDeviceReturned(device::mojom::blink::XRDevicePtr); + + void OnImmersiveDisplayInfoReturned( + device::mojom::blink::VRDisplayInfoPtr info); + // ContextLifecycleObserver. void ContextDestroyed(ExecutionContext*) override; void Dispose(); @@ -53,12 +60,14 @@ void LogGetDisplayResult(); Member<NavigatorVR> navigator_vr_; - VRDisplayVector displays_; + Member<VRDisplay> display_; bool display_synced_; bool has_presentation_capable_display_ = false; bool has_display_ = false; + bool pending_listening_for_activate_ = false; + bool listening_for_activate_ = false; Deque<std::unique_ptr<VRGetDevicesCallback>> pending_get_devices_callbacks_; device::mojom::blink::VRServicePtr service_;
diff --git a/third_party/blink/renderer/modules/vr/vr_display.cc b/third_party/blink/renderer/modules/vr/vr_display.cc index 771340b..fe269f8 100644 --- a/third_party/blink/renderer/modules/vr/vr_display.cc +++ b/third_party/blink/renderer/modules/vr/vr_display.cc
@@ -44,10 +44,10 @@ namespace { -// Threshold for rejecting stored magic window poses as being too old. -// If it's exceeded, defer magic window rAF callback execution until +// Threshold for rejecting stored non-immersive poses as being too old. +// If it's exceeded, defer non-immersive rAF callback execution until // a fresh pose is received. -constexpr WTF::TimeDelta kMagicWindowPoseAgeThreshold = +constexpr WTF::TimeDelta kNonImmersivePoseAgeThreshold = WTF::TimeDelta::FromMilliseconds(250); VREye StringToVREye(const String& which_eye) { @@ -65,7 +65,7 @@ : vr_display_(vr_display) {} ~VRDisplayFrameRequestCallback() override = default; void Invoke(double high_res_time_ms) override { - if (Id() != vr_display_->PendingMagicWindowVSyncId()) + if (Id() != vr_display_->PendingNonImmersiveVSyncId()) return; TimeTicks monotonic_time; if (!vr_display_->GetDocument() || !vr_display_->GetDocument()->Loader()) { @@ -79,7 +79,7 @@ monotonic_time = reference_monotonic_time + TimeDelta::FromMillisecondsD(high_res_time_ms); } - vr_display_->OnMagicWindowVSync(monotonic_time); + vr_display_->OnNonImmersiveVSync(monotonic_time); } void Trace(blink::Visitor* visitor) override { @@ -93,17 +93,45 @@ } // namespace +SessionClientBinding::SessionClientBinding( + VRDisplay* display, + bool is_immersive, + device::mojom::blink::XRSessionClientRequest request) + : display_(display), + is_immersive_(is_immersive), + client_binding_(this, std::move(request)){}; + +SessionClientBinding::~SessionClientBinding() = default; + +void SessionClientBinding::Close() { + DCHECK(client_binding_); + client_binding_.Close(); +} +void SessionClientBinding::OnChanged( + device::mojom::blink::VRDisplayInfoPtr ptr) { + display_->OnChanged(std::move(ptr), is_immersive_); +}; +void SessionClientBinding::OnExitPresent() { + display_->OnExitPresent(is_immersive_); +}; +void SessionClientBinding::OnBlur() { + display_->OnBlur(is_immersive_); +}; +void SessionClientBinding::OnFocus() { + display_->OnFocus(is_immersive_); +}; + VRDisplay::VRDisplay(NavigatorVR* navigator_vr, - device::mojom::blink::XRDevicePtr device, - device::mojom::blink::VRDisplayClientRequest request) + device::mojom::blink::XRDevicePtr device) : PausableObject(navigator_vr->GetDocument()), navigator_vr_(navigator_vr), capabilities_(new VRDisplayCapabilities()), device_ptr_(std::move(device)), - display_client_binding_(this, std::move(request)) { + display_client_binding_(this) { PauseIfNeeded(); // Initialize SuspendabaleObject. - // Request a non-exclusive session to provide magic window. + // Request a non-immersive session immediately as WebVR 1.1 expects to be able + // to get non-immersive poses as soon as the display is returned. device::mojom::blink::XRSessionOptionsPtr options = device::mojom::blink::XRSessionOptions::New(); options->immersive = false; @@ -112,7 +140,7 @@ // TODO(offenwanger): clean up the logging when refactors are complete. device_ptr_->RequestSession( std::move(options), true, - WTF::Bind(&VRDisplay::OnMagicWindowRequestReturned, + WTF::Bind(&VRDisplay::OnNonImmersiveSessionRequestReturned, WrapPersistent(this))); } @@ -225,7 +253,7 @@ << " start: pending_vrdisplay_raf_=" << pending_vrdisplay_raf_ << " in_animation_frame_=" << in_animation_frame_ << " did_submit_this_frame_=" << did_submit_this_frame_ - << " pending_magic_window_vsync_=" << pending_magic_window_vsync_ + << " pending_non_immersive_vsync_=" << pending_non_immersive_vsync_ << " pending_presenting_vsync_=" << pending_presenting_vsync_; if (!pending_vrdisplay_raf_) return; @@ -241,7 +269,7 @@ if (pending_presenting_vsync_) return; - pending_magic_window_vsync_ = false; + pending_non_immersive_vsync_ = false; pending_presenting_vsync_ = true; vr_presentation_data_provider_->GetFrameData( WTF::Bind(&VRDisplay::OnPresentingVSync, WrapWeakPersistent(this))); @@ -249,23 +277,23 @@ DVLOG(2) << __FUNCTION__ << " done: pending_presenting_vsync_=" << pending_presenting_vsync_; } else { - // Check if magic_window_provider_, if not then we are not fully - // initialized, or we do not support magic window, so don't request the - // vsync. If and when magic_window_provider_ is set it will run this code + // Check if non_immersive_provider_, if not then we are not fully + // initialized, or we do not support non-immersive, so don't request the + // vsync. If and when non_immersive_provider_ is set it will run this code // again. - if (!magic_window_provider_) + if (!non_immersive_provider_) return; - if (pending_magic_window_vsync_) + if (pending_non_immersive_vsync_) return; - magic_window_vsync_waiting_for_pose_.Reset(); - magic_window_pose_request_time_ = WTF::CurrentTimeTicks(); - magic_window_provider_->GetFrameData(WTF::Bind( - &VRDisplay::OnMagicWindowFrameData, WrapWeakPersistent(this))); - pending_magic_window_vsync_ = true; - pending_magic_window_vsync_id_ = + non_immersive_vsync_waiting_for_pose_.Reset(); + non_immersive_pose_request_time_ = WTF::CurrentTimeTicks(); + non_immersive_provider_->GetFrameData(WTF::Bind( + &VRDisplay::OnNonImmersiveFrameData, WrapWeakPersistent(this))); + pending_non_immersive_vsync_ = true; + pending_non_immersive_vsync_id_ = doc->RequestAnimationFrame(new VRDisplayFrameRequestCallback(this)); - DVLOG(2) << __FUNCTION__ << " done: pending_magic_window_vsync_=" - << pending_magic_window_vsync_; + DVLOG(2) << __FUNCTION__ << " done: pending_non_immersive_vsync_=" + << pending_non_immersive_vsync_; } } @@ -292,14 +320,20 @@ scripted_animation_controller_->CancelCallback(id); } -void VRDisplay::OnBlur() { +void VRDisplay::OnBlur(bool is_immersive) { + // TODO(http://crbug.com/845283) When cleaning up the Blur events, determine + // whether we should react to blur events from both immersive and non- + // immersive sessions. DVLOG(1) << __FUNCTION__; display_blurred_ = true; navigator_vr_->EnqueueVREvent( VRDisplayEvent::Create(EventTypeNames::vrdisplayblur, this, "")); } -void VRDisplay::OnFocus() { +void VRDisplay::OnFocus(bool is_immersive) { + // TODO(http://crbug.com/845283) When cleaning up the Blur events, determine + // whether we should react to blur events from both immersive and non- + // immersive sessions. DVLOG(1) << __FUNCTION__; display_blurred_ = false; RequestVSync(); @@ -483,7 +517,8 @@ device_ptr_->RequestSession( std::move(options), in_display_activate_, - WTF::Bind(&VRDisplay::OnRequestSessionReturned, WrapPersistent(this))); + WTF::Bind(&VRDisplay::OnRequestImmersiveSessionReturned, + WrapPersistent(this))); pending_present_request_ = true; // The old vr_presentation_provider_ won't be delivering any vsyncs anymore, @@ -498,11 +533,12 @@ return promise; } -void VRDisplay::OnRequestSessionReturned( +void VRDisplay::OnRequestImmersiveSessionReturned( device::mojom::blink::XRSessionPtr session) { pending_present_request_ = false; if (session) { DCHECK(session->submit_frame_sink); + vr_presentation_data_provider_.reset(); vr_presentation_data_provider_.Bind(std::move(session->data_provider)); // The presentation provider error handler can trigger if a device is // disconnected from the system. This can happen if, for example, an HMD is @@ -522,6 +558,13 @@ frame_transport_->SetTransportOptions( std::move(session->submit_frame_sink->transport_options)); + if (immersive_client_binding_) + immersive_client_binding_->Close(); + immersive_client_binding_ = std::make_unique<SessionClientBinding>( + this, false, std::move(session->client_request)); + + Update(std::move(session->display_info)); + this->BeginPresent(); } else { this->ForceExitPresent(); @@ -535,13 +578,15 @@ } } -void VRDisplay::OnMagicWindowRequestReturned( +void VRDisplay::OnNonImmersiveSessionRequestReturned( device::mojom::blink::XRSessionPtr session) { if (!session) { // System does not support any kind of session. return; } - magic_window_provider_.Bind(std::move(session->data_provider)); + non_immersive_provider_.Bind(std::move(session->data_provider)); + non_immersive_client_binding_ = std::make_unique<SessionClientBinding>( + this, false, std::move(session->client_request)); RequestVSync(); } @@ -615,7 +660,7 @@ if (!FocusedOrPresenting() && display_blurred_) { // Presentation doesn't care about focus, so if we're blurred because of // focus, then unblur. - OnFocus(); + OnFocus(true); } is_presenting_ = true; // Call RequestVSync to switch from the (internal) document rAF to the @@ -797,6 +842,13 @@ return navigator_vr_->GetDocument(); } +device::mojom::blink::VRDisplayClientPtr VRDisplay::GetDisplayClient() { + display_client_binding_.Close(); + device::mojom::blink::VRDisplayClientPtr client; + display_client_binding_.Bind(mojo::MakeRequest(&client)); + return client; +} + void VRDisplay::OnPresentChange() { if (frame_transport_) frame_transport_->PresentChange(); @@ -810,12 +862,22 @@ VRDisplayEvent::Create(EventTypeNames::vrdisplaypresentchange, this, "")); } -void VRDisplay::OnChanged(device::mojom::blink::VRDisplayInfoPtr display) { - Update(display); +void VRDisplay::OnChanged(device::mojom::blink::VRDisplayInfoPtr display, + bool is_immersive) { + // VrDisplayInfo is only used for immersive sessions, so unless this is + // from an immersive device, ignore it. + // We expect that non-immersive sessions don't use display info, and immersive + // sessions will not use display info until they are presenting, so it is fine + // for us not to start listening until then. + if (is_immersive) { + Update(display); + } } -void VRDisplay::OnExitPresent() { - StopPresenting(); +void VRDisplay::OnExitPresent(bool is_immersive) { + if (is_immersive) { + StopPresenting(); + } } void VRDisplay::OnConnected() { @@ -957,7 +1019,7 @@ // Sanity check: If pending_vrdisplay_raf_ is true and the vsync provider // is connected, we must now have a pending vsync. - DCHECK(!pending_vrdisplay_raf_ || pending_magic_window_vsync_ || + DCHECK(!pending_vrdisplay_raf_ || pending_non_immersive_vsync_ || pending_presenting_vsync_); } @@ -973,7 +1035,7 @@ return; } - // All early exits that want this VSync converted to a magic window + // All early exits that want this VSync converted to a non-immersive // VSync must happen before this line. Once it's set to not pending, // an early exit woud break animation. pending_presenting_vsync_ = false; @@ -999,24 +1061,24 @@ TimeTicks() + frame_data->time_delta)); } -void VRDisplay::OnMagicWindowVSync(TimeTicks timestamp) { +void VRDisplay::OnNonImmersiveVSync(TimeTicks timestamp) { DVLOG(2) << __FUNCTION__; - pending_magic_window_vsync_ = false; - pending_magic_window_vsync_id_ = -1; + pending_non_immersive_vsync_ = false; + pending_non_immersive_vsync_id_ = -1; if (is_presenting_) return; vr_frame_id_ = -1; WTF::TimeDelta pose_age = - WTF::CurrentTimeTicks() - magic_window_pose_received_time_; - if (pose_age >= kMagicWindowPoseAgeThreshold && - magic_window_pose_request_time_ > magic_window_pose_received_time_) { + WTF::CurrentTimeTicks() - non_immersive_pose_received_time_; + if (pose_age >= kNonImmersivePoseAgeThreshold && + non_immersive_pose_request_time_ > non_immersive_pose_received_time_) { // The VSync got triggered before ever receiving a pose, or the pose is // stale. Defer the animation until a pose arrives to avoid passing null // poses to the application, but only do this if we have an outstanding // unresolved GetPose request. For example, the pose might be stale after - // exiting VR Browser magic window mode due to a longish transition, but we + // exiting VR Browser non-immersive mode due to a longish transition, but we // need to use it anyway if it's from the current frame's GetPose. - magic_window_vsync_waiting_for_pose_ = + non_immersive_vsync_waiting_for_pose_ = WTF::Bind(&VRDisplay::ProcessScheduledAnimations, WrapWeakPersistent(this), timestamp); } else { @@ -1024,9 +1086,9 @@ } } -void VRDisplay::OnMagicWindowFrameData( +void VRDisplay::OnNonImmersiveFrameData( device::mojom::blink::XRFrameDataPtr data) { - magic_window_pose_received_time_ = WTF::CurrentTimeTicks(); + non_immersive_pose_received_time_ = WTF::CurrentTimeTicks(); if (data) { if (!in_animation_frame_) { frame_pose_ = std::move(data->pose); @@ -1034,16 +1096,16 @@ pending_pose_ = std::move(data->pose); } } - if (magic_window_vsync_waiting_for_pose_) { + if (non_immersive_vsync_waiting_for_pose_) { // We have a vsync waiting for a pose, run it now. - std::move(magic_window_vsync_waiting_for_pose_).Run(); - magic_window_vsync_waiting_for_pose_.Reset(); + std::move(non_immersive_vsync_waiting_for_pose_).Run(); + non_immersive_vsync_waiting_for_pose_.Reset(); } } void VRDisplay::OnPresentationProviderConnectionError() { DVLOG(1) << __FUNCTION__ << ";;; is_presenting_=" << is_presenting_ - << " pending_magic_window_vsync_=" << pending_magic_window_vsync_ + << " pending_non_immersive_vsync_=" << pending_non_immersive_vsync_ << " pending_presenting_vsync_=" << pending_presenting_vsync_; vr_presentation_provider_.reset(); vr_presentation_data_provider_.reset(); @@ -1063,7 +1125,9 @@ } void VRDisplay::Dispose() { - display_client_binding_.Close(); + if (non_immersive_client_binding_) + non_immersive_client_binding_->Close(); + non_immersive_client_binding_ = nullptr; vr_presentation_provider_.reset(); } @@ -1093,9 +1157,13 @@ void VRDisplay::FocusChanged() { DVLOG(1) << __FUNCTION__; if (navigator_vr_->IsFocused()) { - OnFocus(); + if (is_presenting_) { + OnFocus(true /* is_immmersive */); + } else { + OnFocus(false /* is_immmersive */); + } } else if (!is_presenting_) { - OnBlur(); + OnBlur(false); } }
diff --git a/third_party/blink/renderer/modules/vr/vr_display.h b/third_party/blink/renderer/modules/vr/vr_display.h index 5cd4aee..98fe777 100644 --- a/third_party/blink/renderer/modules/vr/vr_display.h +++ b/third_party/blink/renderer/modules/vr/vr_display.h
@@ -35,9 +35,33 @@ class VREyeParameters; class VRFrameData; class VRStageParameters; +class VRDisplay; class WebGLRenderingContextBase; +// Wrapper class to allow the VRDisplay to distinguish between immersive and +// non-immersive XRSession events. +class SessionClientBinding : public device::mojom::blink::XRSessionClient { + public: + SessionClientBinding(VRDisplay* display, + bool is_immersive, + device::mojom::blink::XRSessionClientRequest request); + ~SessionClientBinding() override; + void Close(); + + private: + void OnChanged(device::mojom::blink::VRDisplayInfoPtr) override; + void OnExitPresent() override; + void OnBlur() override; + void OnFocus() override; + + // VRDisplay keeps all references to SessionClientBinding, so as soon as + // VRDisplay is destroyed, so is the SessionClientBinding. + UntracedMember<VRDisplay> display_; + bool is_immersive_; + mojo::Binding<device::mojom::blink::XRSessionClient> client_binding_; +}; + enum VREye { kVREyeNone, kVREyeLeft, kVREyeRight }; class VRDisplay final : public EventTargetWithInlineData, @@ -57,8 +81,10 @@ VRDisplayCapabilities* capabilities() const { return capabilities_; } VRStageParameters* stageParameters() const { return stage_parameters_; } + device::mojom::blink::XRDevice* device() { return device_ptr_.get(); } bool isPresenting() const { return is_presenting_; } + bool canPresent() const { return capabilities_->canPresent(); } bool getFrameData(VRFrameData*); @@ -82,6 +108,7 @@ void submitFrame(); Document* GetDocument(); + device::mojom::blink::VRDisplayClientPtr GetDisplayClient(); // EventTarget overrides: ExecutionContext* GetExecutionContext() const override; @@ -97,19 +124,22 @@ void Pause() override; void Unpause() override; + void OnChanged(device::mojom::blink::VRDisplayInfoPtr, bool is_immersive); + void OnExitPresent(bool is_immersive); + void OnBlur(bool is_immersive); + void OnFocus(bool is_immersive); + void FocusChanged(); - void OnMagicWindowVSync(TimeTicks timestamp); - int PendingMagicWindowVSyncId() { return pending_magic_window_vsync_id_; } + void OnNonImmersiveVSync(TimeTicks timestamp); + int PendingNonImmersiveVSyncId() { return pending_non_immersive_vsync_id_; } void Trace(blink::Visitor*) override; protected: friend class VRController; - VRDisplay(NavigatorVR*, - device::mojom::blink::XRDevicePtr, - device::mojom::blink::VRDisplayClientRequest); + VRDisplay(NavigatorVR*, device::mojom::blink::XRDevicePtr); void Update(const device::mojom::blink::VRDisplayInfoPtr&); @@ -123,8 +153,10 @@ VRController* Controller(); private: - void OnRequestSessionReturned(device::mojom::blink::XRSessionPtr session); - void OnMagicWindowRequestReturned(device::mojom::blink::XRSessionPtr session); + void OnRequestImmersiveSessionReturned( + device::mojom::blink::XRSessionPtr session); + void OnNonImmersiveSessionRequestReturned( + device::mojom::blink::XRSessionPtr session); void OnConnected(); void OnDisconnected(); @@ -134,10 +166,6 @@ void OnPresentChange(); // VRDisplayClient - void OnChanged(device::mojom::blink::VRDisplayInfoPtr) override; - void OnExitPresent() override; - void OnBlur() override; - void OnFocus() override; void OnActivate(device::mojom::blink::VRDisplayEventReason, OnActivateCallback on_handled) override; void OnDeactivate(device::mojom::blink::VRDisplayEventReason) override; @@ -145,7 +173,7 @@ void OnPresentingVSync(device::mojom::blink::XRFrameDataPtr); void OnPresentationProviderConnectionError(); - void OnMagicWindowFrameData(device::mojom::blink::XRFrameDataPtr); + void OnNonImmersiveFrameData(device::mojom::blink::XRFrameDataPtr); bool FocusedOrPresenting(); @@ -201,11 +229,11 @@ scripted_animation_controller_; bool pending_vrdisplay_raf_ = false; bool pending_presenting_vsync_ = false; - bool pending_magic_window_vsync_ = false; - int pending_magic_window_vsync_id_ = -1; - base::OnceClosure magic_window_vsync_waiting_for_pose_; - WTF::TimeTicks magic_window_pose_request_time_; - WTF::TimeTicks magic_window_pose_received_time_; + bool pending_non_immersive_vsync_ = false; + int pending_non_immersive_vsync_id_ = -1; + base::OnceClosure non_immersive_vsync_waiting_for_pose_; + WTF::TimeTicks non_immersive_pose_request_time_; + WTF::TimeTicks non_immersive_pose_received_time_; bool in_animation_frame_ = false; bool did_submit_this_frame_ = false; bool display_blurred_ = false; @@ -216,12 +244,14 @@ bool did_log_getFrameData_ = false; bool did_log_requestPresent_ = false; - device::mojom::blink::XRFrameDataProviderPtr magic_window_provider_; + device::mojom::blink::XRFrameDataProviderPtr non_immersive_provider_; device::mojom::blink::XRDevicePtr device_ptr_; bool present_image_needs_copy_ = false; + std::unique_ptr<SessionClientBinding> non_immersive_client_binding_; + std::unique_ptr<SessionClientBinding> immersive_client_binding_; mojo::Binding<device::mojom::blink::VRDisplayClient> display_client_binding_; device::mojom::blink::XRFrameDataProviderPtr vr_presentation_data_provider_; device::mojom::blink::XRPresentationProviderPtr vr_presentation_provider_;
diff --git a/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.cc b/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.cc index 8a28001..bf7cb5c 100644 --- a/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.cc +++ b/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.cc
@@ -1204,7 +1204,7 @@ GLint border, GLenum format, GLenum type, - HTMLCanvasElement* canvas, + CanvasRenderingContextHost* canvas, ExceptionState& exception_state) { if (isContextLost()) return; @@ -1469,7 +1469,7 @@ GLsizei height, GLenum format, GLenum type, - HTMLCanvasElement* canvas, + CanvasRenderingContextHost* canvas, ExceptionState& exception_state) { if (isContextLost()) return; @@ -1811,7 +1811,7 @@ GLint border, GLenum format, GLenum type, - HTMLCanvasElement* canvas, + CanvasRenderingContextHost* canvas, ExceptionState& exception_state) { if (isContextLost()) return;
diff --git a/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.h b/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.h index 90e6b90..27e18e2 100644 --- a/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.h +++ b/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.h
@@ -128,7 +128,7 @@ GLint, GLenum, GLenum, - HTMLCanvasElement*, + CanvasRenderingContextHost*, ExceptionState&); void texImage2D(ExecutionContext*, GLenum, @@ -200,7 +200,7 @@ GLsizei, GLenum, GLenum, - HTMLCanvasElement*, + CanvasRenderingContextHost*, ExceptionState&); void texSubImage2D(ExecutionContext*, GLenum, @@ -361,7 +361,7 @@ GLint, GLenum, GLenum, - HTMLCanvasElement*, + CanvasRenderingContextHost*, ExceptionState&); void texImage3D(ExecutionContext*, GLenum,
diff --git a/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.idl b/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.idl index 0952630..9046cbf9 100644 --- a/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.idl +++ b/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.idl
@@ -298,6 +298,7 @@ void texImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, ImageData data); [CallWith=ExecutionContext, RaisesException] void texImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, HTMLImageElement image); [CallWith=ExecutionContext, RaisesException] void texImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, HTMLCanvasElement canvas); + [CallWith=ExecutionContext, RaisesException] void texImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, OffscreenCanvas offscreenCanvas); [CallWith=ExecutionContext,RaisesException] void texImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, HTMLVideoElement video); [RaisesException] void texImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, ImageBitmap bitmap); void texImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, [AllowShared] ArrayBufferView srcData, GLuint srcOffset); @@ -305,6 +306,7 @@ void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, ImageData data); [CallWith=ExecutionContext, RaisesException] void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, HTMLImageElement image); [CallWith=ExecutionContext, RaisesException] void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, HTMLCanvasElement canvas); + [CallWith=ExecutionContext, RaisesException] void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, OffscreenCanvas offscreenCanvas); [CallWith=ExecutionContext, RaisesException] void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, HTMLVideoElement video); [RaisesException] void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, ImageBitmap bitmap); void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, [AllowShared] ArrayBufferView srcData, GLuint srcOffset); @@ -314,6 +316,7 @@ void texImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, ImageData data); [CallWith=ExecutionContext, RaisesException] void texImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, HTMLImageElement image); [CallWith=ExecutionContext, RaisesException] void texImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, HTMLCanvasElement canvas); + [CallWith=ExecutionContext, RaisesException] void texImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, OffscreenCanvas offscreenCanvas); [CallWith=ExecutionContext, RaisesException] void texImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, HTMLVideoElement video); [RaisesException] void texImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, ImageBitmap bitmap); void texImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, [AllowShared] ArrayBufferView? pixels); @@ -322,6 +325,7 @@ void texSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, ImageData data); [CallWith=ExecutionContext, RaisesException] void texSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, HTMLImageElement image); [CallWith=ExecutionContext, RaisesException] void texSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, HTMLCanvasElement canvas); + [CallWith=ExecutionContext, RaisesException] void texSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, OffscreenCanvas offscreenCanvas); [CallWith=ExecutionContext, RaisesException] void texSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, HTMLVideoElement video); [RaisesException] void texSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, ImageBitmap bitmap); void texSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, [AllowShared] ArrayBufferView pixels, optional GLuint srcOffset = 0);
diff --git a/third_party/blink/renderer/modules/xr/xr.cc b/third_party/blink/renderer/modules/xr/xr.cc index 32fbd78..94d75fb3 100644 --- a/third_party/blink/renderer/modules/xr/xr.cc +++ b/third_party/blink/renderer/modules/xr/xr.cc
@@ -32,26 +32,17 @@ XR::XR(LocalFrame& frame, int64_t ukm_source_id) : ContextLifecycleObserver(frame.GetDocument()), FocusChangedObserver(frame.GetPage()), - devices_synced_(false), ukm_source_id_(ukm_source_id), binding_(this) { frame.GetInterfaceProvider().GetInterface(mojo::MakeRequest(&service_)); service_.set_connection_error_handler( WTF::Bind(&XR::Dispose, WrapWeakPersistent(this))); - - device::mojom::blink::VRServiceClientPtr client; - binding_.Bind(mojo::MakeRequest(&client)); - - // Setting the client kicks off a request for the details of any connected - // XRDevices. - service_->SetClient(std::move(client), - WTF::Bind(&XR::OnDevicesSynced, WrapPersistent(this))); } void XR::FocusedFrameChanged() { - // Tell devices that focus changed. - for (const auto& device : devices_) - device->OnFrameFocusChanged(); + // Tell device that focus changed. + if (device_) + device_->OnFrameFocusChanged(); } bool XR::IsFrameFocused() { @@ -99,60 +90,58 @@ ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state); ScriptPromise promise = resolver->Promise(); - // If we've previously synced the XRDevices or no longer have a valid service - // connection just use the current list. In the case of the service being - // disconnected this will be an empty array. - if (!service_ || devices_synced_) { - // TODO (offenwanger): When we have a prioritized order of devices, or some - // other method of getting the prefered device, insert that here. For now, - // just get the first device out of the list, if there is one. - if (devices_.size() == 0) { - resolver->Reject(DOMException::Create(DOMExceptionCode::kNotFoundError, - kNoDevicesMessage)); - } else { - resolver->Resolve(devices_[0]); - } - + // If we no longer have a valid service connection reject the request. + if (!service_) { + resolver->Reject(DOMException::Create(DOMExceptionCode::kNotFoundError, + kNoDevicesMessage)); return promise; } - // Otherwise wait for the full list of devices to be populated and resolve - // when onDevicesSynced is called. + // If we already have a device, use that. + if (device_) { + resolver->Resolve(device_); + return promise; + } + + // Otherwise wait for device request callback. pending_devices_resolver_ = resolver; + // If we're waiting for sync, then request device is already underway. + if (pending_sync_) { + return promise; + } + + service_->RequestDevice( + WTF::Bind(&XR::OnRequestDeviceReturned, WrapPersistent(this))); + pending_sync_ = true; + return promise; } -// Each time a new XRDevice is connected we'll recieve a XRDisplayPtr for it -// here. Upon calling SetClient in the constructor we should receive one call -// for each XRDevice that was already connected at the time. -void XR::OnDisplayConnected( - device::mojom::blink::XRDevicePtr device, - device::mojom::blink::VRDisplayClientRequest client_request, - device::mojom::blink::VRDisplayInfoPtr display_info) { - XRDevice* xr_device = - new XRDevice(this, std::move(device), std::move(client_request), - std::move(display_info)); - - devices_.push_back(xr_device); - +// This will call when the XRDevice and its capabilities has potentially +// changed. For example, if a new physical device was connected to the system, +// the XRDevice might now be able to support immersive sessions, where it +// couldn't before. +void XR::OnDeviceChanged() { DispatchEvent(*blink::Event::Create(EventTypeNames::devicechange)); } -// Called when the XRService has called OnDevicesConnected for all active -// XRDevices. -void XR::OnDevicesSynced() { - devices_synced_ = true; +void XR::OnRequestDeviceReturned(device::mojom::blink::XRDevicePtr device) { + pending_sync_ = false; + if (device) { + device_ = new XRDevice(this, std::move(device)); + } ResolveRequestDevice(); } // Called when details for every connected XRDevice has been received. void XR::ResolveRequestDevice() { if (pending_devices_resolver_) { - if (devices_.size() == 0) { + if (!device_) { pending_devices_resolver_->Reject(DOMException::Create( DOMExceptionCode::kNotFoundError, kNoDevicesMessage)); } else { + // Log metrics if (!did_log_returned_device_ || !did_log_supports_immersive_) { Document* doc = GetFrame() ? GetFrame()->GetDocument() : nullptr; if (doc) { @@ -160,23 +149,59 @@ ukm_builder.SetReturnedDevice(1); did_log_returned_device_ = true; - // We only expose a single device to WebXR, so report that device's - // capabilities. - if (devices_[0]->SupportsImmersive()) { - ukm_builder.SetReturnedPresentationCapableDevice(1); - did_log_supports_immersive_ = true; - } - ukm_builder.Record(doc->UkmRecorder()); + + device::mojom::blink::XRSessionOptionsPtr session_options = + device::mojom::blink::XRSessionOptions::New(); + session_options->immersive = true; + + // TODO(http://crbug.com/872086) This shouldn't need to be called. + // This information should be logged on the browser side. + device_->xrDevicePtr()->SupportsSession( + std::move(session_options), + WTF::Bind(&XR::ReportImmersiveSupported, WrapPersistent(this))); } } - pending_devices_resolver_->Resolve(devices_[0]); + + // Return the device. + pending_devices_resolver_->Resolve(device_); } pending_devices_resolver_ = nullptr; } } +void XR::ReportImmersiveSupported(bool supported) { + Document* doc = GetFrame() ? GetFrame()->GetDocument() : nullptr; + if (doc && !did_log_supports_immersive_ && supported) { + ukm::builders::XR_WebXR ukm_builder(ukm_source_id_); + ukm_builder.SetReturnedPresentationCapableDevice(1); + ukm_builder.Record(doc->UkmRecorder()); + did_log_supports_immersive_ = true; + } +} + +void XR::AddedEventListener(const AtomicString& event_type, + RegisteredEventListener& registered_listener) { + EventTargetWithInlineData::AddedEventListener(event_type, + registered_listener); + + // If we don't have device and there is no sync pending, then request the + // device to ensure devices have been enumerated and register as a listener + // for changes. + if (event_type == EventTypeNames::devicechange && !device_ && + !pending_sync_) { + device::mojom::blink::VRServiceClientPtr client; + binding_.Bind(mojo::MakeRequest(&client)); + + service_->RequestDevice( + WTF::Bind(&XR::OnRequestDeviceReturned, WrapPersistent(this))); + service_->SetClient(std::move(client)); + + pending_sync_ = true; + } +}; + void XR::ContextDestroyed(ExecutionContext*) { Dispose(); } @@ -187,11 +212,9 @@ service_.reset(); binding_.Close(); - // Shutdown all devices' message pipe - for (const auto& device : devices_) - device->Dispose(); - - devices_.clear(); + // Shutdown device's message pipe. + if (device_) + device_->Dispose(); // Ensure that any outstanding requestDevice promises are resolved. They will // receive a null result. @@ -199,7 +222,7 @@ } void XR::Trace(blink::Visitor* visitor) { - visitor->Trace(devices_); + visitor->Trace(device_); visitor->Trace(pending_devices_resolver_); ContextLifecycleObserver::Trace(visitor); EventTargetWithInlineData::Trace(visitor);
diff --git a/third_party/blink/renderer/modules/xr/xr.h b/third_party/blink/renderer/modules/xr/xr.h index 8462d46..fc3dc56 100644 --- a/third_party/blink/renderer/modules/xr/xr.h +++ b/third_party/blink/renderer/modules/xr/xr.h
@@ -36,10 +36,8 @@ ScriptPromise requestDevice(ScriptState*); - // XRServiceClient overrides. - void OnDisplayConnected(device::mojom::blink::XRDevicePtr, - device::mojom::blink::VRDisplayClientRequest, - device::mojom::blink::VRDisplayInfoPtr) override; + // VRServiceClient overrides. + void OnDeviceChanged() override; // EventTarget overrides. ExecutionContext* GetExecutionContext() const override; @@ -58,11 +56,16 @@ private: explicit XR(LocalFrame& frame, int64_t ukm_source_id_); - void OnDevicesSynced(); + void OnRequestDeviceReturned(device::mojom::blink::XRDevicePtr device); void ResolveRequestDevice(); + void ReportImmersiveSupported(bool supported); + + void AddedEventListener(const AtomicString& event_type, + RegisteredEventListener&) override; + void Dispose(); - bool devices_synced_; + bool pending_sync_ = false; // Indicates whether use of requestDevice has already been logged. bool did_log_requestDevice_ = false; @@ -70,7 +73,7 @@ bool did_log_supports_immersive_ = false; const int64_t ukm_source_id_; - HeapVector<Member<XRDevice>> devices_; + Member<XRDevice> device_; Member<ScriptPromiseResolver> pending_devices_resolver_; device::mojom::blink::VRServicePtr service_; mojo::Binding<device::mojom::blink::VRServiceClient> binding_;
diff --git a/third_party/blink/renderer/modules/xr/xr_device.cc b/third_party/blink/renderer/modules/xr/xr_device.cc index 2efe3f8..43a1612 100644 --- a/third_party/blink/renderer/modules/xr/xr_device.cc +++ b/third_party/blink/renderer/modules/xr/xr_device.cc
@@ -23,9 +23,6 @@ const char kActiveImmersiveSession[] = "XRDevice already has an active, immersive session"; -const char kImmersiveNotSupported[] = - "XRDevice does not support the creation of immersive sessions."; - const char kNoOutputContext[] = "Non-immersive sessions must be created with an outputContext."; @@ -35,19 +32,10 @@ const char kSessionNotSupported[] = "The specified session configuration is not supported."; -const char kRequestFailed[] = "Request for XRSession failed."; - } // namespace -XRDevice::XRDevice(XR* xr, - device::mojom::blink::XRDevicePtr device, - device::mojom::blink::VRDisplayClientRequest client_request, - device::mojom::blink::VRDisplayInfoPtr display_info) - : xr_(xr), - device_ptr_(std::move(device)), - display_client_binding_(this, std::move(client_request)) { - SetXRDisplayInfo(std::move(display_info)); -} +XRDevice::XRDevice(XR* xr, device::mojom::blink::XRDevicePtr device) + : xr_(xr), device_ptr_(std::move(device)) {} const char* XRDevice::checkSessionSupport( const XRSessionCreationOptions& options) const { @@ -59,14 +47,6 @@ } } - if (options.environmentIntegration() && !supports_ar_) { - return kSessionNotSupported; - } - - if (options.immersive() && !supports_immersive_) { - return kSessionNotSupported; - } - return nullptr; } @@ -104,13 +84,10 @@ void XRDevice::OnSupportsSessionReturned(ScriptPromiseResolver* resolver, bool supports_session) { - // kImmersiveNotSupported is currently the only reason that SupportsSession - // rejects on the browser side. That or there are no devices, but that should - // technically not be possible. supports_session ? resolver->Resolve() : resolver->Reject(DOMException::Create( - DOMExceptionCode::kNotSupportedError, kImmersiveNotSupported)); + DOMExceptionCode::kNotSupportedError, kSessionNotSupported)); } int64_t XRDevice::GetSourceId() const { @@ -198,9 +175,11 @@ bool environment_integration, bool immersive, device::mojom::blink::XRSessionPtr session_ptr) { + // TODO(https://crbug.com/872316) Improve the error messaging to indicate why + // a request failed. if (!session_ptr) { DOMException* exception = DOMException::Create( - DOMExceptionCode::kNotAllowedError, kRequestFailed); + DOMExceptionCode::kNotSupportedError, kSessionNotSupported); resolver->Reject(exception); return; } @@ -209,8 +188,13 @@ if (environment_integration) blend_mode = XRSession::kBlendModeAlphaBlend; - XRSession* session = new XRSession(this, immersive, environment_integration, - output_context, blend_mode); + XRSession* session = + new XRSession(this, std::move(session_ptr->client_request), immersive, + environment_integration, output_context, blend_mode); + // immersive sessions must supply display info. + DCHECK(!immersive || session_ptr->display_info); + if (session_ptr->display_info) + session->SetXRDisplayInfo(std::move(session_ptr->display_info)); sessions_.insert(session); if (immersive) { @@ -241,26 +225,6 @@ return xr_->IsFrameFocused(); } -// TODO: Forward these calls on to the sessions once they've been implemented. -void XRDevice::OnChanged(device::mojom::blink::VRDisplayInfoPtr display_info) { - SetXRDisplayInfo(std::move(display_info)); -} -void XRDevice::OnExitPresent() {} -void XRDevice::OnBlur() { - // The device is reporting to us that it is blurred. This could happen for a - // variety of reasons, such as browser UI, a different application using the - // headset, or another page entering an immersive session. - has_device_focus_ = false; - OnFocusChanged(); -} -void XRDevice::OnFocus() { - has_device_focus_ = true; - OnFocusChanged(); -} -void XRDevice::OnActivate(device::mojom::blink::VRDisplayEventReason, - OnActivateCallback on_handled) {} -void XRDevice::OnDeactivate(device::mojom::blink::VRDisplayEventReason) {} - XRFrameProvider* XRDevice::frameProvider() { if (!frame_provider_) { frame_provider_ = new XRFrameProvider(this); @@ -270,20 +234,10 @@ } void XRDevice::Dispose() { - display_client_binding_.Close(); if (frame_provider_) frame_provider_->Dispose(); } -void XRDevice::SetXRDisplayInfo( - device::mojom::blink::VRDisplayInfoPtr display_info) { - display_info_id_++; - display_info_ = std::move(display_info); - is_external_ = display_info_->capabilities->hasExternalDisplay; - supports_immersive_ = (display_info_->capabilities->canPresent); - supports_ar_ = display_info_->capabilities->can_provide_pass_through_images; -} - void XRDevice::Trace(blink::Visitor* visitor) { visitor->Trace(xr_); visitor->Trace(frame_provider_);
diff --git a/third_party/blink/renderer/modules/xr/xr_device.h b/third_party/blink/renderer/modules/xr/xr_device.h index a6508ad..7113265 100644 --- a/third_party/blink/renderer/modules/xr/xr_device.h +++ b/third_party/blink/renderer/modules/xr/xr_device.h
@@ -22,31 +22,16 @@ class XRFrameProvider; class XRSession; -class XRDevice final : public ScriptWrappable, - public device::mojom::blink::VRDisplayClient { +class XRDevice final : public ScriptWrappable { DEFINE_WRAPPERTYPEINFO(); public: - XRDevice(XR*, - device::mojom::blink::XRDevicePtr, - device::mojom::blink::VRDisplayClientRequest, - device::mojom::blink::VRDisplayInfoPtr); + XRDevice(XR*, device::mojom::blink::XRDevicePtr); XR* xr() const { return xr_; } - bool external() const { return is_external_; } - ScriptPromise supportsSession(ScriptState*, const XRSessionCreationOptions&); ScriptPromise requestSession(ScriptState*, const XRSessionCreationOptions&); - // XRDisplayClient - void OnChanged(device::mojom::blink::VRDisplayInfoPtr) override; - void OnExitPresent() override; - void OnBlur() override; - void OnFocus() override; - void OnActivate(device::mojom::blink::VRDisplayEventReason, - OnActivateCallback on_handled) override; - void OnDeactivate(device::mojom::blink::VRDisplayEventReason) override; - XRFrameProvider* frameProvider(); void Dispose(); @@ -62,29 +47,15 @@ xrEnviromentProviderPtr() const { return enviroment_provider_; } - const device::mojom::blink::VRDisplayInfoPtr& xrDisplayInfoPtr() const { - return display_info_; - } - // Incremented every time display_info_ is changed, so that other objects that - // depend on it can know when they need to update. - unsigned int xrDisplayInfoPtrId() const { return display_info_id_; } void OnFrameFocusChanged(); - // The device may report focus to us - for example if another application is - // using the headset, or some browsing UI is shown, we may not have device - // focus. - bool HasDeviceFocus() { return has_device_focus_; } - bool HasDeviceAndFrameFocus() { return IsFrameFocused() && HasDeviceFocus(); } - - bool SupportsImmersive() { return supports_immersive_; } + bool HasFrameFocus() { return IsFrameFocused(); } int64_t GetSourceId() const; void Trace(blink::Visitor*) override; private: - void SetXRDisplayInfo(device::mojom::blink::VRDisplayInfoPtr); - const char* checkSessionSupport(const XRSessionCreationOptions&) const; void OnRequestSessionReturned(ScriptPromiseResolver* resolver, @@ -105,10 +76,6 @@ Member<XR> xr_; Member<XRFrameProvider> frame_provider_; HeapHashSet<WeakMember<XRSession>> sessions_; - bool is_external_ = false; - bool supports_immersive_ = false; - bool supports_ar_ = false; - bool has_device_focus_ = true; // Indicates whether we've already logged a request for an immersive session. bool did_log_request_immersive_session_ = false; @@ -116,10 +83,6 @@ device::mojom::blink::XRFrameDataProviderPtr magic_window_provider_; device::mojom::blink::XREnviromentIntegrationProviderPtr enviroment_provider_; device::mojom::blink::XRDevicePtr device_ptr_; - device::mojom::blink::VRDisplayInfoPtr display_info_; - unsigned int display_info_id_ = 0; - - mojo::Binding<device::mojom::blink::VRDisplayClient> display_client_binding_; }; } // namespace blink
diff --git a/third_party/blink/renderer/modules/xr/xr_device_pose.cc b/third_party/blink/renderer/modules/xr/xr_device_pose.cc index 10e1547..1942968 100644 --- a/third_party/blink/renderer/modules/xr/xr_device_pose.cc +++ b/third_party/blink/renderer/modules/xr/xr_device_pose.cc
@@ -18,7 +18,7 @@ DOMFloat32Array* XRDevicePose::poseModelMatrix() const { if (!pose_model_matrix_) return nullptr; - return transformationMatrixToFloat32Array(*pose_model_matrix_); + return transformationMatrixToDOMFloat32Array(*pose_model_matrix_); } DOMFloat32Array* XRDevicePose::getViewMatrix(XRView* view) { @@ -36,7 +36,7 @@ view_matrix.PostTranslate3d(-view_offset.X(), -view_offset.Y(), -view_offset.Z()); - return transformationMatrixToFloat32Array(view_matrix); + return transformationMatrixToDOMFloat32Array(view_matrix); } void XRDevicePose::Trace(blink::Visitor* visitor) {
diff --git a/third_party/blink/renderer/modules/xr/xr_frame_of_reference.cc b/third_party/blink/renderer/modules/xr/xr_frame_of_reference.cc index d58997d..5c29f5d 100644 --- a/third_party/blink/renderer/modules/xr/xr_frame_of_reference.cc +++ b/third_party/blink/renderer/modules/xr/xr_frame_of_reference.cc
@@ -31,9 +31,9 @@ void XRFrameOfReference::UpdateStageTransform() { const device::mojom::blink::VRDisplayInfoPtr& display_info = - session()->device()->xrDisplayInfoPtr(); + session()->GetVRDisplayInfo(); - if (display_info->stageParameters) { + if (display_info && display_info->stageParameters) { // Use the transform given by xrDisplayInfo's stageParamters if available. const WTF::Vector<float>& m = display_info->stageParameters->standingTransform; @@ -52,7 +52,7 @@ pose_transform_.reset(); } - display_info_id_ = session()->device()->xrDisplayInfoPtrId(); + display_info_id_ = session()->DisplayInfoPtrId(); } // Enables emulated height when using a stage frame of reference, which should @@ -97,7 +97,7 @@ case kTypeStage: // Check first to see if the xrDisplayInfo has updated since the last // call. If so, update the pose transform. - if (display_info_id_ != session()->device()->xrDisplayInfoPtrId()) + if (display_info_id_ != session()->DisplayInfoPtrId()) UpdateStageTransform(); // If the stage has a transform apply it to the base pose and return that,
diff --git a/third_party/blink/renderer/modules/xr/xr_frame_provider.cc b/third_party/blink/renderer/modules/xr/xr_frame_provider.cc index 2e59b0b..b985bd42 100644 --- a/third_party/blink/renderer/modules/xr/xr_frame_provider.cc +++ b/third_party/blink/renderer/modules/xr/xr_frame_provider.cc
@@ -86,7 +86,7 @@ } // namespace XRFrameProvider::XRFrameProvider(XRDevice* device) - : device_(device), last_has_focus_(device->HasDeviceAndFrameFocus()) { + : device_(device), last_has_focus_(device->HasFrameFocus()) { frame_transport_ = new XRFrameTransport(); } @@ -119,7 +119,7 @@ } void XRFrameProvider::OnFocusChanged() { - bool focus = device_->HasDeviceAndFrameFocus(); + bool focus = device_->HasFrameFocus(); // If we are gaining focus, schedule a frame for magic window. This accounts // for skipping RAFs in ProcessScheduledFrame. Only do this when there are @@ -355,7 +355,7 @@ TRACE_EVENT2("gpu", "XRFrameProvider::ProcessScheduledFrame", "frame", frame_id_, "timestamp", high_res_now_ms); - if (!device_->HasDeviceAndFrameFocus() && !immersive_session_) { + if (!device_->HasFrameFocus() && !immersive_session_) { return; // Not currently focused, so we won't expose poses (except to // immersive sessions). } @@ -497,7 +497,7 @@ // TODO(bajones): Remove this when the Windows path has been updated to no // longer require a texture copy. - bool needs_copy = device_->external(); + bool needs_copy = immersive_session_->External(); frame_transport_->FrameSubmit( presentation_provider_.get(), webgl_context->ContextGL(), webgl_context,
diff --git a/third_party/blink/renderer/modules/xr/xr_hit_result.cc b/third_party/blink/renderer/modules/xr/xr_hit_result.cc index 004c50a..07b9349 100644 --- a/third_party/blink/renderer/modules/xr/xr_hit_result.cc +++ b/third_party/blink/renderer/modules/xr/xr_hit_result.cc
@@ -16,10 +16,7 @@ DOMFloat32Array* XRHitResult::hitMatrix() const { if (!hit_transform_) return nullptr; - // TODO(https://crbug.com/845296): rename - // transformationMatrixToFloat32Array() to - // TransformationMatrixToDOMFloat32Array(). - return transformationMatrixToFloat32Array(*hit_transform_); + return transformationMatrixToDOMFloat32Array(*hit_transform_); } } // namespace blink
diff --git a/third_party/blink/renderer/modules/xr/xr_input_pose.cc b/third_party/blink/renderer/modules/xr/xr_input_pose.cc index 8057426..5b7ce85 100644 --- a/third_party/blink/renderer/modules/xr/xr_input_pose.cc +++ b/third_party/blink/renderer/modules/xr/xr_input_pose.cc
@@ -20,7 +20,7 @@ DOMFloat32Array* XRInputPose::gripMatrix() const { if (!grip_matrix_) return nullptr; - return transformationMatrixToFloat32Array(*grip_matrix_); + return transformationMatrixToDOMFloat32Array(*grip_matrix_); } void XRInputPose::Trace(blink::Visitor* visitor) {
diff --git a/third_party/blink/renderer/modules/xr/xr_ray.cc b/third_party/blink/renderer/modules/xr/xr_ray.cc index 22ae3d4..5189e5dd 100644 --- a/third_party/blink/renderer/modules/xr/xr_ray.cc +++ b/third_party/blink/renderer/modules/xr/xr_ray.cc
@@ -24,10 +24,7 @@ DOMFloat32Array* XRRay::transformMatrix() const { if (!transform_matrix_) return nullptr; - // TODO(https://crbug.com/845296): rename - // transformationMatrixToFloat32Array() to - // TransformationMatrixToDOMFloat32Array(). - return transformationMatrixToFloat32Array(*transform_matrix_); + return transformationMatrixToDOMFloat32Array(*transform_matrix_); } void XRRay::Trace(blink::Visitor* visitor) {
diff --git a/third_party/blink/renderer/modules/xr/xr_session.cc b/third_party/blink/renderer/modules/xr/xr_session.cc index 7688a233..1be1aaf 100644 --- a/third_party/blink/renderer/modules/xr/xr_session.cc +++ b/third_party/blink/renderer/modules/xr/xr_session.cc
@@ -89,15 +89,18 @@ Member<XRSession> session_; }; -XRSession::XRSession(XRDevice* device, - bool immersive, - bool environment_integration, - XRPresentationContext* output_context, - EnvironmentBlendMode environment_blend_mode) +XRSession::XRSession( + XRDevice* device, + device::mojom::blink::XRSessionClientRequest client_request, + bool immersive, + bool environment_integration, + XRPresentationContext* output_context, + EnvironmentBlendMode environment_blend_mode) : device_(device), immersive_(immersive), environment_integration_(environment_integration), output_context_(output_context), + client_binding_(this, std::move(client_request)), callback_collection_(new XRFrameRequestCallbackCollection( device->xr()->GetExecutionContext())) { blurred_ = !HasAppropriateFocus(); @@ -198,7 +201,7 @@ if (!options.disableStageEmulation()) { frameOfRef = new XRFrameOfReference(this, XRFrameOfReference::kTypeStage); frameOfRef->UseEmulatedHeight(options.stageEmulationHeight()); - } else if (device_->xrDisplayInfoPtr()->stageParameters) { + } else if (display_info_ && display_info_->stageParameters) { frameOfRef = new XRFrameOfReference(this, XRFrameOfReference::kTypeStage); } else { return ScriptPromise::RejectWithDOMException( @@ -386,7 +389,7 @@ double XRSession::NativeFramebufferScale() const { if (immersive_) { - double scale = device_->xrDisplayInfoPtr()->webxr_default_framebuffer_scale; + double scale = display_info_->webxr_default_framebuffer_scale; DCHECK(scale); // Return the inverse of the default scale, since that's what we'll need to @@ -401,12 +404,12 @@ return OutputCanvasSize(); } - double width = (device_->xrDisplayInfoPtr()->leftEye->renderWidth + - device_->xrDisplayInfoPtr()->rightEye->renderWidth); - double height = std::max(device_->xrDisplayInfoPtr()->leftEye->renderHeight, - device_->xrDisplayInfoPtr()->rightEye->renderHeight); + double width = (display_info_->leftEye->renderWidth + + display_info_->rightEye->renderWidth); + double height = std::max(display_info_->leftEye->renderHeight, + display_info_->rightEye->renderHeight); - double scale = device_->xrDisplayInfoPtr()->webxr_default_framebuffer_scale; + double scale = display_info_->webxr_default_framebuffer_scale; return DoubleSize(width * scale, height * scale); } @@ -438,8 +441,8 @@ // focused. This prevents the in-headset experience from freezing on an // external display headset when the user clicks on another tab. bool XRSession::HasAppropriateFocus() { - return immersive_ ? device_->HasDeviceFocus() - : device_->HasDeviceAndFrameFocus(); + return immersive_ ? has_device_focus_ + : has_device_focus_ && device_->HasFrameFocus(); } void XRSession::OnFocusChanged() { @@ -724,6 +727,24 @@ return XRInputSourceEvent::Create(type, presentation_frame, input_source); } +void XRSession::OnChanged(device::mojom::blink::VRDisplayInfoPtr display_info) { + DCHECK(display_info); + SetXRDisplayInfo(std::move(display_info)); +} + +void XRSession::OnExitPresent() { + if (immersive_) { + ForceEnd(); + } +} + +void XRSession::SetXRDisplayInfo( + device::mojom::blink::VRDisplayInfoPtr display_info) { + display_info_id_++; + display_info_ = std::move(display_info); + is_external_ = display_info_->capabilities->hasExternalDisplay; +} + const HeapVector<Member<XRView>>& XRSession::views() { // TODO(bajones): For now we assume that immersive sessions render a stereo // pair of views and non-immersive sessions render a single view. That doesn't @@ -739,11 +760,11 @@ // In immersive mode the projection and view matrices must be aligned with // the device's physical optics. UpdateViewFromEyeParameters(views_[XRView::kEyeLeft], - device_->xrDisplayInfoPtr()->leftEye, - depth_near_, depth_far_); + display_info_->leftEye, depth_near_, + depth_far_); UpdateViewFromEyeParameters(views_[XRView::kEyeRight], - device_->xrDisplayInfoPtr()->rightEye, - depth_near_, depth_far_); + display_info_->rightEye, depth_near_, + depth_far_); } else { if (views_.IsEmpty()) { views_.push_back(new XRView(this, XRView::kEyeLeft));
diff --git a/third_party/blink/renderer/modules/xr/xr_session.h b/third_party/blink/renderer/modules/xr/xr_session.h index 09df7b1..293b903 100644 --- a/third_party/blink/renderer/modules/xr/xr_session.h +++ b/third_party/blink/renderer/modules/xr/xr_session.h
@@ -37,6 +37,7 @@ class XRView; class XRSession final : public EventTargetWithInlineData, + public device::mojom::blink::XRSessionClient, public ActiveScriptWrappable<XRSession> { DEFINE_WRAPPERTYPEINFO(); USING_GARBAGE_COLLECTED_MIXIN(XRSession); @@ -49,6 +50,7 @@ }; XRSession(XRDevice*, + device::mojom::blink::XRSessionClientRequest client_request, bool immersive, bool environment_integration, XRPresentationContext* output_context, @@ -143,7 +145,16 @@ void OnPoseReset(); + const device::mojom::blink::VRDisplayInfoPtr& GetVRDisplayInfo() { + return display_info_; + } + bool External() const { return is_external_; } + // Incremented every time display_info_ is changed, so that other objects that + // depend on it can know when they need to update. + unsigned int DisplayInfoPtrId() const { return display_info_id_; } + void SetNonImmersiveProjectionMatrix(const WTF::Vector<float>&); + void SetXRDisplayInfo(device::mojom::blink::VRDisplayInfoPtr display_info); void Trace(blink::Visitor*) override; @@ -162,8 +173,12 @@ XRInputSourceEvent* CreateInputSourceEvent(const AtomicString&, XRInputSource*); - void OnFocus(); - void OnBlur(); + // XRSessionClient + void OnChanged(device::mojom::blink::VRDisplayInfoPtr) override; + void OnExitPresent() override; + void OnFocus() override; + void OnBlur() override; + bool HasAppropriateFocus(); void OnHitTestResults( @@ -182,6 +197,13 @@ Member<ResizeObserver> resize_observer_; Member<XRCanvasInputProvider> canvas_input_provider_; + bool has_device_focus_ = true; + bool is_external_ = false; + int display_info_id_ = 0; + device::mojom::blink::VRDisplayInfoPtr display_info_; + + mojo::Binding<device::mojom::blink::XRSessionClient> client_binding_; + TraceWrapperMember<XRFrameRequestCallbackCollection> callback_collection_; std::unique_ptr<TransformationMatrix> base_pose_matrix_;
diff --git a/third_party/blink/renderer/modules/xr/xr_utils.cc b/third_party/blink/renderer/modules/xr/xr_utils.cc index 34ef224..3b549c1 100644 --- a/third_party/blink/renderer/modules/xr/xr_utils.cc +++ b/third_party/blink/renderer/modules/xr/xr_utils.cc
@@ -6,7 +6,7 @@ namespace blink { -DOMFloat32Array* transformationMatrixToFloat32Array( +DOMFloat32Array* transformationMatrixToDOMFloat32Array( const TransformationMatrix& matrix) { float array[] = { static_cast<float>(matrix.M11()), static_cast<float>(matrix.M12()),
diff --git a/third_party/blink/renderer/modules/xr/xr_utils.h b/third_party/blink/renderer/modules/xr/xr_utils.h index d484e5bc..a90d05c 100644 --- a/third_party/blink/renderer/modules/xr/xr_utils.h +++ b/third_party/blink/renderer/modules/xr/xr_utils.h
@@ -10,7 +10,7 @@ namespace blink { -DOMFloat32Array* transformationMatrixToFloat32Array( +DOMFloat32Array* transformationMatrixToDOMFloat32Array( const TransformationMatrix&); } // namespace blink
diff --git a/third_party/blink/renderer/modules/xr/xr_webgl_layer.cc b/third_party/blink/renderer/modules/xr/xr_webgl_layer.cc index 0971d900..cd15c90 100644 --- a/third_party/blink/renderer/modules/xr/xr_webgl_layer.cc +++ b/third_party/blink/renderer/modules/xr/xr_webgl_layer.cc
@@ -126,8 +126,7 @@ framebuffer_scale_(framebuffer_scale) { DCHECK(drawing_buffer_); // If the contents need mirroring, indicate that to the drawing buffer. - if (session->immersive() && session->outputContext() && - session->device()->external()) { + if (session->immersive() && session->outputContext() && session->External()) { mirroring_ = true; drawing_buffer_->SetMirrorClient(this); } @@ -188,7 +187,6 @@ double XRWebGLLayer::getNativeFramebufferScaleFactor(XRSession* session) { return session->NativeFramebufferScale(); - ; } void XRWebGLLayer::UpdateViewports() {
diff --git a/third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.cc b/third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.cc index b2d0209..17899d3 100644 --- a/third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.cc +++ b/third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.cc
@@ -105,6 +105,10 @@ DCHECK_EQ(clip_node.id, kSecondaryRootNodeId); clip_node.clip_type = cc::ClipNode::ClipType::APPLIES_LOCAL_CLIP; + // TODO(bokan): This needs to come from the Visual Viewport which will + // correctly account for the URL bar. In fact, the visual viewport property + // tree builder should probably be the one to create the property tree state + // and have this created in the same way as other layers. clip_node.clip = gfx::RectF( gfx::SizeF(root_layer_->layer_tree_host()->device_viewport_size())); clip_node.transform_id = kRealRootNodeId; @@ -179,6 +183,11 @@ transform_node->FlattensInheritedTransform(); compositor_node.sorting_context_id = transform_node->RenderingContextId(); + if (transform_node->IsAffectedByOuterViewportBoundsDelta()) { + compositor_node.moved_by_outer_viewport_bounds_delta_y = true; + GetTransformTree().AddNodeAffectedByOuterViewportBoundsDelta(id); + } + CompositorElementId compositor_element_id = transform_node->GetCompositorElementId(); if (compositor_element_id) {
diff --git a/third_party/blink/renderer/platform/graphics/paint/transform_paint_property_node.h b/third_party/blink/renderer/platform/graphics/paint/transform_paint_property_node.h index 6de5187..f670c90 100644 --- a/third_party/blink/renderer/platform/graphics/paint/transform_paint_property_node.h +++ b/third_party/blink/renderer/platform/graphics/paint/transform_paint_property_node.h
@@ -49,6 +49,7 @@ CompositingReasons direct_compositing_reasons = CompositingReason::kNone; CompositorElementId compositor_element_id; scoped_refptr<const ScrollPaintPropertyNode> scroll; + bool affected_by_outer_viewport_bounds_delta = false; bool operator==(const State& o) const { return matrix == o.matrix && origin == o.origin && @@ -57,7 +58,9 @@ rendering_context_id == o.rendering_context_id && direct_compositing_reasons == o.direct_compositing_reasons && compositor_element_id == o.compositor_element_id && - scroll == o.scroll; + scroll == o.scroll && + affected_by_outer_viewport_bounds_delta == + o.affected_by_outer_viewport_bounds_delta; } }; @@ -97,6 +100,13 @@ return state_.scroll.get(); } + // If true, this node is translated by the viewport bounds delta, which is + // used to keep bottom-fixed elements appear fixed to the bottom of the + // screen in the presence of URL bar movement. + bool IsAffectedByOuterViewportBoundsDelta() const { + return state_.affected_by_outer_viewport_bounds_delta; + } + // If this is a scroll offset translation (i.e., has an associated scroll // node), returns this. Otherwise, returns the transform node that this node // scrolls with respect to. This can require a full ancestor traversal.
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5 index 1f89e49..aeb798fa 100644 --- a/third_party/blink/renderer/platform/runtime_enabled_features.json5 +++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -1346,6 +1346,9 @@ status: "experimental", }, { + name: "WritableFiles", + }, + { name: "XSLT", status: "stable", },
diff --git a/third_party/blink/tools/audit_non_blink_usage.py b/third_party/blink/tools/audit_non_blink_usage.py index f7d057c..1c0fe38 100755 --- a/third_party/blink/tools/audit_non_blink_usage.py +++ b/third_party/blink/tools/audit_non_blink_usage.py
@@ -32,6 +32,8 @@ # //base constructs that are allowed everywhere 'base::AdoptRef', 'base::AutoReset', + 'base::File', + 'base::FilePath', 'base::GetUniqueIdForProcess', 'base::Location', 'base::MakeRefCounted',
diff --git a/third_party/harfbuzz-ng/README.chromium b/third_party/harfbuzz-ng/README.chromium index 3bee3e5..5f363bb 100644 --- a/third_party/harfbuzz-ng/README.chromium +++ b/third_party/harfbuzz-ng/README.chromium
@@ -1,9 +1,9 @@ Name: harfbuzz-ng Short Name: harfbuzz-ng URL: http://harfbuzz.org -Version: 1.8.7 -Date: 20180809 -Revision: b6fdcf4f8bd09e065c767939125861c9dc8ff18f +Version: 1.8.8 +Date: 20180815 +Revision: 22defe0965adddaa09eebc13df7fa6c64e2abba3 Security Critical: yes License: MIT License File: src/COPYING
diff --git a/third_party/mesa/LICENSE b/third_party/mesa/LICENSE deleted file mode 100644 index 792c6fe..0000000 --- a/third_party/mesa/LICENSE +++ /dev/null
@@ -1,512 +0,0 @@ -The default Mesa license is as follows: - -Copyright (C) 1999-2007 Brian Paul All Rights Reserved. - -Permission is hereby granted, free of charge, to any person obtaining a -copy of this software and associated documentation files (the "Software"), -to deal in the Software without restriction, including without limitation -the rights to use, copy, modify, merge, publish, distribute, sublicense, -and/or sell copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN -AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - - -Some parts of Mesa are copyrighted under the GNU LGPL. See the -Mesa/docs/COPYRIGHT file for details. - -The following is the standard GNU copyright file. ----------------------------------------------------------------------- - - - GNU LIBRARY GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1991 Free Software Foundation, Inc. - 675 Mass Ave, Cambridge, MA 02139, USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -[This is the first released version of the library GPL. It is - numbered 2 because it goes with version 2 of the ordinary GPL.] - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Library General Public License, applies to some -specially designated Free Software Foundation software, and to any -other libraries whose authors decide to use it. You can use it for -your libraries, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if -you distribute copies of the library, or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link a program with the library, you must provide -complete object files to the recipients so that they can relink them -with the library, after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. - - Our method of protecting your rights has two steps: (1) copyright -the library, and (2) offer you this license which gives you legal -permission to copy, distribute and/or modify the library. - - Also, for each distributor's protection, we want to make certain -that everyone understands that there is no warranty for this free -library. If the library is modified by someone else and passed on, we -want its recipients to know that what they have is not the original -version, so that any problems introduced by others will not reflect on -the original authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that companies distributing free -software will individually obtain patent licenses, thus in effect -transforming the program into proprietary software. To prevent this, -we have made it clear that any patent must be licensed for everyone's -free use or not licensed at all. - - Most GNU software, including some libraries, is covered by the ordinary -GNU General Public License, which was designed for utility programs. This -license, the GNU Library General Public License, applies to certain -designated libraries. This license is quite different from the ordinary -one; be sure to read it in full, and don't assume that anything in it is -the same as in the ordinary license. - - The reason we have a separate public license for some libraries is that -they blur the distinction we usually make between modifying or adding to a -program and simply using it. Linking a program with a library, without -changing the library, is in some sense simply using the library, and is -analogous to running a utility program or application program. However, in -a textual and legal sense, the linked executable is a combined work, a -derivative of the original library, and the ordinary General Public License -treats it as such. - - Because of this blurred distinction, using the ordinary General -Public License for libraries did not effectively promote software -sharing, because most developers did not use the libraries. We -concluded that weaker conditions might promote sharing better. - - However, unrestricted linking of non-free programs would deprive the -users of those programs of all benefit from the free status of the -libraries themselves. This Library General Public License is intended to -permit developers of non-free programs to use free libraries, while -preserving your freedom as a user of such programs to change the free -libraries that are incorporated in them. (We have not seen how to achieve -this as regards changes in header files, but we have achieved it as regards -changes in the actual functions of the Library.) The hope is that this -will lead to faster development of free libraries. - - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, while the latter only -works together with the library. - - Note that it is possible for a library to be covered by the ordinary -General Public License rather than by this special one. - - GNU LIBRARY GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library which -contains a notice placed by the copyright holder or other authorized -party saying it may be distributed under the terms of this Library -General Public License (also called "this License"). Each licensee is -addressed as "you". - - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) - - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, complete source code means -all the source code for all modules it contains, plus any associated -interface definition files, plus the scripts used to control compilation -and installation of the library. - - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the -Library. - - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. - - 2. You may modify your copy or copies of the Library or any portion -of it, thus forming a work based on the Library, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote -it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. - - Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. - - If distribution of object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the -source code from the same place satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. - - 6. As an exception to the Sections above, you may also compile or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. - - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Accompany the work with a written offer, valid for at - least three years, to give the same user the materials - specified in Subsection 6a, above, for a charge no more - than the cost of performing this distribution. - - c) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - - d) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the source code distributed need not include anything that is normally -distributed (in either source or binary form) with the major -components (compiler, kernel, and so on) of the operating system on -which the executable runs, unless that component itself accompanies -the executable. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. - - 7. You may place library facilities that are a work based on the -Library side-by-side in a single library together with other library -facilities not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library is void, and will automatically terminate your -rights under this License. However, parties who have received copies, -or rights, from you under this License will not have their licenses -terminated so long as such parties remain in full compliance. - - 9. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under any -particular circumstance, the balance of the section is intended to apply, -and the section as a whole is intended to apply in other circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License may add -an explicit geographical distribution limitation excluding those countries, -so that distribution is permitted only in or among countries not thus -excluded. In such case, this License incorporates the limitation as if -written in the body of this License. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Library General Public License from time to time. -Such new versions will be similar in spirit to the present version, -but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Library -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY -KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU -FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR -CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING -RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. - - END OF TERMS AND CONDITIONS - - Appendix: How to Apply These Terms to Your New Libraries - - If you develop a new library, and you want it to be of the greatest -possible use to the public, we recommend making it free software that -everyone can redistribute and change. You can do so by permitting -redistribution under these terms (or, alternatively, under the terms of the -ordinary General Public License). - - To apply these terms, attach the following notices to the library. It is -safest to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least the -"copyright" line and a pointer to where the full notice is found. - - <one line to give the library's name and a brief idea of what it does.> - Copyright (C) <year> <name of author> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free - Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -Also add information on how to contact you by electronic and paper mail. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the library, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James Random Hacker. - - <signature of Ty Coon>, 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! -
diff --git a/third_party/mesa/OWNERS b/third_party/mesa/OWNERS deleted file mode 100644 index 9f0c3e71..0000000 --- a/third_party/mesa/OWNERS +++ /dev/null
@@ -1,4 +0,0 @@ -kbr@chromium.org -senorblanco@chromium.org -piman@chromium.org -marcheu@chromium.org
diff --git a/third_party/mesa/README.chromium b/third_party/mesa/README.chromium deleted file mode 100644 index 7bd148f..0000000 --- a/third_party/mesa/README.chromium +++ /dev/null
@@ -1,74 +0,0 @@ -Name: mesa -Version: 9.0.3 -URL: http://www.mesa3d.org/ -License: MIT and LGPL v2 -Security Critical: Yes - -Description: -This directory contains a copy of the Mesa sources with minor -modifications to work in Chromium's build infrastructure. - -The license file in this directory is derived from src/docs/license.html -and src/docs/COPYING. - -Modifications made: -- Added the file README.chromium (this file) - -- Disabled optimizations using #pragma optimize('', off) in the - following files: - - src/src/mesa/main/mipmap.c - - src/src/mesa/main/pack.c - - src/src/mesa/math/m_eval.c - - src/src/mesa/swrast/s_texcombine.c - -- Checked in sources normally autogenerated during Mesa's build - process under src/chromium_gensrc. - These files are generated with flex 2.6.1 and bison 3.0.4. - -- Checked in public headers normally autogenerated during Mesa's build - process under include. - -- Modified _mesa_add_parameter to not read from uninitialized - memory - -- Added typedefs for EGLNative*Type in eglplatform.h, guarded by an - __APPLE__ define - -- Modified glsl_strtod in src/glsl/strtod.c to use strtod instead of - strtod_l on Android - -- Added an #include for <assert.h> at the top of - src/gallium/auxiliary/util/u_debug.h - -- Fix a bug with Multiple Render Targets, see - https://code.google.com/p/chromium/issues/detail?id=308715 - -- #ifdef out inline definitions of math functions that are present in - VS2013's standard library. - -- #pragma optimize off around _swrast_write_zoomed_z_span, ICEing on - VS2013: http://crbug.com/348350. - -- Disabled "#pragma export" usage in gl.h and osmesa.h, - https://bugs.freedesktop.org/show_bug.cgi?id=77749 - -- Porting to x64 Android. Remove redefinitions of log2 and log2f. - https://codereview.chromium.org/216773005/ - -- Excluded src/mapi/mapi/mapi.{h,c} from the build. - -- Backported f8e7aa2827e2bdb1ed238cbdd351be3c8a6e9b12 and - e20a2df4017ab10dd7199936948c6ac809bfacb6 to fix issues with - glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES) when no - framebuffer is bound - -- Merge http://cgit.freedesktop.org/mesa/mesa/commit/?id=27307a7 - -- Merge http://cgit.freedesktop.org/mesa/mesa/commit/?id=d2458a4 - -- Statically link libstdc++ in chromecast build - -- Merge http://cgit.freedesktop.org/mesa/mesa/commit/?id=5a6ec26 - -- update GLDEBUGPROCARB and GLDEBUGPROC typedef to latest spec version to avoid - type mismatch between headers (making userParam a const GLvoid*).
diff --git a/third_party/mesa/README.txt b/third_party/mesa/README.txt deleted file mode 100644 index c55181e..0000000 --- a/third_party/mesa/README.txt +++ /dev/null
@@ -1,19 +0,0 @@ -Compilation has a few phases: - -1. Generate the header and dispatch source files that have to match the GL api. - These read in a description of the GL api in the form of XML files. In - addition, generate the GLSL parser and lexer using flex and bison. These - sources are needed for step 2. Generated mesa sources can be generated by - including 'mesa_gensrc.gypi' in mesa.gyp, running 'gclient runhooks' and - running the gyp target 'generate_mesa_sources'. The mesa.gyp file should - not be checked in to include mesa_gensrc.gypi so we do not generate these - files during a regular build. The generated files should be checked in. -2. Compile everything in src/glsl into a library. This step uses the parser and - lexer output. -3. Compile the compiler (executable) that can create the builtin functions' - source file. Note that this step uses builtin_stubs.cpp because we haven't - generated the actual builtin functions' source file yet. -4. Invoke the compiler that we just built to create - gen/mesa/builtin_function.cpp -5. Compile the rest of mesa, using the builtins that we created in step 4. In - addition, link in all the files that we've previously compiled in step 2.
diff --git a/tools/cfi/blacklist.txt b/tools/cfi/blacklist.txt index 41e5b4d..761574a5 100644 --- a/tools/cfi/blacklist.txt +++ b/tools/cfi/blacklist.txt
@@ -9,9 +9,6 @@ # WTF::ThreadSpecific fun:*ThreadSpecific* -# Mesa contains several bad casts. -src:*third_party/mesa* - # LLVM's allocator src:*llvm/Support/Allocator.h
diff --git a/tools/checklicenses/checklicenses.py b/tools/checklicenses/checklicenses.py index 3003d55..3c1c1f1 100755 --- a/tools/checklicenses/checklicenses.py +++ b/tools/checklicenses/checklicenses.py
@@ -452,12 +452,6 @@ 'third_party/lzma_sdk': [ 'UNKNOWN', ], - 'third_party/mesa/src': [ - 'GPL (v2)', - 'GPL (v3 or later)', - 'MIT/X11 (BSD like) GPL (v3 or later) with Bison parser exception', - 'UNKNOWN', # http://crbug.com/98450 - ], 'third_party/modp_b64': [ 'UNKNOWN', ],
diff --git a/tools/checkperms/checkperms.py b/tools/checkperms/checkperms.py index 23c58cd1..52f5291a 100755 --- a/tools/checkperms/checkperms.py +++ b/tools/checkperms/checkperms.py
@@ -186,7 +186,6 @@ 'third_party/lcov/contrib/galaxy/gen_makefile.sh', 'third_party/libxml/linux/xml2-config', 'third_party/libxml/src/ltmain.sh', - 'third_party/mesa/', 'third_party/protobuf/', 'third_party/sqlite/', 'third_party/talloc/script/mksyms.sh',
diff --git a/tools/determinism/compare_build_artifacts.py b/tools/determinism/compare_build_artifacts.py index d17b037..9141da1f 100755 --- a/tools/determinism/compare_build_artifacts.py +++ b/tools/determinism/compare_build_artifacts.py
@@ -7,6 +7,7 @@ import ast import difflib +import glob import json import optparse import os @@ -47,6 +48,43 @@ return ret_files +def get_files_to_compare_using_isolate(build_dir): + # First, find all .isolate files in build_dir. + isolates = glob.glob(os.path.join(build_dir, '*.isolate')) + + # Then, extract their contents. + ret_files = set() + + for isolate in isolates: + with open(isolate) as f: + isolate_contents = ast.literal_eval(f.read()) + isolate_files = isolate_contents['variables']['files'] + for isolate_file in isolate_files: + normalized_path = os.path.normpath( + os.path.join(build_dir, isolate_file)) + + # Ignore isolate files that are not in the build dir ... for now. + # If we ever move to comparing determinism of artifacts built from two + # repositories, we'll want to get rid of this check. + if os.path.commonprefix((normalized_path, build_dir)) != build_dir: + continue + + # Theoretically, directories should end in '/' and files should not, but + # this doesn't hold true because some GN build files are incorrectly + # configured. We explicitly check whether the path is a directory or + # file. + if not os.path.isdir(normalized_path): + ret_files.add(normalized_path) + continue + + for root, dirs, files in os.walk(normalized_path): + for inner_file in files: + ret_files.add(os.path.join(root, inner_file)) + + # Convert back to a relpath since that's what the caller is expecting. + return set(os.path.relpath(f, build_dir) for f in ret_files) + + def diff_dict(a, b): """Returns a yaml-like textural diff of two dict. @@ -203,7 +241,7 @@ def compare_build_artifacts(first_dir, second_dir, ninja_path, target_platform, - json_output, recursive=False): + json_output, recursive, use_isolate_files): """Compares the artifacts from two distinct builds.""" if not os.path.isdir(first_dir): print >> sys.stderr, '%s isn\'t a valid directory.' % first_dir @@ -219,9 +257,13 @@ with open(os.path.join(BASE_DIR, 'deterministic_build_whitelist.pyl')) as f: whitelist = frozenset(ast.literal_eval(f.read())[target_platform]) - # The two directories. - first_list = get_files_to_compare(first_dir, recursive) - second_list = get_files_to_compare(second_dir, recursive) + if use_isolate_files: + first_list = get_files_to_compare_using_isolate(first_dir) + second_list = get_files_to_compare_using_isolate(second_dir) + else: + first_list = get_files_to_compare(first_dir, recursive) + second_list = get_files_to_compare(second_dir, recursive) + equals = [] expected_diffs = [] @@ -234,7 +276,9 @@ print >> sys.stderr, '\n'.join(' ' + i for i in missing_files) unexpected_diffs.extend(missing_files) - max_filepath_len = max(len(n) for n in all_files) + max_filepath_len = 0 + if all_files: + max_filepath_len = max(len(n) for n in all_files) for f in all_files: first_file = os.path.join(first_dir, f) second_file = os.path.join(second_dir, f) @@ -295,6 +339,11 @@ '-s', '--second-build-dir', help='The second build directory.') parser.add_option('-r', '--recursive', action='store_true', default=False, help='Indicates if the comparison should be recursive.') + parser.add_option( + '--use-isolate-files', action='store_true', default=False, + help='Use .isolate files in each directory to determine which artifacts ' + 'to compare.') + parser.add_option('--json-output', help='JSON file to output differences') parser.add_option('--ninja-path', help='path to ninja command.', default='ninja') @@ -317,7 +366,8 @@ options.ninja_path, options.target_platform, options.json_output, - options.recursive) + options.recursive, + options.use_isolate_files) if __name__ == '__main__':
diff --git a/tools/fuchsia/comparative_tester/display_perf_results.html b/tools/fuchsia/comparative_tester/display_perf_results.html new file mode 100644 index 0000000..3976845c --- /dev/null +++ b/tools/fuchsia/comparative_tester/display_perf_results.html
@@ -0,0 +1,8 @@ +<html> + <body> + <div id="stats_div"></div> + <input type="file" id="files" oninput="loadTable()" multiple> + <script type="text/javascript" src="display_perf_results.js"></script> + <script src="https://d3js.org/d3.v5.min.js"></script> + </body> +</html> \ No newline at end of file
diff --git a/tools/fuchsia/comparative_tester/display_perf_results.js b/tools/fuchsia/comparative_tester/display_perf_results.js new file mode 100644 index 0000000..bec01669 --- /dev/null +++ b/tools/fuchsia/comparative_tester/display_perf_results.js
@@ -0,0 +1,84 @@ +// Copyright 2018 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. + +const headers = ["Test", "Line", "Units", "Fuchsia Avg", "Fuchsia Dev", + "Fuchsia CV", "Linux Avg", "Linux Dev", "Linux CV", + "F-L Avgs"]; + +function generateHeader() { + let header_row = document.createElement("tr"); + for (let i = 0; i < headers.length; i++){ + let header = document.createElement("th"); + header.appendChild(document.createTextNode(headers[i])); + header_row.appendChild(header); + } + return header_row; +} + +function generateTableHtmlFromOutputRows(output_rows) { + let table = document.createElement("table"); + table.appendChild(generateHeader()); + output_rows.forEach(function(row){ + let doc_row = document.createElement("tr"); + row.forEach(function(datum){ + let item = document.createElement("td"); + item.appendChild(document.createTextNode(datum)); + doc_row.appendChild(item); + }); + table.appendChild(doc_row); + }); + return table; +} + +function extractStats(line) { + return [line.fuchsia_avg, + line.fuchsia_dev, + line.fuchsia_cv, + line.linux_avg, + line.linux_dev, + line.linux_cv, + line.fuchsia_avg - line.linux_avg]; +} + +function renderTable(obj_dict) { + let rows = [] + + const name = obj_dict['name'] + const tests = obj_dict['tests']; + Object.keys(tests).forEach(function(test_name) { + const test = tests[test_name]; + const test_stats = extractStats(test) + let test_row = [test_name, "Test Totals", test['unit']].concat(test_stats); + rows.push(test_row) + const lines = test['lines'] + Object.keys(lines).forEach(function(line_key) { + const line = lines[line_key]; + const line_stats = extractStats(line); + let line_row = [test_name, line_key, line['unit']].concat(line_stats); + rows.push(line_row); + }); + rows.push([]); + }); + return generateTableHtmlFromOutputRows(rows); +} + +function loadTable() { + let files = document.getElementById('files').files; + let table_div = document.getElementById('stats_div'); + // Clear the table div of all prior stats tables + while (table_div.firstChild) + table_div.removeChild(table_div.firstChild); + + for (let i = 0; i < files.length; i++){ + let file = files[0]; + let reader = new FileReader(); + + reader.addEventListener('loadend', function(contents) { + let json_parsed = JSON.parse(reader.result) + let table = renderTable(json_parsed); + table_div.appendChild(table); + }); + reader.readAsBinaryString(file); + } +}
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl index 5c530fd..7ff7545 100644 --- a/tools/mb/mb_config.pyl +++ b/tools/mb/mb_config.pyl
@@ -99,7 +99,6 @@ 'chromium.clang': { 'CFI Linux CF': 'cfi_full_cfi_icall_cfi_diag_recover_release_static', 'CFI Linux ToT': 'clang_tot_cfi_full_cfi_icall_cfi_diag_thin_lto_release_static_dcheck_always_on', - 'CFI Linux (icall)': 'cfi_full_diag_icall_release_static_dcheck_always_on', 'CrWinAsan': 'asan_clang_fuzzer_static_v8_heap_minimal_symbols_release_tot', 'CrWinAsan(dll)': 'asan_clang_shared_v8_heap_minimal_symbols_release_tot', 'CrWinAsanCov': 'asan_clang_edge_fuzzer_static_v8_heap_minimal_symbols_release_tot', @@ -146,7 +145,6 @@ 'CFI Linux CF': 'cfi_full_cfi_icall_cfi_diag_recover_release_static', 'CFI Linux ToT': 'clang_tot_cfi_full_cfi_icall_cfi_diag_thin_lto_release_static_dcheck_always_on', - 'CFI Linux (icall)': 'cfi_full_diag_icall_release_static_dcheck_always_on', 'chromeos-amd64-generic-rel-goma-canary': 'cros_chrome_sdk', 'chromeos-amd64-generic-rel-vm-tests': 'cros_chrome_sdk_headless_ozone_dcheck_always_on', @@ -917,7 +915,7 @@ ], 'asan_clang_fuzzer_static_v8_heap_minimal_symbols_release': [ - 'asan', 'fuzzer', 'static', 'v8_heap', 'minimal_symbols', 'release', + 'asan', 'fuzzer', 'static', 'v8_heap', 'minimal_symbols', 'release_bot', ], 'asan_clang_fuzzer_static_v8_heap_minimal_symbols_release_tot': [ @@ -1018,10 +1016,6 @@ 'cfi_full', 'cfi_icall', 'cfi_diag', 'thin_lto', 'release', 'static', 'dcheck_always_on', 'goma', ], - 'cfi_full_diag_icall_release_static_dcheck_always_on': [ - 'cfi_full', 'cfi_diag', 'cfi_icall', 'clang_tot', 'thin_lto', 'release', 'static', 'dcheck_always_on', - ], - 'chromeos_asan_lsan_edge_fuzzer_v8_heap_release_bot': [ 'chromeos', 'asan', 'lsan', 'edge', 'fuzzer', 'v8_heap', 'release_bot', ],
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index fa5952e8..a9354a3 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -8748,6 +8748,22 @@ <int value="19" label="Failed to clean up ephemeral cryptohome"/> </enum> +<enum name="CryptohomeLECredError"> + <summary> + The result when a Low Entropy CheckCredential operation was performed. + </summary> + <int value="0" label="Success"/> + <int value="1" label="Invalid LE secret"/> + <int value="2" label="Invalid Reset Secret"/> + <int value="3" label="Too many attempts"/> + <int value="4" label="Hash tree error"/> + <int value="5" label="Invalid LE label"/> + <int value="6" label="No free LE label"/> + <int value="7" label="Invalid Metadata"/> + <int value="8" label="Unclassified Error"/> + <int value="9" label="LE Locked"/> +</enum> + <enum name="CryptohomeMigrationToGaiaId"> <int value="0" label="Not started"/> <int value="1" label="Already migrated"/> @@ -23352,15 +23368,6 @@ <int value="3" label="active, was active"/> </enum> -<enum name="GpuTerminationOrigin"> - <summary> - Return status re-encoded values from GpuTerminationOrigin as defined in - content/browser/gpu/gpu_process_host.h enum GpuTerminationOrigin. - </summary> - <int value="0" label="Unknown Origin">UNKNOWN_ORIGIN</int> - <int value="1" label="Ozone Wayland Proxy">OZONE_WAYLAND_PROXY</int> -</enum> - <enum name="GpuTerminationStatus"> <summary> Return status re-encoded values from GetTerminationStatus as defined in @@ -27774,6 +27781,7 @@ <int value="-1895719323" label="VrBrowsingTabsView:enabled"/> <int value="-1892555086" label="disable-compositor-animation-timelines"/> <int value="-1892000374" label="SeccompSandboxAndroid:enabled"/> + <int value="-1890374564" label="OobeRecommendAppsScreen:disabled"/> <int value="-1888273969" label="tab-capture-upscale-quality"/> <int value="-1887862464" label="SpannableInlineAutocomplete:disabled"/> <int value="-1887053262" @@ -28997,6 +29005,7 @@ <int value="598827460" label="enable-roboto-font-ui"/> <int value="598926697" label="VrLaunchIntent:disabled"/> <int value="600037637" label="AndroidSigninPromos:enabled"/> + <int value="600643275" label="OobeRecommendAppsScreen:enabled"/> <int value="602117675" label="NTPBookmarkSuggestions:enabled"/> <int value="603326800" label="UsePasswordSeparatedSigninFlow:enabled"/> <int value="603988014" label="NetworkService:enabled"/> @@ -29031,6 +29040,7 @@ <int value="646252875" label="ReadItLaterInMenu:enabled"/> <int value="646738320" label="disable-gesture-editing"/> <int value="649111851" label="MidiManagerCros:enabled"/> + <int value="649508040" label="AutofillEnableCompanyName:enabled"/> <int value="651421878" label="VideoRotateToFullscreen:enabled"/> <int value="651844675" label="EasyUnlockPromotions:enabled"/> <int value="652561231" label="CustomContextMenu:enabled"/> @@ -29364,6 +29374,7 @@ <int value="1298981651" label="disable-new-task-manager"/> <int value="1300282719" label="OfflinePagesBackgroundLoading:enabled"/> <int value="1302421166" label="NativeNotifications:disabled"/> + <int value="1307003774" label="AutofillEnableCompanyName:disabled"/> <int value="1308537004" label="force-pnacl-subzero"/> <int value="1311860720" label="ChromeHomeNtpRedesign:disabled"/> <int value="1312025202" label="NTPOfflinePageSuggestions:disabled"/>
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index ab48fdd..581fddd 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -15380,6 +15380,20 @@ </summary> </histogram> +<histogram base="true" name="Cryptohome.LECredential" + enum="CryptohomeLECredError" expires_after="2019-04-23"> +<!-- Name completed by histogram_suffixes name="LECredentialOps" --> + + <owner>pmalani@chromium.org</owner> + <owner>apronin@chromium.org</owner> + <owner>mnissler@chromium.org</owner> + <owner>allenwebb@chromium.org</owner> + <summary> + Events related to Low Entropy (LE) credential management. These are logged + every time an operation involving a LE credential is performed. + </summary> +</histogram> + <histogram name="Cryptohome.MigrationToGaiaId" enum="CryptohomeMigrationToGaiaId"> <owner>alemate@chromium.org</owner> @@ -33348,19 +33362,6 @@ </summary> </histogram> -<histogram name="GPU.GPUProcessTerminationOrigin" enum="GpuTerminationOrigin" - expires_after="2019-08-14"> - <owner>rjkroege@chromium.org</owner> - <owner>msisov@igalia.com</owner> - <summary> - The reason a GPU process is terminated. It works only when - TERMINATION_STATUS_PROCESS_WAS_KILLED TerminationStatus is set. The goal of - this histogram is to get spikes of the above mentioned case when - Ozone/Wayland terminates the GPU process due to invalid data it received if - any. - </summary> -</histogram> - <histogram name="GPU.GPUProcessTerminationStatus" enum="TerminationStatus"> <obsolete> Deprecated April 2018. Replaced by GPU.GPUProcessTerminationStatus2. @@ -76253,6 +76254,25 @@ </summary> </histogram> +<histogram base="true" name="Power.Consumption" units="mW"> + <owner>sdy@chromium.org</owner> + <summary> + Instantaneous power consution in milliwatts, for the system as a whole and + broken down by component. Only recorded on macOS. + </summary> +</histogram> + +<histogram name="Power.Consumption.AppleSMCOpened" enum="BooleanSuccess"> + <owner>sdy@chromium.org</owner> + <summary> + When metrics collection started, records true if a handle to the System + Management Controller (SMC) was successfully opened to monitor power + consumption, false otherwise. If false, a system API might have changed in a + new version of macOS, or Chrome might be running in a nonstandard + environment (VM, hackintosh). Only recorded on macOS. + </summary> +</histogram> + <histogram name="Power.DarkResumeWakeDurationMs" units="ms"> <owner>chirantan@chromium.org</owner> <summary> @@ -93310,8 +93330,9 @@ </histogram> <histogram name="Settings.GivenShowHomeButton_HomePageIsNewTabPage" - enum="Boolean"> + enum="Boolean" expires_after="2019-08-30"> <owner>mpearson@chromium.org</owner> + <owner>twellington@chromium.org</owner> <summary> Whether or not the home page user preference is set to the default NTP value when a profile is loaded. This is only logged if the home button is shown. @@ -93365,6 +93386,9 @@ <histogram name="Settings.HomePageIsNewTabPage.PulledFromSync" enum="Boolean" expires_after="2018-08-30"> + <obsolete> + Removed in Aug 2018. + </obsolete> <owner>Please list the metric's owners. Add more owner tags as needed.</owner> <summary> The value of the home-page-is-new-tab-page pref when pulled down from sync @@ -93374,6 +93398,9 @@ <histogram name="Settings.HomePageIsNewTabPage.PushedToSync" enum="Boolean" expires_after="2018-08-30"> + <obsolete> + Removed in Aug 2018. + </obsolete> <owner>Please list the metric's owners. Add more owner tags as needed.</owner> <summary> The value of the home-page-is-new-tab-page pref when pushed up to sync from @@ -93565,8 +93592,10 @@ </summary> </histogram> -<histogram name="Settings.ShowHomeButton" enum="BooleanEnabled"> +<histogram name="Settings.ShowHomeButton" enum="BooleanEnabled" + expires_after="2019-08-30"> <owner>mpearson@chromium.org</owner> + <owner>twellington@chromium.org</owner> <summary> Whether or not the home button is enabled in user preferences when a profile is loaded. @@ -93575,6 +93604,9 @@ <histogram name="Settings.ShowHomeButton.PulledFromSync" enum="BooleanEnabled" expires_after="2018-08-30"> + <obsolete> + Removed in Aug 2018. + </obsolete> <owner>mpearson@chromium.org</owner> <summary> The enabled state of the Home button pref when pulled down from sync to @@ -93584,6 +93616,9 @@ <histogram name="Settings.ShowHomeButton.PushedToSync" enum="BooleanEnabled" expires_after="2018-08-30"> + <obsolete> + Removed in Aug 2018. + </obsolete> <owner>mpearson@chromium.org</owner> <summary> The enabled state of the Home button pref when pushed up to sync from a @@ -93641,13 +93676,18 @@ </summary> </histogram> -<histogram name="Settings.StartupPageLoadSettings" enum="SessionStartupPref"> +<histogram name="Settings.StartupPageLoadSettings" enum="SessionStartupPref" + expires_after="2019-08-30"> + <owner>ramyan@chromium.org</owner> <owner>mpearson@chromium.org</owner> <summary>The startup page settings when a profile is loaded.</summary> </histogram> <histogram name="Settings.StartupPageLoadSettings.PulledFromSync" enum="SessionStartupPref" expires_after="2018-08-30"> + <obsolete> + Removed in Aug 2018. + </obsolete> <owner>mpearson@chromium.org</owner> <summary> The startup page setting when pulled down from sync to update an out-of-sync @@ -93657,6 +93697,9 @@ <histogram name="Settings.StartupPageLoadSettings.PushedToSync" enum="SessionStartupPref" expires_after="2018-08-30"> + <obsolete> + Removed in Aug 2018. + </obsolete> <owner>mpearson@chromium.org</owner> <summary> The startup page setting when pushed up to sync from a change made locally. @@ -105148,6 +105191,19 @@ </histogram> <histogram name="ThirdPartyModules.ShellExtensionsCount" units="counts"> + <obsolete> + Deprecated as of 14 Aug 2018 as reporting to this metric was incorrect since + its inception. Replaced by ThirdPartyModules.ShellExtensionsCount2. + </obsolete> + <owner>pmonette@chromium.org</owner> + <summary> + The number of registered shell extensions found on the user's machine. This + is emitted shortly after startup when the shell extensions enumeration takes + place. + </summary> +</histogram> + +<histogram name="ThirdPartyModules.ShellExtensionsCount2" units="counts"> <owner>pmonette@chromium.org</owner> <summary> The number of registered shell extensions found on the user's machine. This @@ -121030,6 +121086,25 @@ <affected-histogram name="Renderer4.StartToFinish"/> </histogram_suffixes> +<histogram_suffixes name="LECredentialOps" separator="."> + <suffix name="Check"/> + <suffix name="Insert"/> + <suffix name="Remove"/> + <suffix name="Reset"/> + <suffix name="ResetTree"/> + <suffix name="Sync"/> + <affected-histogram name="Cryptohome.LECredential"/> +</histogram_suffixes> + +<histogram_suffixes name="LECredentialOpsActions" separator="."> + <suffix name="Backend"/> + <suffix name="BackendGetLog"/> + <suffix name="BackendReplayLog"/> + <suffix name="LoadFromDisk"/> + <suffix name="SaveToDisk"/> + <affected-histogram name="Cryptohome.LECredential.Insert"/> +</histogram_suffixes> + <histogram_suffixes name="LevelDBBFEMethods" separator="."> <owner>cmumford@chromium.org</owner> <suffix name="CreateDir" label="ChromiumEnv::CreateDir"/> @@ -125647,6 +125722,33 @@ <affected-histogram name="NewTabPage.Snippets.CardShownScoreNew"/> </histogram_suffixes> +<histogram_suffixes name="PowerConsumptionSources" separator="."> + <suffix name="CPU" label="Instantaneous power used by the CPU."/> + <suffix name="GPU0" + label="Instantaneous power used by the first dedicated GPU, if any."/> + <suffix name="GPU1" + label="Instantaneous power used by the second dedicated GPU, if any."/> + <suffix name="GPUi" + label="Instantaneous power used by the integrated GPU, if any."/> + <suffix name="Total" + label="Instantaneous power used by the whole system. May be less useful + than other power metrics because it includes peripherals like + the display backlight."/> + <affected-histogram name="Power.Consumption"/> +</histogram_suffixes> + +<histogram_suffixes name="PowerConsumptionTimes" separator="."> + <suffix name="All" label="Sampled once per minute."/> + <suffix name="DuringStartup" + label="Sampled once per second during the first 30 seconds after + launch."/> + <affected-histogram name="Power.Consumption.CPU"/> + <affected-histogram name="Power.Consumption.GPU0"/> + <affected-histogram name="Power.Consumption.GPU1"/> + <affected-histogram name="Power.Consumption.GPUi"/> + <affected-histogram name="Power.Consumption.Total"/> +</histogram_suffixes> + <histogram_suffixes name="PpapiPluginName" separator="_"> <suffix name="libpepflashplayer.so" label="Flash player on Linux or Cros"/> <suffix name="libwidevinecdmadapter.so" label="Widevine CDM on Linux or Cros">
diff --git a/tools/perf/benchmarks/v8.py b/tools/perf/benchmarks/v8.py index dac9cd4..70c166c1 100644 --- a/tools/perf/benchmarks/v8.py +++ b/tools/perf/benchmarks/v8.py
@@ -6,12 +6,26 @@ import page_sets +from telemetry import story from telemetry import benchmark from telemetry.timeline import chrome_trace_category_filter from telemetry.web_perf import timeline_based_measurement -class _Top25RuntimeStats(perf_benchmark.PerfBenchmark): +@benchmark.Info(emails=['cbruni@chromium.org']) +class V8Top25RuntimeStats(perf_benchmark.PerfBenchmark): + """Runtime Stats benchmark for a 25 top V8 web pages. + + Designed to represent a mix between top websites and a set of pages that + have unique V8 characteristics. + """ + + SUPPORTED_PLATFORMS = [story.expectations.ALL_DESKTOP] + + @classmethod + def Name(cls): + return 'v8.runtime_stats.top_25' + def SetExtraBrowserOptions(self, options): options.AppendExtraBrowserArgs( '--enable-blink-features=BlinkRuntimeCallStats') @@ -49,18 +63,5 @@ tbm_options.SetTimelineBasedMetrics(['runtimeStatsMetric']) return tbm_options - -@benchmark.Info(emails=['cbruni@chromium.org']) -class V8Top25RuntimeStats(_Top25RuntimeStats): - """Runtime Stats benchmark for a 25 top V8 web pages. - - Designed to represent a mix between top websites and a set of pages that - have unique V8 characteristics. - """ - - @classmethod - def Name(cls): - return 'v8.runtime_stats.top_25' - def CreateStorySet(self, options): return page_sets.V8Top25StorySet()
diff --git a/tools/perf/core/results_dashboard.py b/tools/perf/core/results_dashboard.py index c5ad82c..5ddf799 100755 --- a/tools/perf/core/results_dashboard.py +++ b/tools/perf/core/results_dashboard.py
@@ -63,15 +63,18 @@ (p.stdout.read(), p.stderr.read())) -def SendResults(data, url, send_as_histograms=False, service_account_file=None, +def SendResults(data, data_label, url, send_as_histograms=False, + service_account_file=None, token_generator_callback=LuciAuthTokenGeneratorCallback, - num_retries=3): + num_retries=4): """Sends results to the Chrome Performance Dashboard. This function tries to send the given data to the dashboard. Args: data: The data to try to send. Must be JSON-serializable. + data_label: string name of the data to be uploaded. This is only used for + logging purpose. url: Performance Dashboard URL (including schema). send_as_histograms: True if result is to be sent to /add_histograms. service_account_file: string; path to service account file which is used @@ -99,10 +102,15 @@ dashboard_data_str = json.dumps(data) + # When perf dashboard is overloaded, it takes sometimes to spin up new + # instance. So sleep before retrying again. ( + # For more details, see crbug.com/867379. + wait_before_next_retry_in_seconds = 30 + for i in xrange(1, num_retries + 1): try: - print 'Sending %s result to dashboard (attempt %i out of %i).' % ( - data_type, i, num_retries) + print 'Sending %s result of %s to dashboard (attempt %i out of %i).' % ( + data_type, data_label, i, num_retries) if send_as_histograms: _SendHistogramJson(url, dashboard_data_str, service_account_file, token_generator_callback) @@ -114,6 +122,8 @@ except SendResultsRetryException as e: error = 'Error while uploading %s data: %s' % (data_type, str(e)) errors.append(error) + time.sleep(wait_before_next_retry_in_seconds) + wait_before_next_retry_in_seconds *= 2 except SendResultsFatalException as e: error = 'Fatal error while uploading %s data: %s' % (data_type, str(e)) errors.append(error)
diff --git a/tools/perf/core/results_dashboard_unittest.py b/tools/perf/core/results_dashboard_unittest.py index c3299e8..71df385 100644 --- a/tools/perf/core/results_dashboard_unittest.py +++ b/tools/perf/core/results_dashboard_unittest.py
@@ -4,6 +4,7 @@ import unittest import mock +from mock import call from core import results_dashboard @@ -23,14 +24,19 @@ del token_generator_callback # unused raise results_dashboard.SendResultsRetryException('Should retry') - with mock.patch('core.results_dashboard._SendHistogramJson', - side_effect=raise_retry_exception) as m: - upload_result = results_dashboard.SendResults( - self.perf_data, self.dashboard_url, send_as_histograms=True, - service_account_file=self.fake_service, - token_generator_callback=self.dummy_token_generator, num_retries=5) - self.assertFalse(upload_result) - self.assertEqual(m.call_count, 5) + with mock.patch('core.results_dashboard.time.sleep') as sleep_mock: + with mock.patch('core.results_dashboard._SendHistogramJson', + side_effect=raise_retry_exception) as m: + upload_result = results_dashboard.SendResults( + self.perf_data, 'dummy_benchmark', + self.dashboard_url, send_as_histograms=True, + service_account_file=self.fake_service, + token_generator_callback=self.dummy_token_generator, num_retries=5) + self.assertFalse(upload_result) + self.assertEqual(m.call_count, 5) + self.assertEqual( + sleep_mock.mock_calls, + [call(30), call(60), call(120), call(240), call(480)]) def testNoRetryForSendResultFatalException(self): @@ -40,25 +46,31 @@ del token_generator_callback # unused raise results_dashboard.SendResultsFatalException('Do not retry') - with mock.patch('core.results_dashboard._SendHistogramJson', - side_effect=raise_retry_exception) as m: - upload_result = results_dashboard.SendResults( - self.perf_data, self.dashboard_url, send_as_histograms=True, - service_account_file=self.fake_service, - token_generator_callback=self.dummy_token_generator, - num_retries=5) - self.assertFalse(upload_result) - self.assertEqual(m.call_count, 1) + with mock.patch('core.results_dashboard.time.sleep') as sleep_mock: + with mock.patch('core.results_dashboard._SendHistogramJson', + side_effect=raise_retry_exception) as m: + upload_result = results_dashboard.SendResults( + self.perf_data, 'dummy_benchmark', + self.dashboard_url, send_as_histograms=True, + service_account_file=self.fake_service, + token_generator_callback=self.dummy_token_generator, + num_retries=5) + self.assertFalse(upload_result) + self.assertEqual(m.call_count, 1) + self.assertFalse(sleep_mock.mock_calls) def testNoRetryForSuccessfulSendResult(self): - with mock.patch('core.results_dashboard._SendHistogramJson') as m: - upload_result = results_dashboard.SendResults( - self.perf_data, self.dashboard_url, send_as_histograms=True, - service_account_file=self.fake_service, - token_generator_callback=self.dummy_token_generator, - num_retries=5) - self.assertTrue(upload_result) - self.assertEqual(m.call_count, 1) + with mock.patch('core.results_dashboard.time.sleep') as sleep_mock: + with mock.patch('core.results_dashboard._SendHistogramJson') as m: + upload_result = results_dashboard.SendResults( + self.perf_data, 'dummy_benchmark', + self.dashboard_url, send_as_histograms=True, + service_account_file=self.fake_service, + token_generator_callback=self.dummy_token_generator, + num_retries=5) + self.assertTrue(upload_result) + self.assertEqual(m.call_count, 1) + self.assertFalse(sleep_mock.mock_calls) def testNoRetryAfterSucessfulSendResult(self): counter = [0] @@ -70,12 +82,16 @@ if counter[0] <= 2: raise results_dashboard.SendResultsRetryException('Please retry') - with mock.patch('core.results_dashboard._SendHistogramJson', - side_effect=raise_retry_exception_first_two_times) as m: - upload_result = results_dashboard.SendResults( - self.perf_data, self.dashboard_url, send_as_histograms=True, - service_account_file=self.fake_service, - token_generator_callback=self.dummy_token_generator, - num_retries=5) - self.assertTrue(upload_result) - self.assertEqual(m.call_count, 3) + with mock.patch('core.results_dashboard.time.sleep') as sleep_mock: + with mock.patch('core.results_dashboard._SendHistogramJson', + side_effect=raise_retry_exception_first_two_times) as m: + upload_result = results_dashboard.SendResults( + self.perf_data, 'dummy_benchmark', + self.dashboard_url, send_as_histograms=True, + service_account_file=self.fake_service, + token_generator_callback=self.dummy_token_generator, + num_retries=5) + self.assertTrue(upload_result) + self.assertEqual(m.call_count, 3) + self.assertEqual( + sleep_mock.mock_calls, [call(30), call(60)])
diff --git a/tools/perf/core/upload_results_to_perf_dashboard.py b/tools/perf/core/upload_results_to_perf_dashboard.py index 68e1bbd5..2c2e450 100755 --- a/tools/perf/core/upload_results_to_perf_dashboard.py +++ b/tools/perf/core/upload_results_to_perf_dashboard.py
@@ -142,6 +142,7 @@ if not results_dashboard.SendResults( dashboard_json, + options.name, options.results_url, send_as_histograms=options.send_as_histograms, service_account_file=service_account_file):
diff --git a/tools/perf/expectations.config b/tools/perf/expectations.config index efd02728..88a64d1 100644 --- a/tools/perf/expectations.config +++ b/tools/perf/expectations.config
@@ -221,7 +221,7 @@ crbug.com/843547 [ Android_Go ] system_health.memory_mobile/background:news:nytimes [ Skip ] crbug.com/852888 [ Nexus_5X ] system_health.memory_mobile/background:news:nytimes [ Skip ] crbug.com/859500 [ Nexus_5X ] system_health.memory_mobile/browse:social:tumblr_infinite_scroll [ Skip ] -crbug.com/871708 [ Android_Go Android_Webview ] system_health.memory_mobile/browse:social:facebook_infinite_scroll [ Skip ] +crbug.com/871708 [ Android_Go Android_Webview Android_One ] system_health.memory_mobile/browse:social:facebook_infinite_scroll [ Skip ] # Benchmark: tab_switching.typical_25 crbug.com/747026 [ Mac ] tab_switching.typical_25/multitab:misc:typical24 [ Skip ] @@ -287,7 +287,6 @@ crbug.com/770982 [ Win ] v8.detached_context_age_in_gc/Docs_(1_open_document_tab) [ Skip ] crbug.com/812618 [ Android_Webview ] v8.detached_context_age_in_gc/Docs_(1_open_document_tab) [ Skip ] -# Benchmark: v8.runtime_stats.top_25 crbug.com/664318 [ Android ] v8.runtime_stats.top_25/* [ Skip ] # Benchmark: wasm
diff --git a/tools/perf/process_perf_results.py b/tools/perf/process_perf_results.py index 3d279c3..45e4384 100755 --- a/tools/perf/process_perf_results.py +++ b/tools/perf/process_perf_results.py
@@ -404,8 +404,7 @@ build_properties, output_json_file, service_account_file)) # Kick off the uploads in mutliple processes - cpus = mp.cpu_count() - pool = mp.Pool(cpus) + pool = mp.Pool() try: async_result = pool.map_async( _upload_individual_benchmark, invocations)
diff --git a/ui/accessibility/ax_event_generator.cc b/ui/accessibility/ax_event_generator.cc index 1f09523..25dd625a 100644 --- a/ui/accessibility/ax_event_generator.cc +++ b/ui/accessibility/ax_event_generator.cc
@@ -221,8 +221,12 @@ switch (attr) { case ax::mojom::IntAttribute::kActivedescendantId: - AddEvent(node, Event::ACTIVE_DESCENDANT_CHANGED); - active_descendant_changed_.push_back(node); + // Don't fire on invisible containers, as it confuses some screen readers, + // such as NVDA. + if (!node->data().HasState(ax::mojom::State::kInvisible)) { + AddEvent(node, Event::ACTIVE_DESCENDANT_CHANGED); + active_descendant_changed_.push_back(node); + } break; case ax::mojom::IntAttribute::kCheckedState: AddEvent(node, Event::CHECKED_STATE_CHANGED);
diff --git a/ui/aura/mus/capture_synchronizer.cc b/ui/aura/mus/capture_synchronizer.cc index 48b74f96..20234b5 100644 --- a/ui/aura/mus/capture_synchronizer.cc +++ b/ui/aura/mus/capture_synchronizer.cc
@@ -44,7 +44,11 @@ void CaptureSynchronizer::DetachFromCaptureClient( client::CaptureClient* capture_client) { - SetCaptureWindow(nullptr); + if (capture_window_ && + client::GetCaptureClient(capture_window_->GetWindow()->GetRootWindow()) == + capture_client) { + SetCaptureWindow(nullptr); + } capture_client->RemoveObserver(this); }
diff --git a/ui/aura/mus/window_tree_client_unittest.cc b/ui/aura/mus/window_tree_client_unittest.cc index b69aed9..8387522 100644 --- a/ui/aura/mus/window_tree_client_unittest.cc +++ b/ui/aura/mus/window_tree_client_unittest.cc
@@ -2307,47 +2307,49 @@ std::unique_ptr<TopLevel> top_level1 = CreateWindowTreeHostForTopLevel(); std::unique_ptr<TopLevel> top_level2 = CreateWindowTreeHostForTopLevel(); - aura::Window* root_window1 = top_level1->host->window(); - aura::Window* root_window2 = top_level2->host->window(); - std::unique_ptr<CaptureRecorder> capture_recorder1( - std::make_unique<CaptureRecorder>(root_window1)); - std::unique_ptr<CaptureRecorder> capture_recorder2( - std::make_unique<CaptureRecorder>(root_window2)); - EXPECT_NE(client::GetCaptureClient(root_window1), - client::GetCaptureClient(root_window2)); + aura::Window* root1 = top_level1->host->window(); + aura::Window* root2 = top_level2->host->window(); + auto capture_recorder1 = std::make_unique<CaptureRecorder>(root1); + auto capture_recorder2 = std::make_unique<CaptureRecorder>(root2); + EXPECT_NE(client::GetCaptureClient(root1), client::GetCaptureClient(root2)); EXPECT_EQ(0, capture_recorder1->capture_changed_count()); EXPECT_EQ(0, capture_recorder2->capture_changed_count()); - // Give capture to root_window2 and ensure everyone is notified correctly. - root_window2->SetCapture(); + // Give capture to root2 and ensure everyone is notified correctly. + root2->SetCapture(); ASSERT_TRUE(window_tree()->AckSingleChangeOfType( WindowTreeChangeType::CAPTURE, true)); EXPECT_EQ(0, capture_recorder1->capture_changed_count()); EXPECT_EQ(1, capture_recorder2->capture_changed_count()); - EXPECT_EQ(root_window2->id(), - capture_recorder2->last_gained_capture_window_id()); + EXPECT_EQ(root2->id(), capture_recorder2->last_gained_capture_window_id()); EXPECT_EQ(0, capture_recorder2->last_lost_capture_window_id()); - root_window2->ReleaseCapture(); + root2->ReleaseCapture(); capture_recorder1->reset_capture_captured_count(); capture_recorder2->reset_capture_captured_count(); - // Release capture of shouldn't affect the capture of root_window1. - root_window2->SetCapture(); - root_window1->SetCapture(); - root_window2->ReleaseCapture(); + // Releasing capture of root2 shouldn't affect root1 capture. + root2->SetCapture(); + root1->SetCapture(); + root2->ReleaseCapture(); EXPECT_EQ(1, capture_recorder1->capture_changed_count()); EXPECT_EQ(2, capture_recorder2->capture_changed_count()); - EXPECT_EQ(root_window1->id(), - capture_recorder1->last_gained_capture_window_id()); + EXPECT_EQ(root1->id(), capture_recorder1->last_gained_capture_window_id()); EXPECT_EQ(0, capture_recorder1->last_lost_capture_window_id()); EXPECT_EQ(0, capture_recorder2->last_gained_capture_window_id()); - EXPECT_EQ(root_window2->id(), - capture_recorder2->last_lost_capture_window_id()); - + EXPECT_EQ(root2->id(), capture_recorder2->last_lost_capture_window_id()); capture_recorder1->reset_capture_captured_count(); capture_recorder2->reset_capture_captured_count(); - capture_recorder1.reset(); + + // Destroying top_level2 shouldn't affect root1 capture; see crbug.com/873743. + auto* synchronizer = window_tree_client_impl()->capture_synchronizer(); + EXPECT_EQ(WindowMus::Get(root1), synchronizer->capture_window()); + synchronizer->DetachFromCaptureClient(top_level2->capture_client.get()); capture_recorder2.reset(); + top_level2->host.reset(); + EXPECT_EQ(WindowMus::Get(root1), synchronizer->capture_window()); + EXPECT_EQ(0, capture_recorder1->capture_changed_count()); + EXPECT_EQ(root1->id(), capture_recorder1->last_gained_capture_window_id()); + EXPECT_EQ(0, capture_recorder1->last_lost_capture_window_id()); } TEST_F(WindowTreeClientTest, ModalTypeWindowFail) {
diff --git a/ui/base/ime/input_method_win_base.cc b/ui/base/ime/input_method_win_base.cc index db76ef3d..046f0d05 100644 --- a/ui/base/ime/input_method_win_base.cc +++ b/ui/base/ime/input_method_win_base.cc
@@ -47,13 +47,124 @@ return nullptr; } +// Checks if a given primary language ID is a RTL language. +bool IsRTLPrimaryLangID(LANGID lang) { + switch (lang) { + case LANG_ARABIC: + case LANG_HEBREW: + case LANG_PERSIAN: + case LANG_SYRIAC: + case LANG_UIGHUR: + case LANG_URDU: + return true; + default: + return false; + } +} + +// Checks if there is any RTL keyboard layout installed in the system. +bool IsRTLKeyboardLayoutInstalled() { + static enum { + RTL_KEYBOARD_LAYOUT_NOT_INITIALIZED, + RTL_KEYBOARD_LAYOUT_INSTALLED, + RTL_KEYBOARD_LAYOUT_NOT_INSTALLED, + RTL_KEYBOARD_LAYOUT_ERROR, + } layout = RTL_KEYBOARD_LAYOUT_NOT_INITIALIZED; + + // Cache the result value. + if (layout != RTL_KEYBOARD_LAYOUT_NOT_INITIALIZED) + return layout == RTL_KEYBOARD_LAYOUT_INSTALLED; + + // Retrieve the number of layouts installed in this system. + int size = GetKeyboardLayoutList(0, NULL); + if (size <= 0) { + layout = RTL_KEYBOARD_LAYOUT_ERROR; + return false; + } + + // Retrieve the keyboard layouts in an array and check if there is an RTL + // layout in it. + std::unique_ptr<HKL[]> layouts(new HKL[size]); + ::GetKeyboardLayoutList(size, layouts.get()); + for (int i = 0; i < size; ++i) { + if (IsRTLPrimaryLangID( + PRIMARYLANGID(reinterpret_cast<uintptr_t>(layouts[i])))) { + layout = RTL_KEYBOARD_LAYOUT_INSTALLED; + return true; + } + } + + layout = RTL_KEYBOARD_LAYOUT_NOT_INSTALLED; + return false; +} + +// Checks if the user pressed both Ctrl and right or left Shift keys to +// request to change the text direction and layout alignment explicitly. +// Returns true if only a Ctrl key and a Shift key are down. The desired text +// direction will be stored in |*direction|. +bool IsCtrlShiftPressed(base::i18n::TextDirection* direction) { + uint8_t keystate[256]; + if (!::GetKeyboardState(&keystate[0])) + return false; + + // To check if a user is pressing only a control key and a right-shift key + // (or a left-shift key), we use the steps below: + // 1. Check if a user is pressing a control key and a right-shift key (or + // a left-shift key). + // 2. If the condition 1 is true, we should check if there are any other + // keys pressed at the same time. + // To ignore the keys checked in 1, we set their status to 0 before + // checking the key status. + const int kKeyDownMask = 0x80; + if ((keystate[VK_CONTROL] & kKeyDownMask) == 0) + return false; + + if (keystate[VK_RSHIFT] & kKeyDownMask) { + keystate[VK_RSHIFT] = 0; + *direction = base::i18n::RIGHT_TO_LEFT; + } else if (keystate[VK_LSHIFT] & kKeyDownMask) { + keystate[VK_LSHIFT] = 0; + *direction = base::i18n::LEFT_TO_RIGHT; + } else { + return false; + } + + // Scan the key status to find pressed keys. We should abandon changing the + // text direction when there are other pressed keys. + // This code is executed only when a user is pressing a control key and a + // right-shift key (or a left-shift key), i.e. we should ignore the status of + // the keys: VK_SHIFT, VK_CONTROL, VK_RCONTROL, and VK_LCONTROL. + // So, we reset their status to 0 and ignore them. + keystate[VK_SHIFT] = 0; + keystate[VK_CONTROL] = 0; + keystate[VK_RCONTROL] = 0; + keystate[VK_LCONTROL] = 0; + // Oddly, pressing F10 in another application seemingly breaks all subsequent + // calls to GetKeyboardState regarding the state of the F22 key. Perhaps this + // defect is limited to my keyboard driver, but ignoring F22 should be okay. + keystate[VK_F22] = 0; + for (int i = 0; i <= VK_PACKET; ++i) { + if (keystate[i] & kKeyDownMask) + return false; + } + return true; +} + +ui::EventDispatchDetails DispatcherDestroyedDetails() { + ui::EventDispatchDetails dispatcher_details; + dispatcher_details.dispatcher_destroyed = true; + return dispatcher_details; +} + } // namespace InputMethodWinBase::InputMethodWinBase(internal::InputMethodDelegate* delegate, HWND toplevel_window_handle) : InputMethodBase(delegate, CreateKeyboardController(toplevel_window_handle)), - toplevel_window_handle_(toplevel_window_handle) {} + toplevel_window_handle_(toplevel_window_handle), + pending_requested_direction_(base::i18n::UNKNOWN_DIRECTION), + weak_ptr_factory_(this) {} InputMethodWinBase::~InputMethodWinBase() {} @@ -64,6 +175,89 @@ accept_carriage_return_ = false; } +ui::EventDispatchDetails InputMethodWinBase::DispatchKeyEvent( + ui::KeyEvent* event) { + MSG native_key_event = MSGFromKeyEvent(event); + if (native_key_event.message == WM_CHAR) { + auto ref = weak_ptr_factory_.GetWeakPtr(); + BOOL handled = FALSE; + OnChar(native_key_event.hwnd, native_key_event.message, + native_key_event.wParam, native_key_event.lParam, native_key_event, + &handled); + if (!ref) + return DispatcherDestroyedDetails(); + if (handled) + event->StopPropagation(); + return ui::EventDispatchDetails(); + } + + std::vector<MSG> char_msgs; + // Combines the WM_KEY* and WM_CHAR messages in the event processing flow + // which is necessary to let Chrome IME extension to process the key event + // and perform corresponding IME actions. + // Chrome IME extension may wants to consume certain key events based on + // the character information of WM_CHAR messages. Holding WM_KEY* messages + // until WM_CHAR is processed by the IME extension is not feasible because + // there is no way to know whether there will or not be a WM_CHAR following + // the WM_KEY*. + // Chrome never handles dead chars so it is safe to remove/ignore + // WM_*DEADCHAR messages. + MSG msg; + while (::PeekMessage(&msg, native_key_event.hwnd, WM_CHAR, WM_DEADCHAR, + PM_REMOVE)) { + if (msg.message == WM_CHAR) + char_msgs.push_back(msg); + } + while (::PeekMessage(&msg, native_key_event.hwnd, WM_SYSCHAR, WM_SYSDEADCHAR, + PM_REMOVE)) { + if (msg.message == WM_SYSCHAR) + char_msgs.push_back(msg); + } + + // Handles ctrl-shift key to change text direction and layout alignment. + if (IsRTLKeyboardLayoutInstalled() && !IsTextInputTypeNone()) { + ui::KeyboardCode code = event->key_code(); + if (event->type() == ui::ET_KEY_PRESSED) { + if (code == ui::VKEY_SHIFT) { + base::i18n::TextDirection dir; + if (IsCtrlShiftPressed(&dir)) + pending_requested_direction_ = dir; + } else if (code != ui::VKEY_CONTROL) { + pending_requested_direction_ = base::i18n::UNKNOWN_DIRECTION; + } + } else if (event->type() == ui::ET_KEY_RELEASED && + (code == ui::VKEY_SHIFT || code == ui::VKEY_CONTROL) && + pending_requested_direction_ != base::i18n::UNKNOWN_DIRECTION) { + GetTextInputClient()->ChangeTextDirectionAndLayoutAlignment( + pending_requested_direction_); + pending_requested_direction_ = base::i18n::UNKNOWN_DIRECTION; + } + } + + // If only 1 WM_CHAR per the key event, set it as the character of it. + if (char_msgs.size() == 1 && + !std::iswcntrl(static_cast<wint_t>(char_msgs[0].wParam))) + event->set_character(static_cast<base::char16>(char_msgs[0].wParam)); + + // Dispatches the key events to the Chrome IME extension which is listening to + // key events on the following two situations: + // 1) |char_msgs| is empty when the event is non-character key. + // 2) |char_msgs|.size() == 1 when the event is character key and the WM_CHAR + // messages have been combined in the event processing flow. + if (char_msgs.size() <= 1 && GetEngine() && + GetEngine()->IsInterestedInKeyEvent()) { + ui::IMEEngineHandlerInterface::KeyEventDoneCallback callback = + base::BindOnce(&InputMethodWinBase::ProcessKeyEventDone, + weak_ptr_factory_.GetWeakPtr(), + base::Owned(new ui::KeyEvent(*event)), + base::Owned(new std::vector<MSG>(char_msgs))); + GetEngine()->ProcessKeyEvent(*event, std::move(callback)); + return ui::EventDispatchDetails(); + } + + return ProcessUnhandledKeyEvent(event, &char_msgs); +} + bool InputMethodWinBase::IsWindowFocused(const TextInputClient* client) const { if (!client) return false; @@ -292,4 +486,32 @@ return 1; // returns non-zero value when succeeded. } +void InputMethodWinBase::ProcessKeyEventDone(ui::KeyEvent* event, + const std::vector<MSG>* char_msgs, + bool is_handled) { + if (is_handled) + return; + ProcessUnhandledKeyEvent(event, char_msgs); +} + +ui::EventDispatchDetails InputMethodWinBase::ProcessUnhandledKeyEvent( + ui::KeyEvent* event, + const std::vector<MSG>* char_msgs) { + DCHECK(event); + ui::EventDispatchDetails details = DispatchKeyEventPostIME(event); + if (details.dispatcher_destroyed || details.target_destroyed || + event->stopped_propagation()) { + return details; + } + + BOOL handled; + for (const auto& msg : (*char_msgs)) { + auto ref = weak_ptr_factory_.GetWeakPtr(); + OnChar(msg.hwnd, msg.message, msg.wParam, msg.lParam, msg, &handled); + if (!ref) + return DispatcherDestroyedDetails(); + } + return details; +} + } // namespace ui
diff --git a/ui/base/ime/input_method_win_base.h b/ui/base/ime/input_method_win_base.h index 3c0d414..1745c866 100644 --- a/ui/base/ime/input_method_win_base.h +++ b/ui/base/ime/input_method_win_base.h
@@ -26,6 +26,7 @@ protected: void OnDidChangeFocusedClient(TextInputClient* focused_before, TextInputClient* focused) override; + ui::EventDispatchDetails DispatchKeyEvent(ui::KeyEvent* event) override; // Returns true if the Win32 native window bound to |client| is considered // to be ready for receiving keyboard input. @@ -50,6 +51,15 @@ LRESULT OnReconvertString(RECONVERTSTRING* reconv); LRESULT OnQueryCharPosition(IMECHARPOSITION* char_positon); + // Callback function for IMEEngineHandlerInterface::ProcessKeyEvent. + void ProcessKeyEventDone(ui::KeyEvent* event, + const std::vector<MSG>* char_msgs, + bool is_handled); + + ui::EventDispatchDetails ProcessUnhandledKeyEvent( + ui::KeyEvent* event, + const std::vector<MSG>* char_msgs); + // The toplevel window handle. const HWND toplevel_window_handle_; @@ -59,6 +69,14 @@ // TODO(yukawa, IME): Figure out long-term solution. bool accept_carriage_return_ = false; + // The new text direction and layout alignment requested by the user by + // pressing ctrl-shift. It'll be sent to the text input client when the key + // is released. + base::i18n::TextDirection pending_requested_direction_; + + // Used for making callbacks. + base::WeakPtrFactory<InputMethodWinBase> weak_ptr_factory_; + DISALLOW_COPY_AND_ASSIGN(InputMethodWinBase); };
diff --git a/ui/base/ime/input_method_win_imm32.cc b/ui/base/ime/input_method_win_imm32.cc index 92528b2f..162cf77e 100644 --- a/ui/base/ime/input_method_win_imm32.cc +++ b/ui/base/ime/input_method_win_imm32.cc
@@ -23,25 +23,15 @@ #include "ui/gfx/win/hwnd_util.h" namespace ui { -namespace { - -ui::EventDispatchDetails DispatcherDestroyedDetails() { - ui::EventDispatchDetails dispatcher_details; - dispatcher_details.dispatcher_destroyed = true; - return dispatcher_details; -} - -} // namespace InputMethodWinImm32::InputMethodWinImm32( internal::InputMethodDelegate* delegate, HWND toplevel_window_handle) : InputMethodWinBase(delegate, toplevel_window_handle), - pending_requested_direction_(base::i18n::UNKNOWN_DIRECTION), + enabled_(false), is_candidate_popup_open_(false), - composing_window_handle_(NULL), - weak_ptr_factory_(this) { + composing_window_handle_(NULL) { imm32_manager_.SetInputLanguage(); } @@ -97,118 +87,6 @@ return !!handled; } -ui::EventDispatchDetails InputMethodWinImm32::DispatchKeyEvent( - ui::KeyEvent* event) { - MSG native_key_event = MSGFromKeyEvent(event); - if (native_key_event.message == WM_CHAR) { - auto ref = weak_ptr_factory_.GetWeakPtr(); - BOOL handled = FALSE; - OnChar(native_key_event.hwnd, native_key_event.message, - native_key_event.wParam, native_key_event.lParam, native_key_event, - &handled); - if (!ref) - return DispatcherDestroyedDetails(); - if (handled) - event->StopPropagation(); - return ui::EventDispatchDetails(); - } - - std::vector<MSG> char_msgs; - // Combines the WM_KEY* and WM_CHAR messages in the event processing flow - // which is necessary to let Chrome IME extension to process the key event - // and perform corresponding IME actions. - // Chrome IME extension may wants to consume certain key events based on - // the character information of WM_CHAR messages. Holding WM_KEY* messages - // until WM_CHAR is processed by the IME extension is not feasible because - // there is no way to know wether there will or not be a WM_CHAR following - // the WM_KEY*. - // Chrome never handles dead chars so it is safe to remove/ignore - // WM_*DEADCHAR messages. - MSG msg; - while (::PeekMessage(&msg, native_key_event.hwnd, WM_CHAR, WM_DEADCHAR, - PM_REMOVE)) { - if (msg.message == WM_CHAR) - char_msgs.push_back(msg); - } - while (::PeekMessage(&msg, native_key_event.hwnd, WM_SYSCHAR, WM_SYSDEADCHAR, - PM_REMOVE)) { - if (msg.message == WM_SYSCHAR) - char_msgs.push_back(msg); - } - - // Handles ctrl-shift key to change text direction and layout alignment. - if (ui::IMM32Manager::IsRTLKeyboardLayoutInstalled() && - !IsTextInputTypeNone()) { - ui::KeyboardCode code = event->key_code(); - if (event->type() == ui::ET_KEY_PRESSED) { - if (code == ui::VKEY_SHIFT) { - base::i18n::TextDirection dir; - if (ui::IMM32Manager::IsCtrlShiftPressed(&dir)) - pending_requested_direction_ = dir; - } else if (code != ui::VKEY_CONTROL) { - pending_requested_direction_ = base::i18n::UNKNOWN_DIRECTION; - } - } else if (event->type() == ui::ET_KEY_RELEASED && - (code == ui::VKEY_SHIFT || code == ui::VKEY_CONTROL) && - pending_requested_direction_ != base::i18n::UNKNOWN_DIRECTION) { - GetTextInputClient()->ChangeTextDirectionAndLayoutAlignment( - pending_requested_direction_); - pending_requested_direction_ = base::i18n::UNKNOWN_DIRECTION; - } - } - - // If only 1 WM_CHAR per the key event, set it as the character of it. - if (char_msgs.size() == 1 && - !std::iswcntrl(static_cast<wint_t>(char_msgs[0].wParam))) - event->set_character(static_cast<base::char16>(char_msgs[0].wParam)); - - // Dispatches the key events to the Chrome IME extension which is listening to - // key events on the following two situations: - // 1) |char_msgs| is empty when the event is non-character key. - // 2) |char_msgs|.size() == 1 when the event is character key and the WM_CHAR - // messages have been combined in the event processing flow. - if (char_msgs.size() <= 1 && GetEngine() && - GetEngine()->IsInterestedInKeyEvent()) { - ui::IMEEngineHandlerInterface::KeyEventDoneCallback callback = - base::BindOnce(&InputMethodWinImm32::ProcessKeyEventDone, - weak_ptr_factory_.GetWeakPtr(), - base::Owned(new ui::KeyEvent(*event)), - base::Owned(new std::vector<MSG>(char_msgs))); - GetEngine()->ProcessKeyEvent(*event, std::move(callback)); - return ui::EventDispatchDetails(); - } - - return ProcessUnhandledKeyEvent(event, &char_msgs); -} - -void InputMethodWinImm32::ProcessKeyEventDone(ui::KeyEvent* event, - const std::vector<MSG>* char_msgs, - bool is_handled) { - if (is_handled) - return; - ProcessUnhandledKeyEvent(event, char_msgs); -} - -ui::EventDispatchDetails InputMethodWinImm32::ProcessUnhandledKeyEvent( - ui::KeyEvent* event, - const std::vector<MSG>* char_msgs) { - DCHECK(event); - ui::EventDispatchDetails details = DispatchKeyEventPostIME(event); - if (details.dispatcher_destroyed || details.target_destroyed || - event->stopped_propagation()) { - return details; - } - - BOOL handled; - for (const auto& msg : (*char_msgs)) { - auto ref = weak_ptr_factory_.GetWeakPtr(); - OnChar(msg.hwnd, msg.message, msg.wParam, msg.lParam, msg, &handled); - if (!ref) - return DispatcherDestroyedDetails(); - } - return details; -} - void InputMethodWinImm32::OnTextInputTypeChanged( const TextInputClient* client) { if (!IsTextInputClientFocused(client) || !IsWindowFocused(client))
diff --git a/ui/base/ime/input_method_win_imm32.h b/ui/base/ime/input_method_win_imm32.h index 1d43a29..a144e4823 100644 --- a/ui/base/ime/input_method_win_imm32.h +++ b/ui/base/ime/input_method_win_imm32.h
@@ -29,7 +29,6 @@ // Overridden from InputMethod: bool OnUntranslatedIMEMessage(const MSG event, NativeEventResult* result) override; - ui::EventDispatchDetails DispatchKeyEvent(ui::KeyEvent* event) override; void OnTextInputTypeChanged(const TextInputClient* client) override; void OnCaretBoundsChanged(const TextInputClient* client) override; void CancelComposition(const TextInputClient* client) override; @@ -80,24 +79,10 @@ // Enables or disables the IME according to the current text input type. void UpdateIMEState(); - // Callback function for IMEEngineHandlerInterface::ProcessKeyEvent. - void ProcessKeyEventDone(ui::KeyEvent* event, - const std::vector<MSG>* char_msgs, - bool is_handled); - - ui::EventDispatchDetails ProcessUnhandledKeyEvent( - ui::KeyEvent* event, - const std::vector<MSG>* char_msgs); - // Windows IMM32 wrapper. // (See "ui/base/ime/win/ime_input.h" for its details.) ui::IMM32Manager imm32_manager_; - // The new text direction and layout alignment requested by the user by - // pressing ctrl-shift. It'll be sent to the text input client when the key - // is released. - base::i18n::TextDirection pending_requested_direction_; - // True when an IME should be allowed to process key events. bool enabled_; @@ -108,9 +93,6 @@ // composition. HWND composing_window_handle_; - // Used for making callbacks. - base::WeakPtrFactory<InputMethodWinImm32> weak_ptr_factory_; - DISALLOW_COPY_AND_ASSIGN(InputMethodWinImm32); };
diff --git a/ui/base/ime/input_method_win_tsf.cc b/ui/base/ime/input_method_win_tsf.cc index 0cf6f88..5e723f1 100644 --- a/ui/base/ime/input_method_win_tsf.cc +++ b/ui/base/ime/input_method_win_tsf.cc
@@ -38,12 +38,6 @@ InputMethodWinTSF::~InputMethodWinTSF() {} -ui::EventDispatchDetails InputMethodWinTSF::DispatchKeyEvent( - ui::KeyEvent* event) { - // TODO(dtapuska): Handle WM_CHAR events. - return ui::EventDispatchDetails(); -} - void InputMethodWinTSF::OnFocus() { tsf_event_router_->SetManager( ui::TSFBridge::GetInstance()->GetThreadManager().Get());
diff --git a/ui/base/ime/input_method_win_tsf.h b/ui/base/ime/input_method_win_tsf.h index 4d8a7c4..aa53ec06 100644 --- a/ui/base/ime/input_method_win_tsf.h +++ b/ui/base/ime/input_method_win_tsf.h
@@ -23,7 +23,6 @@ ~InputMethodWinTSF() override; // Overridden from InputMethod: - ui::EventDispatchDetails DispatchKeyEvent(ui::KeyEvent* event) override; void OnFocus() override; void OnBlur() override; bool OnUntranslatedIMEMessage(const MSG event,
diff --git a/ui/base/ime/win/imm32_manager.cc b/ui/base/ime/win/imm32_manager.cc index 9f9e6548..7fbaf37 100644 --- a/ui/base/ime/win/imm32_manager.cc +++ b/ui/base/ime/win/imm32_manager.cc
@@ -92,21 +92,6 @@ } } -// Checks if a given primary language ID is a RTL language. -bool IsRTLPrimaryLangID(LANGID lang) { - switch (lang) { - case LANG_ARABIC: - case LANG_HEBREW: - case LANG_PERSIAN: - case LANG_SYRIAC: - case LANG_UIGHUR: - case LANG_URDU: - return true; - default: - return false; - } -} - } // namespace namespace ui { @@ -496,89 +481,6 @@ } // static -bool IMM32Manager::IsRTLKeyboardLayoutInstalled() { - static enum { - RTL_KEYBOARD_LAYOUT_NOT_INITIALIZED, - RTL_KEYBOARD_LAYOUT_INSTALLED, - RTL_KEYBOARD_LAYOUT_NOT_INSTALLED, - RTL_KEYBOARD_LAYOUT_ERROR, - } layout = RTL_KEYBOARD_LAYOUT_NOT_INITIALIZED; - - // Cache the result value. - if (layout != RTL_KEYBOARD_LAYOUT_NOT_INITIALIZED) - return layout == RTL_KEYBOARD_LAYOUT_INSTALLED; - - // Retrieve the number of layouts installed in this system. - int size = GetKeyboardLayoutList(0, NULL); - if (size <= 0) { - layout = RTL_KEYBOARD_LAYOUT_ERROR; - return false; - } - - // Retrieve the keyboard layouts in an array and check if there is an RTL - // layout in it. - std::unique_ptr<HKL[]> layouts(new HKL[size]); - ::GetKeyboardLayoutList(size, layouts.get()); - for (int i = 0; i < size; ++i) { - if (IsRTLPrimaryLangID( - PRIMARYLANGID(reinterpret_cast<uintptr_t>(layouts[i])))) { - layout = RTL_KEYBOARD_LAYOUT_INSTALLED; - return true; - } - } - - layout = RTL_KEYBOARD_LAYOUT_NOT_INSTALLED; - return false; -} - -bool IMM32Manager::IsCtrlShiftPressed(base::i18n::TextDirection* direction) { - uint8_t keystate[256]; - if (!::GetKeyboardState(&keystate[0])) - return false; - - // To check if a user is pressing only a control key and a right-shift key - // (or a left-shift key), we use the steps below: - // 1. Check if a user is pressing a control key and a right-shift key (or - // a left-shift key). - // 2. If the condition 1 is true, we should check if there are any other - // keys pressed at the same time. - // To ignore the keys checked in 1, we set their status to 0 before - // checking the key status. - const int kKeyDownMask = 0x80; - if ((keystate[VK_CONTROL] & kKeyDownMask) == 0) - return false; - - if (keystate[VK_RSHIFT] & kKeyDownMask) { - keystate[VK_RSHIFT] = 0; - *direction = base::i18n::RIGHT_TO_LEFT; - } else if (keystate[VK_LSHIFT] & kKeyDownMask) { - keystate[VK_LSHIFT] = 0; - *direction = base::i18n::LEFT_TO_RIGHT; - } else { - return false; - } - - // Scan the key status to find pressed keys. We should abandon changing the - // text direction when there are other pressed keys. - // This code is executed only when a user is pressing a control key and a - // right-shift key (or a left-shift key), i.e. we should ignore the status of - // the keys: VK_SHIFT, VK_CONTROL, VK_RCONTROL, and VK_LCONTROL. - // So, we reset their status to 0 and ignore them. - keystate[VK_SHIFT] = 0; - keystate[VK_CONTROL] = 0; - keystate[VK_RCONTROL] = 0; - keystate[VK_LCONTROL] = 0; - // Oddly, pressing F10 in another application seemingly breaks all subsequent - // calls to GetKeyboardState regarding the state of the F22 key. Perhaps this - // defect is limited to my keyboard driver, but ignoring F22 should be okay. - keystate[VK_F22] = 0; - for (int i = 0; i <= VK_PACKET; ++i) { - if (keystate[i] & kKeyDownMask) - return false; - } - return true; -} - void IMM32Manager::ConvertInputModeToImmFlags(TextInputMode input_mode, DWORD initial_conversion_mode, BOOL* open,
diff --git a/ui/base/ime/win/imm32_manager.h b/ui/base/ime/win/imm32_manager.h index a261a0c..e2df5f5 100644 --- a/ui/base/ime/win/imm32_manager.h +++ b/ui/base/ime/win/imm32_manager.h
@@ -237,15 +237,6 @@ // Helper functions ---------------------------------------------------------- - // Checks if there is any RTL keyboard layout installed in the system. - static bool IsRTLKeyboardLayoutInstalled(); - - // Checks if the user pressed both Ctrl and right or left Shift keys to - // requrest to change the text direction and layout alignment explicitly. - // Returns true if only a Ctrl key and a Shift key are down. The desired text - // direction will be stored in |*direction|. - static bool IsCtrlShiftPressed(base::i18n::TextDirection* direction); - // Gets parameters for ::ImmSetOpenStatus and ::ImmSetConversionStatus from // |input_mode|. static void ConvertInputModeToImmFlags(TextInputMode input_mode,
diff --git a/ui/base/ui_base_features.cc b/ui/base/ui_base_features.cc index 056fce23..f130b42 100644 --- a/ui/base/ui_base_features.cc +++ b/ui/base/ui_base_features.cc
@@ -51,7 +51,7 @@ base::FEATURE_ENABLED_BY_DEFAULT}; const base::Feature kTouchableAppContextMenu = { - "EnableTouchableAppContextMenu", base::FEATURE_DISABLED_BY_DEFAULT}; + "EnableTouchableAppContextMenu", base::FEATURE_ENABLED_BY_DEFAULT}; bool IsTouchableAppContextMenuEnabled() { return base::FeatureList::IsEnabled(kTouchableAppContextMenu) ||
diff --git a/ui/gl/BUILD.gn b/ui/gl/BUILD.gn index 904a597f..2699acc 100644 --- a/ui/gl/BUILD.gn +++ b/ui/gl/BUILD.gn
@@ -60,6 +60,7 @@ "ca_renderer_layer_params.h", "dc_renderer_layer_params.cc", "dc_renderer_layer_params.h", + "egl_timestamps.h", "gl_bindings.cc", "gl_bindings.h", "gl_bindings_autogen_gl.cc",
diff --git a/ui/gl/egl_timestamps.h b/ui/gl/egl_timestamps.h new file mode 100644 index 0000000..50ccdfb --- /dev/null +++ b/ui/gl/egl_timestamps.h
@@ -0,0 +1,34 @@ +// Copyright (c) 2018 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 UI_GL_EGL_TIMESTAMPS_H_ +#define UI_GL_EGL_TIMESTAMPS_H_ + +#include "base/time/time.h" +#include "ui/gl/gl_export.h" + +namespace gl { + +// Interface to query EGL timestamps. +class GL_EXPORT EGLTimestampClient { + public: + virtual ~EGLTimestampClient() {} + + // Returns whether EGL Timestamps are supported or not. + virtual bool IsEGLTimestampSupported() const = 0; + + // Returns false if the egl timestamps are pending for the given frame id. If + // timestamps are pending, it means the frame is not yet done. Also returns + // the presentation time, composite interval and presentation flags for a + // frame as out parameters. + virtual bool GetFrameTimestampInfoIfAvailable( + base::TimeTicks* presentation_time, + base::TimeDelta* composite_interval, + uint32_t* presentation_flags, + int frame_id) = 0; +}; + +} // namespace gl + +#endif // UI_GL_EGL_TIMESTAMPS_H_
diff --git a/ui/gl/gl_surface.cc b/ui/gl/gl_surface.cc index 5f983987..a0df579 100644 --- a/ui/gl/gl_surface.cc +++ b/ui/gl/gl_surface.cc
@@ -243,6 +243,10 @@ return false; } +EGLTimestampClient* GLSurface::GetEGLTimestampClient() { + return nullptr; +} + GLSurface* GLSurface::GetCurrent() { return current_surface_.Pointer()->Get(); }
diff --git a/ui/gl/gl_surface.h b/ui/gl/gl_surface.h index 317fb9d8..b21b2e49 100644 --- a/ui/gl/gl_surface.h +++ b/ui/gl/gl_surface.h
@@ -37,6 +37,7 @@ namespace gl { class GLContext; +class EGLTimestampClient; // Encapsulates a surface that can be rendered to with GL, hiding platform // specific management. @@ -298,6 +299,9 @@ // triple-buffered surfaces this would return 3, etc. virtual int GetBufferCount() const; + // Return the interface used for querying EGL timestamps. + virtual EGLTimestampClient* GetEGLTimestampClient(); + static GLSurface* GetCurrent(); protected:
diff --git a/ui/gl/gl_surface_egl.cc b/ui/gl/gl_surface_egl.cc index 373e5bb..5de8ec0 100644 --- a/ui/gl/gl_surface_egl.cc +++ b/ui/gl/gl_surface_egl.cc
@@ -1109,6 +1109,13 @@ eglSurfaceAttrib(GetDisplay(), surface_, EGL_TIMESTAMPS_ANDROID, EGL_TRUE); + // Check if egl composite interval is supported or not. If not then return. + // Else check which other timestamps are supported. + EGLint interval_name = EGL_COMPOSITE_INTERVAL_ANDROID; + if (!eglGetCompositorTimingSupportedANDROID(GetDisplay(), surface_, + interval_name)) + return; + static const struct { EGLint egl_name; const char* name; @@ -1131,6 +1138,25 @@ ts.egl_name)) continue; + // For presentation feedback, prefer the actual scan out time, but fallback + // to SurfaceFlinger's composite time since some devices don't support + // the former. + switch (ts.egl_name) { + case EGL_FIRST_COMPOSITION_START_TIME_ANDROID: + // Value of presentation_feedback_index_ relies on the order of + // all_timestamps. + presentation_feedback_index_ = + static_cast<int>(supported_egl_timestamps_.size()); + presentation_flags_ = 0; + break; + case EGL_DISPLAY_PRESENT_TIME_ANDROID: + presentation_feedback_index_ = + static_cast<int>(supported_egl_timestamps_.size()); + presentation_flags_ = gfx::PresentationFeedback::kVSync | + gfx::PresentationFeedback::kHWCompletion; + break; + } + // Stored in separate vectors so we can pass the egl timestamps // directly to the EGL functions. supported_egl_timestamps_.push_back(ts.egl_name); @@ -1176,21 +1202,24 @@ return gfx::SwapResult::SWAP_FAILED; } - EGLuint64KHR newFrameId = 0; - bool newFrameIdIsValid = true; + EGLuint64KHR new_frame_id = 0; + bool new_frame_id_is_valid = true; if (use_egl_timestamps_) { - newFrameIdIsValid = - !!eglGetNextFrameIdANDROID(GetDisplay(), surface_, &newFrameId); + new_frame_id_is_valid = + !!eglGetNextFrameIdANDROID(GetDisplay(), surface_, &new_frame_id); } + if (!new_frame_id_is_valid) + new_frame_id = -1; GLSurfacePresentationHelper::ScopedSwapBuffers scoped_swap_buffers( - presentation_helper_.get(), callback); + presentation_helper_.get(), callback, new_frame_id); + if (!eglSwapBuffers(GetDisplay(), surface_)) { DVLOG(1) << "eglSwapBuffers failed with error " << GetLastEGLErrorString(); scoped_swap_buffers.set_result(gfx::SwapResult::SWAP_FAILED); } else if (use_egl_timestamps_) { - UpdateSwapEvents(newFrameId, newFrameIdIsValid); + UpdateSwapEvents(new_frame_id, new_frame_id_is_valid); } #if defined(USE_X11) @@ -1383,6 +1412,80 @@ return g_use_direct_composition; } +EGLTimestampClient* NativeViewGLSurfaceEGL::GetEGLTimestampClient() { + // This api call is used by GLSurfacePresentationHelper class which is member + // of this class NativeViewGLSurfaceEGL. Hence its guaranteed "this" pointer + // will live longer than the GLSurfacePresentationHelper class. + return this; +} + +bool NativeViewGLSurfaceEGL::IsEGLTimestampSupported() const { + return use_egl_timestamps_; +} + +bool NativeViewGLSurfaceEGL::GetFrameTimestampInfoIfAvailable( + base::TimeTicks* presentation_time, + base::TimeDelta* composite_interval, + uint32_t* presentation_flags, + int frame_id) { + DCHECK(presentation_time); + DCHECK(composite_interval); + DCHECK(presentation_flags); + + TRACE_EVENT1("gpu", "NativeViewGLSurfaceEGL:GetFrameTimestampInfoIfAvailable", + "frame_id", frame_id); + + // Get the composite interval. + EGLint interval_name = EGL_COMPOSITE_INTERVAL_ANDROID; + EGLnsecsANDROID composite_interval_ns = 0; + + *presentation_time = base::TimeTicks(); + *presentation_flags = 0; + + // If an error is generated, we will treat it as a frame done for timestamp + // reporting purpose. + if (!eglGetCompositorTimingANDROID(GetDisplay(), surface_, 1, &interval_name, + &composite_interval_ns)) { + *composite_interval = base::TimeDelta::FromNanoseconds( + base::TimeTicks::kNanosecondsPerSecond / 60); + return true; + } + + // If the composite interval is pending, the frame is not yet done. + if (composite_interval_ns == EGL_TIMESTAMP_PENDING_ANDROID) { + return false; + } + DCHECK_GT(composite_interval_ns, 0); + *composite_interval = base::TimeDelta::FromNanoseconds(composite_interval_ns); + + // Get the all available timestamps for the frame. If a frame is invalid or + // an error is generated, we will treat it as a frame done for timestamp + // reporting purpose. + std::vector<EGLnsecsANDROID> egl_timestamps(supported_egl_timestamps_.size(), + EGL_TIMESTAMP_INVALID_ANDROID); + if ((frame_id < 0) || + !eglGetFrameTimestampsANDROID( + GetDisplay(), surface_, frame_id, + static_cast<EGLint>(supported_egl_timestamps_.size()), + supported_egl_timestamps_.data(), egl_timestamps.data())) { + return true; + } + DCHECK_GE(presentation_feedback_index_, 0); + + // Get the presentation time. + EGLnsecsANDROID presentation_time_ns = + egl_timestamps[presentation_feedback_index_]; + + // If the presentation time is pending, the frame is not yet done. + if (presentation_time_ns == EGL_TIMESTAMP_PENDING_ANDROID) { + return false; + } + *presentation_time = base::TimeTicks() + + base::TimeDelta::FromNanoseconds(presentation_time_ns); + *presentation_flags = presentation_flags_; + return true; +} + gfx::SwapResult NativeViewGLSurfaceEGL::SwapBuffersWithDamage( const std::vector<int>& rects, const PresentationCallback& callback) {
diff --git a/ui/gl/gl_surface_egl.h b/ui/gl/gl_surface_egl.h index c2398a61..3d44351 100644 --- a/ui/gl/gl_surface_egl.h +++ b/ui/gl/gl_surface_egl.h
@@ -21,6 +21,7 @@ #include "build/build_config.h" #include "ui/gfx/geometry/size.h" #include "ui/gfx/vsync_provider.h" +#include "ui/gl/egl_timestamps.h" #include "ui/gl/gl_bindings.h" #include "ui/gl/gl_export.h" #include "ui/gl/gl_surface.h" @@ -103,7 +104,8 @@ }; // Encapsulates an EGL surface bound to a view. -class GL_EXPORT NativeViewGLSurfaceEGL : public GLSurfaceEGL { +class GL_EXPORT NativeViewGLSurfaceEGL : public GLSurfaceEGL, + public EGLTimestampClient { public: NativeViewGLSurfaceEGL(EGLNativeWindowType window, std::unique_ptr<gfx::VSyncProvider> vsync_provider); @@ -144,6 +146,15 @@ std::unique_ptr<gfx::GpuFence> gpu_fence) override; bool FlipsVertically() const override; bool BuffersFlipped() const override; + EGLTimestampClient* GetEGLTimestampClient() override; + + // EGLTimestampClient implementation. + bool IsEGLTimestampSupported() const override; + + bool GetFrameTimestampInfoIfAvailable(base::TimeTicks* presentation_time, + base::TimeDelta* composite_interval, + uint32_t* presentation_flags, + int frame_id) override; // Takes care of the platform dependant bits, of any, for creating the window. virtual bool InitializeNativeWindow(); @@ -167,7 +178,6 @@ // Commit the |pending_overlays_| and clear the vector. Returns false if any // fail to be committed. bool CommitAndClearPendingOverlays(); - void UpdateSwapEvents(EGLuint64KHR newFrameId, bool newFrameIdIsValid); void TraceSwapEvents(EGLuint64KHR oldFrameId); @@ -191,6 +201,10 @@ std::vector<EGLint> supported_egl_timestamps_; std::vector<const char*> supported_event_names_; + // PresentationFeedback support. + int presentation_feedback_index_ = -1; + uint32_t presentation_flags_ = 0; + base::queue<SwapInfo> swap_info_queue_; bool vsync_enabled_ = true;
diff --git a/ui/gl/gl_surface_presentation_helper.cc b/ui/gl/gl_surface_presentation_helper.cc index 064dca9f..ec65cee0 100644 --- a/ui/gl/gl_surface_presentation_helper.cc +++ b/ui/gl/gl_surface_presentation_helper.cc
@@ -7,6 +7,7 @@ #include "base/threading/thread_task_runner_handle.h" #include "build/build_config.h" #include "ui/gfx/vsync_provider.h" +#include "ui/gl/egl_timestamps.h" #include "ui/gl/gl_context.h" #include "ui/gl/gl_fence.h" #include "ui/gl/gpu_timing.h" @@ -16,9 +17,15 @@ GLSurfacePresentationHelper::ScopedSwapBuffers::ScopedSwapBuffers( GLSurfacePresentationHelper* helper, const GLSurface::PresentationCallback& callback) + : ScopedSwapBuffers(helper, callback, -1) {} + +GLSurfacePresentationHelper::ScopedSwapBuffers::ScopedSwapBuffers( + GLSurfacePresentationHelper* helper, + const GLSurface::PresentationCallback& callback, + int frame_id) : helper_(helper) { if (helper_) - helper_->PreSwapBuffers(callback); + helper_->PreSwapBuffers(callback, frame_id); } GLSurfacePresentationHelper::ScopedSwapBuffers::~ScopedSwapBuffers() { @@ -29,6 +36,11 @@ GLSurfacePresentationHelper::Frame::Frame(Frame&& other) = default; GLSurfacePresentationHelper::Frame::Frame( + int frame_id, + const GLSurface::PresentationCallback& callback) + : frame_id(frame_id), callback(callback) {} + +GLSurfacePresentationHelper::Frame::Frame( std::unique_ptr<GPUTimer>&& timer, const GLSurface::PresentationCallback& callback) : timer(std::move(timer)), callback(callback) {} @@ -47,20 +59,67 @@ GLSurfacePresentationHelper::Frame& GLSurfacePresentationHelper::Frame:: operator=(Frame&& other) = default; -bool GLSurfacePresentationHelper::Frame::StillPending() const { - DCHECK(timer || fence); - return timer ? !timer->IsAvailable() : !fence->HasCompleted(); -} +bool GLSurfacePresentationHelper::GetFrameTimestampInfoIfAvailable( + const Frame& frame, + base::TimeTicks* timestamp, + base::TimeDelta* interval, + uint32_t* flags) { + DCHECK(frame.timer || frame.fence || egl_timestamp_client_); -base::TimeTicks GLSurfacePresentationHelper::Frame::GetTimestamp() const { - DCHECK(!StillPending()); - if (timer) { + if (egl_timestamp_client_) { + return egl_timestamp_client_->GetFrameTimestampInfoIfAvailable( + timestamp, interval, flags, frame.frame_id); + } else if (frame.timer) { + if (!frame.timer->IsAvailable()) + return false; int64_t start = 0; int64_t end = 0; - timer->GetStartEndTimestamps(&start, &end); - return base::TimeTicks() + base::TimeDelta::FromMicroseconds(start); + frame.timer->GetStartEndTimestamps(&start, &end); + *timestamp = base::TimeTicks() + base::TimeDelta::FromMicroseconds(start); + } else { + if (!frame.fence->HasCompleted()) + return false; + *timestamp = base::TimeTicks::Now(); } - return base::TimeTicks::Now(); + // Below logic is used to calculate final values of timestamp, interval and + // flags when using timer/fence to report the timestamps. + const bool fixed_vsync = !vsync_provider_; + const bool hw_clock = vsync_provider_ && vsync_provider_->IsHWClock(); + *interval = vsync_interval_; + *flags = 0; + if (vsync_interval_.is_zero() || fixed_vsync) { + // If VSync parameters are fixed or not available, we just run + // presentation callbacks with timestamp from GPUTimers. + return true; + } else if (*timestamp < vsync_timebase_) { + // We got a VSync whose timestamp is after GPU finished rendering this + // back buffer. + *flags = gfx::PresentationFeedback::kVSync | + gfx::PresentationFeedback::kHWCompletion; + auto delta = vsync_timebase_ - *timestamp; + if (delta < vsync_interval_) { + // The |vsync_timebase_| is the closest VSync's timestamp after the GPU + // finished rendering. + *timestamp = vsync_timebase_; + if (hw_clock) + *flags |= gfx::PresentationFeedback::kHWClock; + } else { + // The |vsync_timebase_| isn't the closest VSync's timestamp after the + // GPU finished rendering. We have to compute the closest VSync's + // timestmp. + *timestamp = + timestamp->SnappedToNextTick(vsync_timebase_, vsync_interval_); + } + } else { + // The |vsync_timebase_| is earlier than |timestamp|, we will compute the + // next vSync's timestamp and use it to run callback. + if (!vsync_interval_.is_zero()) { + *timestamp = + timestamp->SnappedToNextTick(vsync_timebase_, vsync_interval_); + *flags = gfx::PresentationFeedback::kVSync; + } + } + return true; } void GLSurfacePresentationHelper::Frame::Destroy(bool has_context) { @@ -116,6 +175,20 @@ pending_frames_.clear(); gl_context_ = context; + + // Get an egl timestamp client. + egl_timestamp_client_ = surface_->GetEGLTimestampClient(); + + // If there is an egl timestamp client, check if egl timestamps are supported + // or not. If supported, then return as there is no need to use gpu timestamp + // client or fence. + if (egl_timestamp_client_) { + if (egl_timestamp_client_->IsEGLTimestampSupported()) + return; + else + egl_timestamp_client_ = nullptr; + } + gpu_timing_client_ = context->CreateGPUTimingClient(); if (!gpu_timing_client_->IsAvailable()) gpu_timing_client_ = nullptr; @@ -128,8 +201,11 @@ } void GLSurfacePresentationHelper::PreSwapBuffers( - const GLSurface::PresentationCallback& callback) { - if (gpu_timing_client_) { + const GLSurface::PresentationCallback& callback, + int frame_id) { + if (egl_timestamp_client_) { + pending_frames_.emplace_back(frame_id, callback); + } else if (gpu_timing_client_) { std::unique_ptr<GPUTimer> timer; timer = gpu_timing_client_->CreateGPUTimer(false /* prefer_elapsed_time */); timer->QueryTimeStamp(); @@ -167,6 +243,7 @@ if (!gl_context_->MakeCurrent(surface_)) { gl_context_ = nullptr; + egl_timestamp_client_ = nullptr; gpu_timing_client_ = nullptr; for (auto& frame : pending_frames_) frame.Destroy(); @@ -177,10 +254,11 @@ bool need_update_vsync = false; bool disjoint_occurred = gpu_timing_client_ && gpu_timing_client_->CheckAndResetTimerErrors(); - if (disjoint_occurred || (!gpu_timing_client_ && !gl_fence_supported_)) { - // If GPUTimer and GLFence are not avaliable or disjoint occurred, we will - // compute the next VSync's timestamp and use it to run presentation - // callback. + if (disjoint_occurred || + (!egl_timestamp_client_ && !gpu_timing_client_ && !gl_fence_supported_)) { + // If EGLTimestamps, GPUTimer and GLFence are not available or disjoint + // occurred, we will compute the next VSync's timestamp and use it to run + // presentation callback. uint32_t flags = 0; auto timestamp = base::TimeTicks::Now(); if (!vsync_interval_.is_zero()) { @@ -206,9 +284,6 @@ } } - const bool fixed_vsync = !vsync_provider_; - const bool hw_clock = vsync_provider_ && vsync_provider_->IsHWClock(); - while (!pending_frames_.empty()) { auto& frame = pending_frames_.front(); // Helper lambda for running the presentation callback and releasing the @@ -226,49 +301,16 @@ continue; } - if (frame.StillPending()) + base::TimeTicks timestamp; + base::TimeDelta interval; + uint32_t flags = 0; + // Get timestamp info for a frame if available. If timestamp is not + // available, it means this frame is not yet done. + if (!GetFrameTimestampInfoIfAvailable(frame, ×tamp, &interval, &flags)) break; - auto timestamp = frame.GetTimestamp(); - - if (vsync_interval_.is_zero() || fixed_vsync) { - // If VSync parameters are fixed or not avaliable, we just run - // presentation callbacks with timestamp from GPUTimers. - frame_presentation_callback( - gfx::PresentationFeedback(timestamp, vsync_interval_, 0 /* flags */)); - } else if (timestamp < vsync_timebase_) { - // We got a VSync whose timestamp is after GPU finished renderering this - // back buffer. - uint32_t flags = gfx::PresentationFeedback::kVSync | - gfx::PresentationFeedback::kHWCompletion; - auto delta = vsync_timebase_ - timestamp; - if (delta < vsync_interval_) { - // The |vsync_timebase_| is the closest VSync's timestamp after the GPU - // finished renderering. - timestamp = vsync_timebase_; - if (hw_clock) - flags |= gfx::PresentationFeedback::kHWClock; - } else { - // The |vsync_timebase_| isn't the closest VSync's timestamp after the - // GPU finished renderering. We have to compute the closest VSync's - // timestmp. - timestamp = - timestamp.SnappedToNextTick(vsync_timebase_, vsync_interval_); - } - frame_presentation_callback( - gfx::PresentationFeedback(timestamp, vsync_interval_, flags)); - } else { - // The |vsync_timebase_| is earlier than |timestamp|, we will compute the - // next vSync's timestamp and use it to run callback. - uint32_t flags = 0; - if (!vsync_interval_.is_zero()) { - timestamp = - timestamp.SnappedToNextTick(vsync_timebase_, vsync_interval_); - flags = gfx::PresentationFeedback::kVSync; - } - frame_presentation_callback( - gfx::PresentationFeedback(timestamp, vsync_interval_, flags)); - } + frame_presentation_callback( + gfx::PresentationFeedback(timestamp, interval, flags)); } if (pending_frames_.empty() && !need_update_vsync)
diff --git a/ui/gl/gl_surface_presentation_helper.h b/ui/gl/gl_surface_presentation_helper.h index 32c09b7..5162891 100644 --- a/ui/gl/gl_surface_presentation_helper.h +++ b/ui/gl/gl_surface_presentation_helper.h
@@ -32,6 +32,9 @@ public: ScopedSwapBuffers(GLSurfacePresentationHelper* helper, const GLSurface::PresentationCallback& callback); + ScopedSwapBuffers(GLSurfacePresentationHelper* helper, + const GLSurface::PresentationCallback& callback, + int frame_id); ~ScopedSwapBuffers(); void set_result(gfx::SwapResult result) { result_ = result; } @@ -52,12 +55,14 @@ ~GLSurfacePresentationHelper(); void OnMakeCurrent(GLContext* context, GLSurface* surface); - void PreSwapBuffers(const GLSurface::PresentationCallback& callback); + void PreSwapBuffers(const GLSurface::PresentationCallback& callback, + int frame_id); void PostSwapBuffers(gfx::SwapResult result); private: struct Frame { Frame(Frame&& other); + Frame(int frame_id, const GLSurface::PresentationCallback& callback); Frame(std::unique_ptr<GPUTimer>&& timer, const GLSurface::PresentationCallback& callback); Frame(std::unique_ptr<GLFence>&& fence, @@ -66,17 +71,21 @@ ~Frame(); Frame& operator=(Frame&& other); - bool StillPending() const; - base::TimeTicks GetTimestamp() const; void Destroy(bool has_context = false); std::unique_ptr<GPUTimer> timer; // GLFence is used only if gpu timers are not available. std::unique_ptr<GLFence> fence; + int frame_id = -1; GLSurface::PresentationCallback callback; gfx::SwapResult result = gfx::SwapResult::SWAP_ACK; }; + bool GetFrameTimestampInfoIfAvailable(const Frame& frame, + base::TimeTicks* timestamp, + base::TimeDelta* interval, + uint32_t* flags); + // Check |pending_frames_| and run presentation callbacks. void CheckPendingFrames(); @@ -97,6 +106,7 @@ base::TimeDelta vsync_interval_; bool check_pending_frame_scheduled_ = false; bool gl_fence_supported_ = false; + EGLTimestampClient* egl_timestamp_client_ = nullptr; base::WeakPtrFactory<GLSurfacePresentationHelper> weak_ptr_factory_;
diff --git a/ui/ozone/common/linux/BUILD.gn b/ui/ozone/common/linux/BUILD.gn index 0d62943e..de979e68 100644 --- a/ui/ozone/common/linux/BUILD.gn +++ b/ui/ozone/common/linux/BUILD.gn
@@ -5,7 +5,7 @@ import("//build/config/ui.gni") import("//ui/ozone/ozone.gni") -assert(ozone_platform_gbm || ozone_platform_wayland) +assert(ozone_platform_gbm) source_set("linux") { sources = [
diff --git a/ui/ozone/common/linux/drm_util_linux.cc b/ui/ozone/common/linux/drm_util_linux.cc index b9a26887..eaa8d5822 100644 --- a/ui/ozone/common/linux/drm_util_linux.cc +++ b/ui/ozone/common/linux/drm_util_linux.cc
@@ -74,25 +74,4 @@ } } -bool IsValidBufferFormat(uint32_t current_format) { - switch (GetBufferFormatFromFourCCFormat(current_format)) { - case gfx::BufferFormat::R_8: - case gfx::BufferFormat::RG_88: - case gfx::BufferFormat::RGBA_8888: - case gfx::BufferFormat::RGBX_8888: - case gfx::BufferFormat::BGRA_8888: - case gfx::BufferFormat::BGRX_8888: - case gfx::BufferFormat::BGRX_1010102: - case gfx::BufferFormat::RGBX_1010102: - case gfx::BufferFormat::BGR_565: - case gfx::BufferFormat::UYVY_422: - case gfx::BufferFormat::YUV_420_BIPLANAR: - case gfx::BufferFormat::YVU_420: - return true; - default: - return false; - } - return false; -} - } // namespace ui
diff --git a/ui/ozone/common/linux/drm_util_linux.h b/ui/ozone/common/linux/drm_util_linux.h index 4e836bc9..f430a39 100644 --- a/ui/ozone/common/linux/drm_util_linux.h +++ b/ui/ozone/common/linux/drm_util_linux.h
@@ -13,9 +13,6 @@ int GetFourCCFormatFromBufferFormat(gfx::BufferFormat format); gfx::BufferFormat GetBufferFormatFromFourCCFormat(int format); -// Returns true if the fourcc format is known. -bool IsValidBufferFormat(uint32_t current_format); - } // namespace ui #endif // UI_OZONE_COMMON_LINUX_DRM_UTIL_LINUX_H__
diff --git a/ui/ozone/platform/drm/host/drm_device_connector.cc b/ui/ozone/platform/drm/host/drm_device_connector.cc index dfdd37c..ed0bb34 100644 --- a/ui/ozone/platform/drm/host/drm_device_connector.cc +++ b/ui/ozone/platform/drm/host/drm_device_connector.cc
@@ -61,8 +61,7 @@ void DrmDeviceConnector::OnGpuServiceLaunched( scoped_refptr<base::SingleThreadTaskRunner> ui_runner, scoped_refptr<base::SingleThreadTaskRunner> io_runner, - GpuHostBindInterfaceCallback binder, - GpuHostTerminateCallback terminate_callback) { + GpuHostBindInterfaceCallback binder) { // We need to preserve |binder| to let us bind interfaces later. binder_callback_ = std::move(binder); if (am_running_in_ws_mode()) {
diff --git a/ui/ozone/platform/drm/host/drm_device_connector.h b/ui/ozone/platform/drm/host/drm_device_connector.h index 8de058eb..d77183c 100644 --- a/ui/ozone/platform/drm/host/drm_device_connector.h +++ b/ui/ozone/platform/drm/host/drm_device_connector.h
@@ -39,8 +39,7 @@ void OnGpuServiceLaunched( scoped_refptr<base::SingleThreadTaskRunner> ui_runner, scoped_refptr<base::SingleThreadTaskRunner> io_runner, - GpuHostBindInterfaceCallback binder, - GpuHostTerminateCallback terminate_callback) override; + GpuHostBindInterfaceCallback binder) override; // BindInterface arranges for the drm_device_ptr to be connected. void BindInterfaceDrmDevice(
diff --git a/ui/ozone/platform/drm/host/drm_gpu_platform_support_host.cc b/ui/ozone/platform/drm/host/drm_gpu_platform_support_host.cc index 5daea0c..12332387 100644 --- a/ui/ozone/platform/drm/host/drm_gpu_platform_support_host.cc +++ b/ui/ozone/platform/drm/host/drm_gpu_platform_support_host.cc
@@ -121,8 +121,7 @@ void DrmGpuPlatformSupportHost::OnGpuServiceLaunched( scoped_refptr<base::SingleThreadTaskRunner> ui_runner, scoped_refptr<base::SingleThreadTaskRunner> io_runner, - GpuHostBindInterfaceCallback binder, - GpuHostTerminateCallback terminate_callback) { + GpuHostBindInterfaceCallback binder) { NOTREACHED() << "DrmGpuPlatformSupportHost::OnGpuServiceLaunched shouldn't " "be used with pre-mojo IPC"; }
diff --git a/ui/ozone/platform/drm/host/drm_gpu_platform_support_host.h b/ui/ozone/platform/drm/host/drm_gpu_platform_support_host.h index 9c8cf6f..c2d1d65 100644 --- a/ui/ozone/platform/drm/host/drm_gpu_platform_support_host.h +++ b/ui/ozone/platform/drm/host/drm_gpu_platform_support_host.h
@@ -44,8 +44,7 @@ void OnGpuServiceLaunched( scoped_refptr<base::SingleThreadTaskRunner> ui_runner, scoped_refptr<base::SingleThreadTaskRunner> io_runner, - GpuHostBindInterfaceCallback binder, - GpuHostTerminateCallback terminate_callback) override; + GpuHostBindInterfaceCallback binder) override; void OnMessageReceived(const IPC::Message& message) override;
diff --git a/ui/ozone/platform/scenic/ozone_platform_scenic.cc b/ui/ozone/platform/scenic/ozone_platform_scenic.cc index 6100a7f..5bb85d465 100644 --- a/ui/ozone/platform/scenic/ozone_platform_scenic.cc +++ b/ui/ozone/platform/scenic/ozone_platform_scenic.cc
@@ -29,11 +29,9 @@ namespace { -const OzonePlatform::PlatformProperties kScenicPlatformProperties( +constexpr OzonePlatform::PlatformProperties kScenicPlatformProperties = { /*needs_view_owner_request=*/true, - /*custom_frame_pref_default=*/false, - /*use_system_title_bar=*/false, - std::vector<gfx::BufferFormat>()); +}; class ScenicPlatformEventSource : public ui::PlatformEventSource { public:
diff --git a/ui/ozone/platform/wayland/BUILD.gn b/ui/ozone/platform/wayland/BUILD.gn index 7c5d82b1..97eae521 100644 --- a/ui/ozone/platform/wayland/BUILD.gn +++ b/ui/ozone/platform/wayland/BUILD.gn
@@ -5,7 +5,6 @@ visibility = [ "//ui/ozone/*" ] import("//build/config/linux/pkg_config.gni") -import("//ui/ozone/platform/wayland/wayland.gni") pkg_config("wayland-egl") { packages = [ "wayland-egl" ] @@ -17,14 +16,10 @@ "client_native_pixmap_factory_wayland.h", "gl_surface_wayland.cc", "gl_surface_wayland.h", - "gpu/wayland_connection_proxy.cc", - "gpu/wayland_connection_proxy.h", "ozone_platform_wayland.cc", "ozone_platform_wayland.h", "wayland_connection.cc", "wayland_connection.h", - "wayland_connection_connector.cc", - "wayland_connection_connector.h", "wayland_cursor.cc", "wayland_cursor.h", "wayland_data_device.cc", @@ -75,12 +70,8 @@ deps = [ "//base", - "//mojo/public/cpp/bindings", "//skia", - "//third_party/libdrm", - "//third_party/minigbm", "//third_party/wayland:wayland_client", - "//third_party/wayland-protocols:linux_dmabuf_protocol", "//third_party/wayland-protocols:xdg_shell_protocol", "//ui/base", "//ui/base:ui_features", @@ -88,43 +79,17 @@ "//ui/events", "//ui/events:dom_keycode_converter", "//ui/events/ozone:events_ozone", - "//ui/events/ozone:events_ozone_evdev", "//ui/events/ozone:events_ozone_layout", "//ui/events/platform", "//ui/gfx", - "//ui/gfx:memory_buffer", "//ui/gfx/geometry", "//ui/ozone:ozone_base", "//ui/ozone/common", - "//ui/ozone/common/linux", - "//ui/ozone/public/interfaces/wayland:wayland_interfaces", "//ui/platform_window", ] defines = [ "OZONE_IMPLEMENTATION" ] - import("//ui/ozone/platform/wayland/wayland.gni") - if (use_wayland_gbm) { - defines += [ "WAYLAND_GBM" ] - sources += [ - "gpu/drm_render_node_handle.cc", - "gpu/drm_render_node_handle.h", - "gpu/drm_render_node_path_finder.cc", - "gpu/drm_render_node_path_finder.h", - "gpu/gbm_pixmap_wayland.cc", - "gpu/gbm_pixmap_wayland.h", - "gpu/gbm_surfaceless_wayland.cc", - "gpu/gbm_surfaceless_wayland.h", - ] - - deps += [ - "//third_party/libdrm", - "//third_party/minigbm", - "//ui/gfx:memory_buffer", - "//ui/ozone/common/linux", - ] - } - configs += [ ":wayland-egl", "//third_party/khronos:khronos_headers",
diff --git a/ui/ozone/platform/wayland/DEPS b/ui/ozone/platform/wayland/DEPS index fde6dba3..e60ac4f2 100644 --- a/ui/ozone/platform/wayland/DEPS +++ b/ui/ozone/platform/wayland/DEPS
@@ -1,5 +1,4 @@ include_rules = [ "+ui/base/ui_features.h", # UI features doesn't bring in all of ui/base. - "+mojo/public", ]
diff --git a/ui/ozone/platform/wayland/client_native_pixmap_factory_wayland.cc b/ui/ozone/platform/wayland/client_native_pixmap_factory_wayland.cc index 0515392..5670324 100644 --- a/ui/ozone/platform/wayland/client_native_pixmap_factory_wayland.cc +++ b/ui/ozone/platform/wayland/client_native_pixmap_factory_wayland.cc
@@ -4,53 +4,12 @@ #include "ui/ozone/platform/wayland/client_native_pixmap_factory_wayland.h" -#include "ui/gfx/linux/client_native_pixmap_dmabuf.h" -#include "ui/gfx/linux/client_native_pixmap_factory_dmabuf.h" -#include "ui/ozone/public/ozone_platform.h" +#include "ui/ozone/common/stub_client_native_pixmap_factory.h" namespace ui { -// Implements ClientNativePixmapFactory to provide a more accurate buffer format -// support when Wayland dmabuf is used. -class ClientNativePixmapFactoryWayland : public gfx::ClientNativePixmapFactory { - public: - ClientNativePixmapFactoryWayland() { - dmabuf_factory_.reset(gfx::CreateClientNativePixmapFactoryDmabuf()); - } - ~ClientNativePixmapFactoryWayland() override {} - - // ClientNativePixmapFactory overrides: - bool IsConfigurationSupported(gfx::BufferFormat format, - gfx::BufferUsage usage) const override { - OzonePlatform::PlatformProperties properties = - OzonePlatform::GetInstance()->GetPlatformProperties(); - if (properties.supported_buffer_formats.empty()) { - // If the compositor did not announce supported buffer formats, do our - // best and assume those are supported. - return dmabuf_factory_->IsConfigurationSupported(format, usage); - } - - for (auto buffer_format : properties.supported_buffer_formats) { - if (buffer_format == format) - return dmabuf_factory_->IsConfigurationSupported(format, usage); - } - return false; - } - - std::unique_ptr<gfx::ClientNativePixmap> ImportFromHandle( - const gfx::NativePixmapHandle& handle, - const gfx::Size& size, - gfx::BufferUsage usage) override { - return dmabuf_factory_->ImportFromHandle(handle, size, usage); - } - - private: - std::unique_ptr<ClientNativePixmapFactory> dmabuf_factory_; - DISALLOW_COPY_AND_ASSIGN(ClientNativePixmapFactoryWayland); -}; - gfx::ClientNativePixmapFactory* CreateClientNativePixmapFactoryWayland() { - return new ClientNativePixmapFactoryWayland(); + return CreateStubClientNativePixmapFactory(); } } // namespace ui
diff --git a/ui/ozone/platform/wayland/gpu/drm_render_node_handle.cc b/ui/ozone/platform/wayland/gpu/drm_render_node_handle.cc deleted file mode 100644 index a049ee5..0000000 --- a/ui/ozone/platform/wayland/gpu/drm_render_node_handle.cc +++ /dev/null
@@ -1,35 +0,0 @@ -// Copyright 2018 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 "ui/ozone/platform/wayland/gpu/drm_render_node_handle.h" - -#include <fcntl.h> -#include <xf86drm.h> - -namespace ui { - -DrmRenderNodeHandle::DrmRenderNodeHandle() = default; - -DrmRenderNodeHandle::~DrmRenderNodeHandle() = default; - -bool DrmRenderNodeHandle::Initialize(const base::FilePath& path) { - base::ScopedFD drm_fd(open(path.value().c_str(), O_RDWR)); - if (drm_fd.get() < 0) - return false; - - drmVersionPtr drm_version = drmGetVersion(drm_fd.get()); - if (!drm_version) { - LOG(FATAL) << "Can't get version for device: '" << path << "'"; - return false; - } - - drm_fd_ = std::move(drm_fd); - return true; -} - -base::ScopedFD DrmRenderNodeHandle::PassFD() { - return std::move(drm_fd_); -} - -} // namespace ui
diff --git a/ui/ozone/platform/wayland/gpu/drm_render_node_handle.h b/ui/ozone/platform/wayland/gpu/drm_render_node_handle.h deleted file mode 100644 index 46632326..0000000 --- a/ui/ozone/platform/wayland/gpu/drm_render_node_handle.h +++ /dev/null
@@ -1,32 +0,0 @@ -// Copyright 2018 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 UI_OZONE_PLATFORM_WAYLAND_GPU_DRM_RENDER_NODE_HANDLE_H_ -#define UI_OZONE_PLATFORM_WAYLAND_GPU_DRM_RENDER_NODE_HANDLE_H_ - -#include "base/files/file_path.h" -#include "base/files/scoped_file.h" -#include "base/macros.h" - -namespace ui { - -// A wrapper around a DRM render node device handle. -class DrmRenderNodeHandle { - public: - DrmRenderNodeHandle(); - ~DrmRenderNodeHandle(); - - bool Initialize(const base::FilePath& path); - - base::ScopedFD PassFD(); - - private: - base::ScopedFD drm_fd_; - - DISALLOW_COPY_AND_ASSIGN(DrmRenderNodeHandle); -}; - -} // namespace ui - -#endif // UI_OZONE_PLATFORM_WAYLAND_GPU_DRM_RENDER_NODE_HANDLE_H_
diff --git a/ui/ozone/platform/wayland/gpu/drm_render_node_path_finder.cc b/ui/ozone/platform/wayland/gpu/drm_render_node_path_finder.cc deleted file mode 100644 index c3367aee..0000000 --- a/ui/ozone/platform/wayland/gpu/drm_render_node_path_finder.cc +++ /dev/null
@@ -1,49 +0,0 @@ -// Copyright 2018 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 "ui/ozone/platform/wayland/gpu/drm_render_node_path_finder.h" - -#include <fcntl.h> - -#include "base/files/scoped_file.h" -#include "base/strings/stringprintf.h" - -namespace ui { - -namespace { - -// Drm render node path template. -constexpr char kDriRenderNodeTemplate[] = "/dev/dri/renderD%u"; - -// Number of files to look for when discovering DRM devices. -constexpr uint32_t kDrmMaxMinor = 15; -constexpr uint32_t kRenderNodeStart = 128; -constexpr uint32_t kRenderNodeEnd = kRenderNodeStart + kDrmMaxMinor + 1; - -} // namespace - -DrmRenderNodePathFinder::DrmRenderNodePathFinder() = default; - -DrmRenderNodePathFinder::~DrmRenderNodePathFinder() = default; - -base::FilePath DrmRenderNodePathFinder::GetDrmRenderNodePath() { - if (drm_render_node_path_.empty()) - FindDrmRenderNodePath(); - - return drm_render_node_path_; -} - -void DrmRenderNodePathFinder::FindDrmRenderNodePath() { - for (uint32_t i = kRenderNodeStart; i < kRenderNodeEnd; i++) { - std::string dri_render_node(base::StringPrintf(kDriRenderNodeTemplate, i)); - base::ScopedFD drm_fd(open(dri_render_node.c_str(), O_RDWR)); - if (drm_fd.get() < 0) - continue; - - drm_render_node_path_ = base::FilePath(dri_render_node); - break; - } -} - -} // namespace ui
diff --git a/ui/ozone/platform/wayland/gpu/drm_render_node_path_finder.h b/ui/ozone/platform/wayland/gpu/drm_render_node_path_finder.h deleted file mode 100644 index a6408e7b..0000000 --- a/ui/ozone/platform/wayland/gpu/drm_render_node_path_finder.h +++ /dev/null
@@ -1,33 +0,0 @@ -// Copyright 2018 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 UI_OZONE_PLATFORM_WAYLAND_GPU_DRM_RENDER_NODE_PATH_FINDER_H_ -#define UI_OZONE_PLATFORM_WAYLAND_GPU_DRM_RENDER_NODE_PATH_FINDER_H_ - -#include "base/files/file_path.h" -#include "base/macros.h" - -namespace ui { - -// A helper class that finds a DRM render node device and returns a path to it. -class DrmRenderNodePathFinder { - public: - DrmRenderNodePathFinder(); - ~DrmRenderNodePathFinder(); - - // Returns a path to a drm render node device. If it hasn't been found yet, - // triggers FindDrmRenderNodePath and returns the path. - base::FilePath GetDrmRenderNodePath(); - - private: - void FindDrmRenderNodePath(); - - base::FilePath drm_render_node_path_; - - DISALLOW_COPY_AND_ASSIGN(DrmRenderNodePathFinder); -}; - -} // namespace ui - -#endif // UI_OZONE_PLATFORM_WAYLAND_GPU_DRM_RENDER_NODE_PATH_FINDER_H_
diff --git a/ui/ozone/platform/wayland/gpu/gbm_pixmap_wayland.cc b/ui/ozone/platform/wayland/gpu/gbm_pixmap_wayland.cc deleted file mode 100644 index 8c3d01b4..0000000 --- a/ui/ozone/platform/wayland/gpu/gbm_pixmap_wayland.cc +++ /dev/null
@@ -1,192 +0,0 @@ -// Copyright 2018 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 "ui/ozone/platform/wayland/gpu/gbm_pixmap_wayland.h" - -#include <drm_fourcc.h> -#include <gbm.h> -#include <xf86drmMode.h> - -#include "base/files/platform_file.h" -#include "base/logging.h" -#include "base/posix/eintr_wrapper.h" -#include "base/strings/stringprintf.h" -#include "base/trace_event/trace_event.h" -#include "ui/gfx/buffer_format_util.h" -#include "ui/gfx/geometry/size_conversions.h" -#include "ui/gfx/native_pixmap_handle.h" -#include "ui/ozone/common/linux/drm_util_linux.h" -#include "ui/ozone/common/linux/gbm_device.h" -#include "ui/ozone/platform/wayland/gpu/gbm_surfaceless_wayland.h" -#include "ui/ozone/platform/wayland/gpu/wayland_connection_proxy.h" -#include "ui/ozone/platform/wayland/wayland_surface_factory.h" -#include "ui/ozone/public/overlay_plane.h" -#include "ui/ozone/public/ozone_platform.h" - -namespace ui { - -GbmPixmapWayland::GbmPixmapWayland(WaylandSurfaceFactory* surface_manager, - WaylandConnectionProxy* connection) - : surface_manager_(surface_manager), connection_(connection) {} - -GbmPixmapWayland::~GbmPixmapWayland() { - connection_->DestroyZwpLinuxDmabuf(GetUniqueId()); -} - -bool GbmPixmapWayland::InitializeBuffer(gfx::Size size, - gfx::BufferFormat format, - gfx::BufferUsage usage) { - TRACE_EVENT1("Wayland", "GbmPixmapWayland::InitializeBuffer", "size", - size.ToString()); - uint32_t flags = 0; - switch (usage) { - case gfx::BufferUsage::GPU_READ: - flags = GBM_BO_USE_LINEAR; - break; - case gfx::BufferUsage::SCANOUT: - flags = GBM_BO_USE_RENDERING | GBM_BO_USE_SCANOUT; - break; - case gfx::BufferUsage::SCANOUT_CAMERA_READ_WRITE: - flags = GBM_BO_USE_LINEAR | GBM_BO_USE_WRITE | GBM_BO_USE_SCANOUT; - break; - case gfx::BufferUsage::SCANOUT_CPU_READ_WRITE: - flags = GBM_BO_USE_LINEAR | GBM_BO_USE_SCANOUT; - break; - case gfx::BufferUsage::SCANOUT_VDA_WRITE: - flags = GBM_BO_USE_SCANOUT; - break; - case gfx::BufferUsage::GPU_READ_CPU_READ_WRITE: - case gfx::BufferUsage::GPU_READ_CPU_READ_WRITE_PERSISTENT: - // mmap cannot be used with gbm buffers on a different process. That is, - // Linux disallows this and "permission denied" is returned. To overcome - // this and make software rasterization working, buffers must be created - // on the browser process and gbm_bo_map must be used. - // TODO(msisov): add support fir these two buffer usage cases. - // https://crbug.com/864914 - LOG(FATAL) << "This scenario is not supported in Wayland now"; - break; - default: - NOTREACHED() << "Not supported buffer format"; - break; - } - - const uint32_t fourcc_format = GetFourCCFormatFromBufferFormat(format); - gbm_bo_ = connection_->gbm_device()->CreateBuffer(fourcc_format, size, flags); - if (!gbm_bo_) { - LOG(FATAL) << "Cannot create bo"; - return false; - } - - CreateZwpLinuxDmabuf(); - return true; -} - -bool GbmPixmapWayland::AreDmaBufFdsValid() const { - return gbm_bo_->AreFdsValid(); -} - -size_t GbmPixmapWayland::GetDmaBufFdCount() const { - return gbm_bo_->GetFdCount(); -} - -int GbmPixmapWayland::GetDmaBufFd(size_t plane) const { - return gbm_bo_->GetPlaneFd(plane); -} - -int GbmPixmapWayland::GetDmaBufPitch(size_t plane) const { - return gbm_bo_->GetPlaneStride(plane); -} - -int GbmPixmapWayland::GetDmaBufOffset(size_t plane) const { - return gbm_bo_->GetPlaneOffset(plane); -} - -uint64_t GbmPixmapWayland::GetDmaBufModifier(size_t plane) const { - // TODO(msisov): figure out why returning format modifier results in - // EGL_BAD_ALLOC. - // - // return gbm_bo_->get_format_modifier(); - return 0; -} - -gfx::BufferFormat GbmPixmapWayland::GetBufferFormat() const { - return gbm_bo_->GetBufferFormat(); -} - -gfx::Size GbmPixmapWayland::GetBufferSize() const { - return gbm_bo_->GetSize(); -} - -uint32_t GbmPixmapWayland::GetUniqueId() const { - return gbm_bo_->GetHandle(); -} - -bool GbmPixmapWayland::ScheduleOverlayPlane( - gfx::AcceleratedWidget widget, - int plane_z_order, - gfx::OverlayTransform plane_transform, - const gfx::Rect& display_bounds, - const gfx::RectF& crop_rect, - bool enable_blend, - std::unique_ptr<gfx::GpuFence> gpu_fence) { - GbmSurfacelessWayland* surfaceless = surface_manager_->GetSurface(widget); - DCHECK(surfaceless); - surfaceless->QueueOverlayPlane( - OverlayPlane(this, std::move(gpu_fence), plane_z_order, plane_transform, - display_bounds, crop_rect, enable_blend)); - return true; -} - -gfx::NativePixmapHandle GbmPixmapWayland::ExportHandle() { - gfx::NativePixmapHandle handle; - gfx::BufferFormat format = GetBufferFormat(); - - // TODO(dcastagna): Use gbm_bo_get_num_planes once all the formats we use are - // supported by gbm. - for (size_t i = 0; i < gfx::NumberOfPlanesForBufferFormat(format); ++i) { - // Some formats (e.g: YVU_420) might have less than one fd per plane. - if (i < GetDmaBufFdCount()) { - base::ScopedFD scoped_fd(HANDLE_EINTR(dup(GetDmaBufFd(i)))); - if (!scoped_fd.is_valid()) { - PLOG(ERROR) << "dup"; - return gfx::NativePixmapHandle(); - } - handle.fds.emplace_back( - base::FileDescriptor(scoped_fd.release(), true /* auto_close */)); - } - handle.planes.emplace_back(GetDmaBufPitch(i), GetDmaBufOffset(i), - gbm_bo_->GetPlaneSize(i), GetDmaBufModifier(i)); - } - return handle; -} - -void GbmPixmapWayland::CreateZwpLinuxDmabuf() { - uint64_t modifier = gbm_bo_->GetFormatModifier(); - - std::vector<uint32_t> strides; - std::vector<uint32_t> offsets; - std::vector<uint64_t> modifiers; - - size_t plane_count = gbm_bo_->GetNumPlanes(); - for (size_t i = 0; i < plane_count; ++i) { - strides.push_back(GetDmaBufPitch(i)); - offsets.push_back(GetDmaBufOffset(i)); - if (modifier != DRM_FORMAT_MOD_INVALID) - modifiers.push_back(modifier); - } - - base::ScopedFD fd(HANDLE_EINTR(dup(GetDmaBufFd(0)))); - if (!fd.is_valid()) { - PLOG(FATAL) << "dup"; - return; - } - base::File file(fd.release()); - - // Asks Wayland to create a wl_buffer based on the |file| fd. - connection_->CreateZwpLinuxDmabuf(std::move(file), GetBufferSize(), strides, - offsets, modifiers, gbm_bo_->GetFormat(), - plane_count, GetUniqueId()); -} - -} // namespace ui
diff --git a/ui/ozone/platform/wayland/gpu/gbm_pixmap_wayland.h b/ui/ozone/platform/wayland/gpu/gbm_pixmap_wayland.h deleted file mode 100644 index 6998041..0000000 --- a/ui/ozone/platform/wayland/gpu/gbm_pixmap_wayland.h +++ /dev/null
@@ -1,70 +0,0 @@ -// Copyright 2018 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 UI_OZONE_PLATFORM_WAYLAND_GPU_GBM_PIXMAP_WAYLAND_H_ -#define UI_OZONE_PLATFORM_WAYLAND_GPU_GBM_PIXMAP_WAYLAND_H_ - -#include <vector> - -#include "base/files/scoped_file.h" -#include "base/macros.h" -#include "ui/gfx/buffer_types.h" -#include "ui/gfx/geometry/size.h" -#include "ui/gfx/native_pixmap.h" -#include "ui/ozone/common/linux/gbm_buffer.h" - -namespace ui { - -class WaylandSurfaceFactory; -class WaylandConnectionProxy; - -class GbmPixmapWayland : public gfx::NativePixmap { - public: - GbmPixmapWayland(WaylandSurfaceFactory* surface_manager, - WaylandConnectionProxy* connection); - - // Creates a buffer object and initializes the pixmap buffer. - bool InitializeBuffer(gfx::Size size, - gfx::BufferFormat format, - gfx::BufferUsage usage); - - // gfx::NativePixmap overrides: - bool AreDmaBufFdsValid() const override; - size_t GetDmaBufFdCount() const override; - int GetDmaBufFd(size_t plane) const override; - int GetDmaBufPitch(size_t plane) const override; - int GetDmaBufOffset(size_t plane) const override; - uint64_t GetDmaBufModifier(size_t plane) const override; - gfx::BufferFormat GetBufferFormat() const override; - gfx::Size GetBufferSize() const override; - uint32_t GetUniqueId() const override; - bool ScheduleOverlayPlane(gfx::AcceleratedWidget widget, - int plane_z_order, - gfx::OverlayTransform plane_transform, - const gfx::Rect& display_bounds, - const gfx::RectF& crop_rect, - bool enable_blend, - std::unique_ptr<gfx::GpuFence> gpu_fence) override; - gfx::NativePixmapHandle ExportHandle() override; - - private: - ~GbmPixmapWayland() override; - - // Asks Wayland to create a dmabuf based wl_buffer. - void CreateZwpLinuxDmabuf(); - - // gbm_bo wrapper for struct gbm_bo. - std::unique_ptr<GbmBuffer> gbm_bo_; - - WaylandSurfaceFactory* surface_manager_ = nullptr; - - // Represents a connection to Wayland. - WaylandConnectionProxy* connection_ = nullptr; - - DISALLOW_COPY_AND_ASSIGN(GbmPixmapWayland); -}; - -} // namespace ui - -#endif // UI_OZONE_PLATFORM_WAYLAND_GPU_GBM_PIXMAP_WAYLAND_H_
diff --git a/ui/ozone/platform/wayland/gpu/gbm_surfaceless_wayland.cc b/ui/ozone/platform/wayland/gpu/gbm_surfaceless_wayland.cc deleted file mode 100644 index 5403739..0000000 --- a/ui/ozone/platform/wayland/gpu/gbm_surfaceless_wayland.cc +++ /dev/null
@@ -1,251 +0,0 @@ -// Copyright 2018 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 "ui/ozone/platform/wayland/gpu/gbm_surfaceless_wayland.h" - -#include "base/bind.h" -#include "base/task/post_task.h" -#include "base/trace_event/trace_event.h" -#include "ui/gfx/gpu_fence.h" -#include "ui/ozone/common/egl_util.h" -#include "ui/ozone/platform/wayland/wayland_surface_factory.h" - -namespace ui { - -namespace { - -void WaitForFence(EGLDisplay display, EGLSyncKHR fence) { - eglClientWaitSyncKHR(display, fence, EGL_SYNC_FLUSH_COMMANDS_BIT_KHR, - EGL_FOREVER_KHR); - eglDestroySyncKHR(display, fence); -} - -} // namespace - -GbmSurfacelessWayland::GbmSurfacelessWayland( - WaylandSurfaceFactory* surface_factory, - gfx::AcceleratedWidget widget) - : SurfacelessEGL(gfx::Size()), - surface_factory_(surface_factory), - widget_(widget), - has_implicit_external_sync_( - HasEGLExtension("EGL_ARM_implicit_external_sync")), - weak_factory_(this) { - surface_factory_->RegisterSurface(widget_, this); - unsubmitted_frames_.push_back(std::make_unique<PendingFrame>()); -} - -void GbmSurfacelessWayland::QueueOverlayPlane(OverlayPlane plane) { - planes_.push_back(std::move(plane)); -} - -bool GbmSurfacelessWayland::ScheduleOverlayPlane( - int z_order, - gfx::OverlayTransform transform, - gl::GLImage* image, - const gfx::Rect& bounds_rect, - const gfx::RectF& crop_rect, - bool enable_blend, - std::unique_ptr<gfx::GpuFence> gpu_fence) { - unsubmitted_frames_.back()->overlays.push_back( - gl::GLSurfaceOverlay(z_order, transform, image, bounds_rect, crop_rect, - enable_blend, std::move(gpu_fence))); - return true; -} - -bool GbmSurfacelessWayland::IsOffscreen() { - return false; -} - -bool GbmSurfacelessWayland::SupportsPresentationCallback() { - // TODO(msisov): enable a real presentation callback for wayland. For now, we - // just blindly say it was successful. https://crbug.com/859012. - return true; -} - -bool GbmSurfacelessWayland::SupportsAsyncSwap() { - return true; -} - -bool GbmSurfacelessWayland::SupportsPostSubBuffer() { - // TODO(msisov): figure out how to enable subbuffers with wayland/dmabuf. - return false; -} - -gfx::SwapResult GbmSurfacelessWayland::PostSubBuffer( - int x, - int y, - int width, - int height, - const PresentationCallback& callback) { - // The actual sub buffer handling is handled at higher layers. - NOTREACHED(); - return gfx::SwapResult::SWAP_FAILED; -} - -void GbmSurfacelessWayland::SwapBuffersAsync( - const SwapCompletionCallback& completion_callback, - const PresentationCallback& presentation_callback) { - TRACE_EVENT0("wayland", "GbmSurfacelessWayland::SwapBuffersAsync"); - // If last swap failed, don't try to schedule new ones. - if (!last_swap_buffers_result_) { - completion_callback.Run(gfx::SwapResult::SWAP_FAILED, nullptr); - // Notify the caller, the buffer is never presented on a screen. - presentation_callback.Run(gfx::PresentationFeedback::Failure()); - return; - } - - // TODO(dcastagna): remove glFlush since eglImageFlushExternalEXT called on - // the image should be enough (https://crbug.com/720045). - glFlush(); - unsubmitted_frames_.back()->Flush(); - - PendingFrame* frame = unsubmitted_frames_.back().get(); - frame->completion_callback = completion_callback; - frame->presentation_callback = presentation_callback; - unsubmitted_frames_.push_back(std::make_unique<PendingFrame>()); - - // TODO: the following should be replaced by a per surface flush as it gets - // implemented in GL drivers. - EGLSyncKHR fence = InsertFence(has_implicit_external_sync_); - if (!fence) { - completion_callback.Run(gfx::SwapResult::SWAP_FAILED, nullptr); - // Notify the caller, the buffer is never presented on a screen. - presentation_callback.Run(gfx::PresentationFeedback::Failure()); - return; - } - - base::OnceClosure fence_wait_task = - base::BindOnce(&WaitForFence, GetDisplay(), fence); - - base::OnceClosure fence_retired_callback = base::BindOnce( - &GbmSurfacelessWayland::FenceRetired, weak_factory_.GetWeakPtr(), frame); - - base::PostTaskWithTraitsAndReply( - FROM_HERE, - {base::MayBlock(), base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}, - std::move(fence_wait_task), std::move(fence_retired_callback)); -} - -void GbmSurfacelessWayland::PostSubBufferAsync( - int x, - int y, - int width, - int height, - const SwapCompletionCallback& completion_callback, - const PresentationCallback& presentation_callback) { - // See the comment in SupportsPostSubBuffer. - NOTREACHED(); -} - -EGLConfig GbmSurfacelessWayland::GetConfig() { - if (!config_) { - EGLint config_attribs[] = {EGL_BUFFER_SIZE, - 32, - EGL_ALPHA_SIZE, - 8, - EGL_BLUE_SIZE, - 8, - EGL_GREEN_SIZE, - 8, - EGL_RED_SIZE, - 8, - EGL_RENDERABLE_TYPE, - EGL_OPENGL_ES2_BIT, - EGL_SURFACE_TYPE, - EGL_DONT_CARE, - EGL_NONE}; - config_ = ChooseEGLConfig(GetDisplay(), config_attribs); - } - return config_; -} - -GbmSurfacelessWayland::~GbmSurfacelessWayland() { - surface_factory_->UnregisterSurface(widget_); -} - -GbmSurfacelessWayland::PendingFrame::PendingFrame() {} - -GbmSurfacelessWayland::PendingFrame::~PendingFrame() {} - -bool GbmSurfacelessWayland::PendingFrame::ScheduleOverlayPlanes( - gfx::AcceleratedWidget widget) { - for (auto& overlay : overlays) - if (!overlay.ScheduleOverlayPlane(widget)) - return false; - return true; -} - -void GbmSurfacelessWayland::PendingFrame::Flush() { - for (const auto& overlay : overlays) - overlay.Flush(); -} - -void GbmSurfacelessWayland::SubmitFrame() { - DCHECK(!unsubmitted_frames_.empty()); - - if (unsubmitted_frames_.front()->ready && !submitted_frame_) { - submitted_frame_ = std::move(unsubmitted_frames_.front()); - unsubmitted_frames_.erase(unsubmitted_frames_.begin()); - - bool schedule_planes_succeeded = - submitted_frame_->ScheduleOverlayPlanes(widget_); - - if (!schedule_planes_succeeded) { - OnSubmission(gfx::SwapResult::SWAP_FAILED, nullptr); - OnPresentation(gfx::PresentationFeedback::Failure()); - return; - } - - uint32_t buffer_id = planes_.back().pixmap->GetUniqueId(); - surface_factory_->ScheduleBufferSwap(widget_, buffer_id); - - // Check comment in ::SupportsPresentationCallback. - OnSubmission(gfx::SwapResult::SWAP_ACK, nullptr); - OnPresentation( - gfx::PresentationFeedback(base::TimeTicks::Now(), base::TimeDelta(), - gfx::PresentationFeedback::kZeroCopy)); - - planes_.clear(); - } -} - -EGLSyncKHR GbmSurfacelessWayland::InsertFence(bool implicit) { - const EGLint attrib_list[] = {EGL_SYNC_CONDITION_KHR, - EGL_SYNC_PRIOR_COMMANDS_IMPLICIT_EXTERNAL_ARM, - EGL_NONE}; - return eglCreateSyncKHR(GetDisplay(), EGL_SYNC_FENCE_KHR, - implicit ? attrib_list : NULL); -} - -void GbmSurfacelessWayland::FenceRetired(PendingFrame* frame) { - frame->ready = true; - SubmitFrame(); -} - -void GbmSurfacelessWayland::OnSubmission( - gfx::SwapResult result, - std::unique_ptr<gfx::GpuFence> out_fence) { - submitted_frame_->swap_result = result; -} - -void GbmSurfacelessWayland::OnPresentation( - const gfx::PresentationFeedback& feedback) { - // Explicitly destroy overlays to free resources (e.g., fences) early. - submitted_frame_->overlays.clear(); - - gfx::SwapResult result = submitted_frame_->swap_result; - std::move(submitted_frame_->completion_callback).Run(result, nullptr); - std::move(submitted_frame_->presentation_callback).Run(feedback); - submitted_frame_.reset(); - - if (result == gfx::SwapResult::SWAP_FAILED) { - last_swap_buffers_result_ = false; - return; - } - - SubmitFrame(); -} - -} // namespace ui
diff --git a/ui/ozone/platform/wayland/gpu/gbm_surfaceless_wayland.h b/ui/ozone/platform/wayland/gpu/gbm_surfaceless_wayland.h deleted file mode 100644 index cc660f3..0000000 --- a/ui/ozone/platform/wayland/gpu/gbm_surfaceless_wayland.h +++ /dev/null
@@ -1,102 +0,0 @@ -// Copyright 2018 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 UI_OZONE_PLATFORM_WAYLAND_GPU_GBM_SURFACELESS_WAYLAND_H_ -#define UI_OZONE_PLATFORM_WAYLAND_GPU_GBM_SURFACELESS_WAYLAND_H_ - -#include "base/macros.h" -#include "base/memory/weak_ptr.h" -#include "ui/gfx/native_widget_types.h" -#include "ui/gl/gl_surface_egl.h" -#include "ui/ozone/public/overlay_plane.h" -#include "ui/ozone/public/swap_completion_callback.h" - -namespace ui { - -class WaylandSurfaceFactory; - -// A GLSurface for Wayland Ozone platform that uses surfaceless drawing. Drawing -// and displaying happens directly through NativePixmap buffers. CC would call -// into SurfaceFactoryOzone to allocate the buffers and then call -// ScheduleOverlayPlane(..) to schedule the buffer for presentation. -class GbmSurfacelessWayland : public gl::SurfacelessEGL { - public: - GbmSurfacelessWayland(WaylandSurfaceFactory* surface_factory, - gfx::AcceleratedWidget widget); - - void QueueOverlayPlane(OverlayPlane plane); - - // gl::GLSurface: - bool ScheduleOverlayPlane(int z_order, - gfx::OverlayTransform transform, - gl::GLImage* image, - const gfx::Rect& bounds_rect, - const gfx::RectF& crop_rect, - bool enable_blend, - std::unique_ptr<gfx::GpuFence> gpu_fence) override; - bool IsOffscreen() override; - bool SupportsPresentationCallback() override; - bool SupportsAsyncSwap() override; - bool SupportsPostSubBuffer() override; - gfx::SwapResult PostSubBuffer(int x, - int y, - int width, - int height, - const PresentationCallback& callback) override; - void SwapBuffersAsync( - const SwapCompletionCallback& completion_callback, - const PresentationCallback& presentation_callback) override; - void PostSubBufferAsync( - int x, - int y, - int width, - int height, - const SwapCompletionCallback& completion_callback, - const PresentationCallback& presentation_callback) override; - EGLConfig GetConfig() override; - - private: - ~GbmSurfacelessWayland() override; - - struct PendingFrame { - PendingFrame(); - ~PendingFrame(); - - bool ScheduleOverlayPlanes(gfx::AcceleratedWidget widget); - void Flush(); - - bool ready = false; - gfx::SwapResult swap_result = gfx::SwapResult::SWAP_FAILED; - std::vector<gl::GLSurfaceOverlay> overlays; - SwapCompletionCallback completion_callback; - PresentationCallback presentation_callback; - }; - - void SubmitFrame(); - - EGLSyncKHR InsertFence(bool implicit); - void FenceRetired(PendingFrame* frame); - - void OnSubmission(gfx::SwapResult result, - std::unique_ptr<gfx::GpuFence> out_fence); - void OnPresentation(const gfx::PresentationFeedback& feedback); - - WaylandSurfaceFactory* surface_factory_; - std::vector<OverlayPlane> planes_; - - // The native surface. Deleting this is allowed to free the EGLNativeWindow. - gfx::AcceleratedWidget widget_; - std::vector<std::unique_ptr<PendingFrame>> unsubmitted_frames_; - std::unique_ptr<PendingFrame> submitted_frame_; - bool has_implicit_external_sync_; - bool last_swap_buffers_result_ = true; - - base::WeakPtrFactory<GbmSurfacelessWayland> weak_factory_; - - DISALLOW_COPY_AND_ASSIGN(GbmSurfacelessWayland); -}; - -} // namespace ui - -#endif // UI_OZONE_PLATFORM_WAYLAND_GPU_GBM_SURFACELESS_WAYLAND_H_
diff --git a/ui/ozone/platform/wayland/gpu/wayland_connection_proxy.cc b/ui/ozone/platform/wayland/gpu/wayland_connection_proxy.cc deleted file mode 100644 index 149f3369..0000000 --- a/ui/ozone/platform/wayland/gpu/wayland_connection_proxy.cc +++ /dev/null
@@ -1,118 +0,0 @@ -// Copyright 2018 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 "ui/ozone/platform/wayland/gpu/wayland_connection_proxy.h" - -#include "base/process/process.h" -#include "third_party/khronos/EGL/egl.h" -#include "ui/ozone/common/linux/drm_util_linux.h" -#include "ui/ozone/platform/wayland/wayland_connection.h" - -namespace ui { - -WaylandConnectionProxy::WaylandConnectionProxy(WaylandConnection* connection) - : connection_(connection), - ui_runner_(base::ThreadTaskRunnerHandle::Get()) {} - -WaylandConnectionProxy::~WaylandConnectionProxy() = default; - -void WaylandConnectionProxy::SetWaylandConnection( - ozone::mojom::WaylandConnectionPtr wc_ptr) { - // Store current thread's task runner to be able to make mojo calls on the - // right sequence. - ui_runner_ = base::ThreadTaskRunnerHandle::Get(); - wc_ptr.Bind(wc_ptr.PassInterface()); - wc_ptr_ = std::move(wc_ptr); -} - -void WaylandConnectionProxy::CreateZwpLinuxDmabuf( - base::File file, - gfx::Size size, - const std::vector<uint32_t>& strides, - const std::vector<uint32_t>& offsets, - const std::vector<uint64_t>& modifiers, - uint32_t current_format, - uint32_t planes_count, - uint32_t buffer_id) { - DCHECK(ui_runner_->BelongsToCurrentThread()); - DCHECK(wc_ptr_); - wc_ptr_->CreateZwpLinuxDmabuf(std::move(file), size.width(), size.height(), - strides, offsets, current_format, modifiers, - planes_count, buffer_id); -} - -void WaylandConnectionProxy::DestroyZwpLinuxDmabuf(uint32_t buffer_id) { - // Mojo calls must be done on the right sequence. - DCHECK(ui_runner_); - ui_runner_->PostTask( - FROM_HERE, - base::BindOnce(&WaylandConnectionProxy::DestroyZwpLinuxDmabufInternal, - base::Unretained(this), buffer_id)); -} - -void WaylandConnectionProxy::DestroyZwpLinuxDmabufInternal(uint32_t buffer_id) { - DCHECK(ui_runner_->BelongsToCurrentThread()); - DCHECK(wc_ptr_); - wc_ptr_->DestroyZwpLinuxDmabuf(buffer_id); -} - -void WaylandConnectionProxy::ScheduleBufferSwap(gfx::AcceleratedWidget widget, - uint32_t buffer_id) { - // Mojo calls must be done on the right sequence. - DCHECK(ui_runner_); - ui_runner_->PostTask( - FROM_HERE, - base::BindOnce(&WaylandConnectionProxy::ScheduleBufferSwapInternal, - base::Unretained(this), widget, buffer_id)); -} - -void WaylandConnectionProxy::ScheduleBufferSwapInternal( - gfx::AcceleratedWidget widget, - uint32_t buffer_id) { - DCHECK(ui_runner_->BelongsToCurrentThread()); - DCHECK(wc_ptr_); - wc_ptr_->ScheduleBufferSwap(widget, buffer_id); -} - -WaylandWindow* WaylandConnectionProxy::GetWindow( - gfx::AcceleratedWidget widget) { - if (connection_) - return connection_->GetWindow(widget); - return nullptr; -} - -void WaylandConnectionProxy::ScheduleFlush() { - if (connection_) - return connection_->ScheduleFlush(); - - LOG(FATAL) << "Flush mustn't be called directly on the WaylandConnection, " - "when multi-process moe is used"; -} - -wl_shm* WaylandConnectionProxy::shm() { - wl_shm* shm = nullptr; - if (connection_) - shm = connection_->shm(); - return shm; -} - -intptr_t WaylandConnectionProxy::Display() { - if (connection_) - return reinterpret_cast<intptr_t>(connection_->display()); - -#if defined(WAYLAND_GBM) - // It must not be a single process mode. Thus, shared dmabuf approach is used, - // which requires |gbm_device_|. - DCHECK(gbm_device_); - return EGL_DEFAULT_DISPLAY; -#endif - return 0; -} - -void WaylandConnectionProxy::AddBindingWaylandConnectionClient( - ozone::mojom::WaylandConnectionClientRequest request) { - bindings_.AddBinding(this, std::move(request)); -} - -} // namespace ui
diff --git a/ui/ozone/platform/wayland/gpu/wayland_connection_proxy.h b/ui/ozone/platform/wayland/gpu/wayland_connection_proxy.h deleted file mode 100644 index dcd8eaf8..0000000 --- a/ui/ozone/platform/wayland/gpu/wayland_connection_proxy.h +++ /dev/null
@@ -1,123 +0,0 @@ -// Copyright 2018 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 UI_OZONE_PLATFORM_WAYLAND_GPU_WAYLAND_CONNECTION_PROXY_H_ -#define UI_OZONE_PLATFORM_WAYLAND_GPU_WAYLAND_CONNECTION_PROXY_H_ - -#include "base/macros.h" -#include "base/threading/sequenced_task_runner_handle.h" -#include "base/threading/thread_checker.h" -#include "mojo/public/cpp/bindings/binding_set.h" -#include "ui/gfx/native_widget_types.h" -#include "ui/ozone/platform/wayland/wayland_connection.h" -#include "ui/ozone/public/interfaces/wayland/wayland_connection.mojom.h" - -#if defined(WAYLAND_GBM) -#include "ui/ozone/common/linux/gbm_device.h" -#endif - -struct wl_shm; - -namespace ui { - -class WaylandConnection; -class WaylandWindow; - -// Provides a proxy connection to a WaylandConnection object on -// browser process side. When in multi-process mode, this is used to create -// Wayland dmabufs and ask it to do commits. When in single process mode, -// this class just forwards calls directly to WaylandConnection. -// -// It's guaranteed that WaylandConnectionProxy makes mojo calls on the right -// sequence. -class WaylandConnectionProxy : public ozone::mojom::WaylandConnectionClient { - public: - explicit WaylandConnectionProxy(WaylandConnection* connection); - ~WaylandConnectionProxy() override; - - // WaylandConnectionProxy overrides: - void SetWaylandConnection(ozone::mojom::WaylandConnectionPtr wc_ptr) override; - - // Methods, which must be used when GPU is hosted on a different process - // aka gpu process. - // - // Asks Wayland to create a wl_buffer based on a shared buffer file - // descriptor backed (gbm_bo). - void CreateZwpLinuxDmabuf(base::File file, - gfx::Size size, - const std::vector<uint32_t>& strides, - const std::vector<uint32_t>& offsets, - const std::vector<uint64_t>& modifiers, - uint32_t current_format, - uint32_t planes_count, - uint32_t buffer_id); - - // Asks Wayland to destroy a wl_buffer. - void DestroyZwpLinuxDmabuf(uint32_t buffer_id); - - // Asks Wayland to find a wl_buffer with the |buffer_id| and schedule a - // buffer swap for a WaylandWindow, which backs the following |widget|. - void ScheduleBufferSwap(gfx::AcceleratedWidget widget, uint32_t buffer_id); - -#if defined(WAYLAND_GBM) - // Returns a gbm_device based on a DRM render node. - GbmDevice* gbm_device() const { return gbm_device_.get(); } - void set_gbm_device(std::unique_ptr<GbmDevice> gbm_device) { - gbm_device_ = std::move(gbm_device); - } -#endif - - // Methods, which must be used when a single process mode is used (GPU is - // hosted in the browser process). - // - // Return a WaylandWindow based on the |widget|. - WaylandWindow* GetWindow(gfx::AcceleratedWidget widget); - // Schedule flush in the Wayland message loop. - void ScheduleFlush(); - // Returns an object for a shared memory support. Used for software fallback. - wl_shm* shm(); - - // Methods, which can be used with both single- and multi-process modes. - // - // Returns a pointer to native display. When used in single process mode, - // a wl_display pointer is returned. For the the mode, when there are GPU - // and browser processes, EGL_DEFAULT_DISPLAY is returned. - intptr_t Display(); - - // Adds a WaylandConnectionClient binding. - void AddBindingWaylandConnectionClient( - ozone::mojom::WaylandConnectionClientRequest request); - - WaylandConnection* connection() { return connection_; } - - private: - void DestroyZwpLinuxDmabufInternal(uint32_t buffer_id); - void ScheduleBufferSwapInternal(gfx::AcceleratedWidget widget, - uint32_t buffer_id); - - // Non-owned pointer to a WaylandConnection. It is only used in a single - // process mode, when a shared dmabuf approach is not used. - WaylandConnection* connection_ = nullptr; - -#if defined(WAYLAND_GBM) - // A DRM render node based gbm device. - std::unique_ptr<GbmDevice> gbm_device_; -#endif - - mojo::BindingSet<ozone::mojom::WaylandConnectionClient> bindings_; - - // A pointer to a WaylandConnection object, which always lives on a browser - // process side. It's used for a multi-process mode. - ozone::mojom::WaylandConnectionPtr wc_ptr_; - - // A task runner, which is initialized when a WaylandConnectionPtr is set. - // It is used to make sure mojo calls are done on a right sequence. - scoped_refptr<base::SingleThreadTaskRunner> ui_runner_; - - DISALLOW_COPY_AND_ASSIGN(WaylandConnectionProxy); -}; - -} // namespace ui - -#endif // UI_OZONE_PLATFORM_WAYLAND_GPU_WAYLAND_CONNECTION_PROXY_H_
diff --git a/ui/ozone/platform/wayland/ozone_platform_wayland.cc b/ui/ozone/platform/wayland/ozone_platform_wayland.cc index 4476357..1aa07027 100644 --- a/ui/ozone/platform/wayland/ozone_platform_wayland.cc +++ b/ui/ozone/platform/wayland/ozone_platform_wayland.cc
@@ -4,16 +4,13 @@ #include "ui/ozone/platform/wayland/ozone_platform_wayland.h" -#include "base/memory/ptr_util.h" #include "ui/base/cursor/ozone/bitmap_cursor_factory_ozone.h" #include "ui/base/ui_features.h" #include "ui/display/manager/fake_display_delegate.h" #include "ui/events/ozone/layout/keyboard_layout_engine_manager.h" #include "ui/events/system_input_injector.h" #include "ui/ozone/common/stub_overlay_manager.h" -#include "ui/ozone/platform/wayland/gpu/wayland_connection_proxy.h" #include "ui/ozone/platform/wayland/wayland_connection.h" -#include "ui/ozone/platform/wayland/wayland_connection_connector.h" #include "ui/ozone/platform/wayland/wayland_native_display_delegate.h" #include "ui/ozone/platform/wayland/wayland_surface_factory.h" #include "ui/ozone/platform/wayland/wayland_window.h" @@ -29,12 +26,6 @@ #include "ui/events/ozone/layout/stub/stub_keyboard_layout_engine.h" #endif -#if defined(WAYLAND_GBM) -#include "ui/ozone/common/linux/gbm_wrapper.h" -#include "ui/ozone/platform/wayland/gpu/drm_render_node_handle.h" -#include "ui/ozone/platform/wayland/gpu/drm_render_node_path_finder.h" -#endif - namespace ui { namespace { @@ -70,7 +61,7 @@ } GpuPlatformSupportHost* GetGpuPlatformSupportHost() override { - return connector_ ? connector_.get() : gpu_platform_support_host_.get(); + return gpu_platform_support_host_.get(); } std::unique_ptr<SystemInputInjector> CreateSystemInputInjector() override { @@ -104,63 +95,33 @@ if (!connection_->Initialize()) LOG(FATAL) << "Failed to initialize Wayland platform"; -#if defined(WAYLAND_GBM) - if (!args.single_process) - connector_.reset(new WaylandConnectionConnector(connection_.get())); -#endif - cursor_factory_.reset(new BitmapCursorFactoryOzone); overlay_manager_.reset(new StubOverlayManager); input_controller_ = CreateStubInputController(); + surface_factory_.reset(new WaylandSurfaceFactory(connection_.get())); gpu_platform_support_host_.reset(CreateStubGpuPlatformSupportHost()); } void InitializeGPU(const InitParams& args) override { - if (!args.single_process) { - proxy_.reset(new WaylandConnectionProxy(nullptr)); -#if defined(WAYLAND_GBM) - DrmRenderNodePathFinder path_finder; - const base::FilePath drm_node_path = path_finder.GetDrmRenderNodePath(); - if (drm_node_path.empty()) - LOG(FATAL) << "Failed to find drm render node path."; - - DrmRenderNodeHandle handle; - if (!handle.Initialize(drm_node_path)) - LOG(FATAL) << "Failed to initialize drm render node handle."; - - auto gbm = CreateGbmDevice(handle.PassFD().release()); - if (!gbm) - LOG(FATAL) << "Failed to initialize gbm device."; - - proxy_->set_gbm_device(std::move(gbm)); -#endif - } else { - proxy_.reset(new WaylandConnectionProxy(connection_.get())); + // TODO(fwang): args.single_process parameter should be checked here; make + // sure callers pass in the proper value. Once it happens, the check whether + // surface factory was set in the same process by a previous InitializeUI + // call becomes unneeded. + if (!surface_factory_) { + // TODO(fwang): Separate processes can not share a Wayland connection + // and so the current implementations of GLOzoneEGLWayland and + // WaylandCanvasSurface may only work when UI and GPU live in the same + // process. GetSurfaceFactoryOzone() must be non-null so a dummy instance + // of WaylandSurfaceFactory is needed to make the GPU initialization + // gracefully fail. + surface_factory_.reset(new WaylandSurfaceFactory(nullptr)); } - surface_factory_.reset(new WaylandSurfaceFactory(proxy_.get())); } const PlatformProperties& GetPlatformProperties() override { - DCHECK(connection_.get()); - if (properties_.supported_buffer_formats.empty()) { - properties_.supported_buffer_formats = - connection_->GetSupportedBufferFormats(); - } return properties_; } - void AddInterfaces(service_manager::BinderRegistry* registry) override { - registry->AddInterface<ozone::mojom::WaylandConnectionClient>( - base::BindRepeating( - &OzonePlatformWayland::CreateWaylandConnectionClientBinding, - base::Unretained(this))); - } - - void CreateWaylandConnectionClientBinding( - ozone::mojom::WaylandConnectionClientRequest request) { - proxy_->AddBindingWaylandConnectionClient(std::move(request)); - } - private: std::unique_ptr<WaylandConnection> connection_; std::unique_ptr<WaylandSurfaceFactory> surface_factory_; @@ -173,9 +134,6 @@ XkbEvdevCodes xkb_evdev_code_converter_; #endif - std::unique_ptr<WaylandConnectionProxy> proxy_; - std::unique_ptr<WaylandConnectionConnector> connector_; - PlatformProperties properties_; DISALLOW_COPY_AND_ASSIGN(OzonePlatformWayland);
diff --git a/ui/ozone/platform/wayland/wayland.gni b/ui/ozone/platform/wayland/wayland.gni deleted file mode 100644 index 8cfdc4c..0000000 --- a/ui/ozone/platform/wayland/wayland.gni +++ /dev/null
@@ -1,12 +0,0 @@ -# Copyright 2018 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. - -import("//build/config/ui.gni") -import("//ui/ozone/ozone.gni") - -declare_args() { - # Checks if Wayland must be compiled with dmabuf/gbm feature, which allows a - # multi-process hardware accelerated mode. - use_wayland_gbm = true -}
diff --git a/ui/ozone/platform/wayland/wayland_connection.cc b/ui/ozone/platform/wayland/wayland_connection.cc index 4718cf2..b31e91e 100644 --- a/ui/ozone/platform/wayland/wayland_connection.cc +++ b/ui/ozone/platform/wayland/wayland_connection.cc
@@ -4,9 +4,6 @@ #include "ui/ozone/platform/wayland/wayland_connection.h" -#include <drm_fourcc.h> - -#include <linux-dmabuf-unstable-v1-client-protocol.h> #include <xdg-shell-unstable-v5-client-protocol.h> #include <xdg-shell-unstable-v6-client-protocol.h> @@ -17,8 +14,6 @@ #include "base/message_loop/message_loop_current.h" #include "base/strings/string_util.h" #include "base/threading/thread_task_runner_handle.h" -#include "base/trace_event/trace_event.h" -#include "ui/ozone/common/linux/drm_util_linux.h" #include "ui/ozone/platform/wayland/wayland_object.h" #include "ui/ozone/platform/wayland/wayland_window.h" @@ -27,18 +22,15 @@ namespace ui { namespace { const uint32_t kMaxCompositorVersion = 4; -const uint32_t kMaxLinuxDmabufVersion = 1; const uint32_t kMaxSeatVersion = 4; const uint32_t kMaxShmVersion = 1; const uint32_t kMaxXdgShellVersion = 1; } // namespace -WaylandConnection::WaylandConnection() - : controller_(FROM_HERE), binding_(this) {} +WaylandConnection::WaylandConnection() : controller_(FROM_HERE) {} WaylandConnection::~WaylandConnection() { - DCHECK(pending_buffer_map_.empty() && params_to_id_map_.empty() && - buffers_.empty()); + DCHECK(window_map_.empty()); } bool WaylandConnection::Initialize() { @@ -155,154 +147,10 @@ return modifiers; } -// TODO(msisov): handle buffer swap failure or success. -void WaylandConnection::ScheduleBufferSwap(gfx::AcceleratedWidget widget, - uint32_t buffer_id) { - DCHECK(base::MessageLoopForUI::IsCurrent()); - if (!ValidateDataFromGpu(widget, buffer_id)) - return; - - auto it = buffers_.find(buffer_id); - // A buffer might not exist by this time. So, store the request and process - // it once it is created. - if (it == buffers_.end()) { - auto pending_buffers_it = pending_buffer_map_.find(buffer_id); - if (pending_buffers_it != pending_buffer_map_.end()) { - // If a buffer didn't exist and second call for a swap comes, buffer must - // be associated with the same widget. - DCHECK_EQ(pending_buffers_it->second, widget); - } else { - pending_buffer_map_.insert( - std::pair<uint32_t, gfx::AcceleratedWidget>(buffer_id, widget)); - } - return; - } - struct wl_buffer* buffer = it->second.get(); - - WaylandWindow* window = GetWindow(widget); - if (!window) - return; - - // TODO(msisov): it would be beneficial to use real damage regions to improve - // performance. - // - // TODO(msisov): also start using wl_surface_frame callbacks for better - // performance. - wl_surface_damage(window->surface(), 0, 0, window->GetBounds().width(), - window->GetBounds().height()); - wl_surface_attach(window->surface(), buffer, 0, 0); - wl_surface_commit(window->surface()); - - ScheduleFlush(); -} - -void WaylandConnection::CreateZwpLinuxDmabuf( - base::File file, - uint32_t width, - uint32_t height, - const std::vector<uint32_t>& strides, - const std::vector<uint32_t>& offsets, - uint32_t format, - const std::vector<uint64_t>& modifiers, - uint32_t planes_count, - uint32_t buffer_id) { - TRACE_EVENT2("Wayland", "WaylandConnection::CreateZwpLinuxDmabuf", "Format", - format, "Buffer id", buffer_id); - - static const struct zwp_linux_buffer_params_v1_listener params_listener = { - WaylandConnection::CreateSucceeded, WaylandConnection::CreateFailed}; - - DCHECK(base::MessageLoopForUI::IsCurrent()); - if (!ValidateDataFromGpu(file, width, height, strides, offsets, format, - modifiers, planes_count, buffer_id)) { - // base::File::Close() has an assertion that checks if blocking operations - // are allowed. Thus, manually close the fd here. - base::ScopedFD fd(file.TakePlatformFile()); - fd.reset(); - return; - } - - // Store |params| connected to |buffer_id| to track buffer creation and - // identify, which buffer a client wants to use. - struct zwp_linux_buffer_params_v1* params = - zwp_linux_dmabuf_v1_create_params(zwp_linux_dmabuf()); - params_to_id_map_.insert( - std::pair<struct zwp_linux_buffer_params_v1*, uint32_t>(params, - buffer_id)); - uint32_t fd = file.TakePlatformFile(); - for (size_t i = 0; i < planes_count; i++) { - zwp_linux_buffer_params_v1_add(params, fd, i /* plane id */, offsets[i], - strides[i], 0 /* modifier hi */, - 0 /* modifier lo */); - } - zwp_linux_buffer_params_v1_add_listener(params, ¶ms_listener, this); - zwp_linux_buffer_params_v1_create(params, width, height, format, 0); - - ScheduleFlush(); -} - -void WaylandConnection::DestroyZwpLinuxDmabuf(uint32_t buffer_id) { - TRACE_EVENT1("Wayland", "WaylandConnection::DestroyZwpLinuxDmabuf", - "Buffer id", buffer_id); - - DCHECK(base::MessageLoopForUI::IsCurrent()); - - auto it = buffers_.find(buffer_id); - if (it == buffers_.end()) { - TerminateGpuProcess("Trying to destroy non-existing buffer"); - return; - } - buffers_.erase(it); - - ScheduleFlush(); -} - ClipboardDelegate* WaylandConnection::GetClipboardDelegate() { return this; } -// static -void WaylandConnection::CreateSucceeded( - void* data, - struct zwp_linux_buffer_params_v1* params, - struct wl_buffer* new_buffer) { - DCHECK(base::MessageLoopForUI::IsCurrent()); - - WaylandConnection* connection = static_cast<WaylandConnection*>(data); - DCHECK(connection); - - // Find which buffer id |params| belong to and store wl_buffer - // with that id. - auto it = connection->params_to_id_map_.find(params); - CHECK(it != connection->params_to_id_map_.end()); - uint32_t buffer_id = it->second; - connection->params_to_id_map_.erase(params); - zwp_linux_buffer_params_v1_destroy(params); - - connection->buffers_.insert(std::pair<uint32_t, wl::Object<wl_buffer>>( - buffer_id, wl::Object<wl_buffer>(new_buffer))); - - TRACE_EVENT1("Wayland", "WaylandConnection::CreateSucceeded", "Buffer id", - buffer_id); - - auto pending_buffers_it = connection->pending_buffer_map_.find(buffer_id); - if (pending_buffers_it != connection->pending_buffer_map_.end()) { - gfx::AcceleratedWidget widget = pending_buffers_it->second; - connection->pending_buffer_map_.erase(pending_buffers_it); - connection->ScheduleBufferSwap(widget, buffer_id); - } -} - -// static -void WaylandConnection::CreateFailed( - void* data, - struct zwp_linux_buffer_params_v1* params) { - DCHECK(base::MessageLoopForUI::IsCurrent()); - - zwp_linux_buffer_params_v1_destroy(params); - LOG(FATAL) << "zwp_linux_buffer_params.create failed"; -} - void WaylandConnection::OfferClipboardData( const ClipboardDelegate::DataMap& data_map, ClipboardDelegate::OfferDataClosure callback) { @@ -331,24 +179,6 @@ return !!data_source_; } -ozone::mojom::WaylandConnectionPtr WaylandConnection::BindInterface() { - // This mustn't be called twice or when the zwp_linux_dmabuf interface is not - // available. - DCHECK(!binding_.is_bound() || zwp_linux_dmabuf_); - ozone::mojom::WaylandConnectionPtr ptr; - binding_.Bind(MakeRequest(&ptr)); - return ptr; -} - -std::vector<gfx::BufferFormat> WaylandConnection::GetSupportedBufferFormats() { - return buffer_formats_; -} - -void WaylandConnection::SetTerminateGpuCallback( - base::OnceCallback<void(std::string)> terminate_callback) { - terminate_gpu_cb_ = std::move(terminate_callback); -} - void WaylandConnection::GetAvailableMimeTypes( ClipboardDelegate::GetMimeTypesClosure callback) { std::move(callback).Run(data_device_->GetAvailableMimeTypes()); @@ -396,81 +226,6 @@ void WaylandConnection::OnFileCanWriteWithoutBlocking(int fd) {} -bool WaylandConnection::ValidateDataFromGpu( - const base::File& file, - uint32_t width, - uint32_t height, - const std::vector<uint32_t>& strides, - const std::vector<uint32_t>& offsets, - uint32_t format, - const std::vector<uint64_t>& modifiers, - uint32_t planes_count, - uint32_t buffer_id) { - std::string reason; - if (!file.IsValid()) - reason = "Buffer fd is invalid"; - - if (width == 0 || height == 0) - reason = "Buffer size is invalid"; - - if (planes_count < 1) - reason = "Planes count cannot be less than 1"; - - if (planes_count != strides.size() || planes_count != offsets.size() || - planes_count != modifiers.size()) { - reason = "Number of strides(" + std::to_string(strides.size()) + - ")/offsets(" + std::to_string(offsets.size()) + ")/modifiers(" + - std::to_string(modifiers.size()) + - ") does not correspond to the number of planes(" + - std::to_string(planes_count) + ")"; - } - - for (auto stride : strides) { - if (stride == 0) - reason = "Strides are invalid"; - } - - if (!IsValidBufferFormat(format)) - reason = "Buffer format is invalid"; - - if (buffer_id < 1) - reason = "Invalid buffer id: " + std::to_string(buffer_id); - - if (!reason.empty()) { - TerminateGpuProcess(reason); - return false; - } - return true; -} - -bool WaylandConnection::ValidateDataFromGpu( - const gfx::AcceleratedWidget& widget, - uint32_t buffer_id) { - std::string reason; - - if (widget == gfx::kNullAcceleratedWidget) - reason = "Invalid accelerated widget"; - - if (buffer_id < 1) - reason = "Invalid buffer id: " + std::to_string(buffer_id); - - if (!reason.empty()) { - TerminateGpuProcess(reason); - return false; - } - - return true; -} - -void WaylandConnection::TerminateGpuProcess(std::string reason) { - std::move(terminate_gpu_cb_).Run(std::move(reason)); - binding_.Unbind(); - - buffers_.clear(); - params_to_id_map_.clear(); - pending_buffer_map_.clear(); -} - const std::vector<std::unique_ptr<WaylandOutput>>& WaylandConnection::GetOutputList() const { return output_list_; @@ -491,9 +246,6 @@ static const zxdg_shell_v6_listener shell_v6_listener = { &WaylandConnection::PingV6, }; - static const zwp_linux_dmabuf_v1_listener dmabuf_listener = { - &WaylandConnection::Format, &WaylandConnection::Modifiers, - }; WaylandConnection* connection = static_cast<WaylandConnection*>(data); if (!connection->compositor_ && strcmp(interface, "wl_compositor") == 0) { @@ -578,15 +330,6 @@ connection->data_device_manager_.reset( new WaylandDataDeviceManager(data_device_manager.release())); connection->data_device_manager_->set_connection(connection); - } else if (!connection->zwp_linux_dmabuf_ && - (strcmp(interface, "zwp_linux_dmabuf_v1") == 0)) { - connection->zwp_linux_dmabuf_ = wl::Bind<zwp_linux_dmabuf_v1>( - registry, name, std::min(version, kMaxLinuxDmabufVersion)); - zwp_linux_dmabuf_v1_add_listener(connection->zwp_linux_dmabuf(), - &dmabuf_listener, connection); - // A roundtrip after binding guarantees that the client has received all - // supported formats. - wl_display_roundtrip(connection->display_.get()); } connection->ScheduleFlush(); @@ -671,25 +414,4 @@ connection->ScheduleFlush(); } -// static -void WaylandConnection::Modifiers(void* data, - struct zwp_linux_dmabuf_v1* zwp_linux_dmabuf, - uint32_t format, - uint32_t modifier_hi, - uint32_t modifier_lo) { - NOTIMPLEMENTED(); -} - -// static -void WaylandConnection::Format(void* data, - struct zwp_linux_dmabuf_v1* zwp_linux_dmabuf, - uint32_t format) { - WaylandConnection* connection = static_cast<WaylandConnection*>(data); - // Return on not the supported ARGB format. - if (format == DRM_FORMAT_ARGB2101010) - return; - connection->buffer_formats_.push_back( - GetBufferFormatFromFourCCFormat(format)); -} - } // namespace ui
diff --git a/ui/ozone/platform/wayland/wayland_connection.h b/ui/ozone/platform/wayland/wayland_connection.h index ad3543d..e617c86d 100644 --- a/ui/ozone/platform/wayland/wayland_connection.h +++ b/ui/ozone/platform/wayland/wayland_connection.h
@@ -7,11 +7,7 @@ #include <map> -#include "ui/gfx/buffer_types.h" - -#include "base/files/file.h" #include "base/message_loop/message_pump_libevent.h" -#include "mojo/public/cpp/bindings/binding.h" #include "ui/events/platform/platform_event_source.h" #include "ui/gfx/native_widget_types.h" #include "ui/ozone/platform/wayland/wayland_data_device.h" @@ -23,11 +19,6 @@ #include "ui/ozone/platform/wayland/wayland_pointer.h" #include "ui/ozone/platform/wayland/wayland_touch.h" #include "ui/ozone/public/clipboard_delegate.h" -#include "ui/ozone/public/gpu_platform_support_host.h" -#include "ui/ozone/public/interfaces/wayland/wayland_connection.mojom.h" - -struct zwp_linux_dmabuf_v1; -struct zwp_linux_buffer_params_v1; namespace ui { @@ -35,7 +26,6 @@ class WaylandConnection : public PlatformEventSource, public ClipboardDelegate, - public ozone::mojom::WaylandConnection, public base::MessagePumpLibevent::FdWatcher { public: WaylandConnection(); @@ -44,28 +34,6 @@ bool Initialize(); bool StartProcessingEvents(); - // ozone::mojom::WaylandConnection overrides: - // - // The overridden methods below are invoked by GPU. - // - // Called by the GPU and asks to import a wl_buffer based on a gbm file - // descriptor. - void CreateZwpLinuxDmabuf(base::File file, - uint32_t width, - uint32_t height, - const std::vector<uint32_t>& strides, - const std::vector<uint32_t>& offsets, - uint32_t format, - const std::vector<uint64_t>& modifiers, - uint32_t planes_count, - uint32_t buffer_id) override; - // Called by the GPU to destroy the imported wl_buffer with a |buffer_id|. - void DestroyZwpLinuxDmabuf(uint32_t buffer_id) override; - // Called by the GPU and asks to attach a wl_buffer with a |buffer_id| to a - // WaylandWindow with the specified |widget|. - void ScheduleBufferSwap(gfx::AcceleratedWidget widget, - uint32_t buffer_id) override; - // Schedules a flush of the Wayland connection. void ScheduleFlush(); @@ -77,7 +45,6 @@ zxdg_shell_v6* shell_v6() { return shell_v6_.get(); } wl_seat* seat() { return seat_.get(); } wl_data_device* data_device() { return data_device_->data_device(); } - zwp_linux_dmabuf_v1* zwp_linux_dmabuf() { return zwp_linux_dmabuf_.get(); } WaylandWindow* GetWindow(gfx::AcceleratedWidget widget); WaylandWindow* GetCurrentFocusedWindow(); @@ -117,14 +84,6 @@ ClipboardDelegate::GetMimeTypesClosure callback) override; bool IsSelectionOwner() override; - // Returns bound pointer to own mojo interface. - ozone::mojom::WaylandConnectionPtr BindInterface(); - - std::vector<gfx::BufferFormat> GetSupportedBufferFormats(); - - void SetTerminateGpuCallback( - base::OnceCallback<void(std::string)> terminate_gpu_cb); - private: void Flush(); void DispatchUiEvent(Event* event); @@ -136,22 +95,6 @@ void OnFileCanReadWithoutBlocking(int fd) override; void OnFileCanWriteWithoutBlocking(int fd) override; - // Validates data sent by the GPU. If anything, terminates the gpu process. - bool ValidateDataFromGpu(const base::File& file, - uint32_t width, - uint32_t height, - const std::vector<uint32_t>& strides, - const std::vector<uint32_t>& offsets, - uint32_t format, - const std::vector<uint64_t>& modifiers, - uint32_t planes_count, - uint32_t buffer_id); - bool ValidateDataFromGpu(const gfx::AcceleratedWidget& widget, - uint32_t buffer_id); - - // Terminates the GPU process on invalid data received - void TerminateGpuProcess(std::string reason); - // wl_registry_listener static void Global(void* data, wl_registry* registry, @@ -170,22 +113,6 @@ // xdg_shell_listener static void Ping(void* data, xdg_shell* shell, uint32_t serial); - // zwp_linux_dmabuf_v1_listener - static void Modifiers(void* data, - struct zwp_linux_dmabuf_v1* zwp_linux_dmabuf, - uint32_t format, - uint32_t modifier_hi, - uint32_t modifier_lo); - static void Format(void* data, - struct zwp_linux_dmabuf_v1* zwp_linux_dmabuf, - uint32_t format); - - static void CreateSucceeded(void* data, - struct zwp_linux_buffer_params_v1* params, - struct wl_buffer* new_buffer); - static void CreateFailed(void* data, - struct zwp_linux_buffer_params_v1* params); - std::map<gfx::AcceleratedWidget, WaylandWindow*> window_map_; wl::Object<wl_display> display_; @@ -195,23 +122,8 @@ wl::Object<wl_seat> seat_; wl::Object<wl_shm> shm_; wl::Object<xdg_shell> shell_; - wl::Object<zwp_linux_dmabuf_v1> zwp_linux_dmabuf_; wl::Object<zxdg_shell_v6> shell_v6_; - // Stores a wl_buffer and it's id provided by the GbmBuffer object on the - // GPU process side. - base::flat_map<uint32_t, wl::Object<wl_buffer>> buffers_; - // A temporary params-to-buffer id map, which is used to identify which - // id wl_buffer should be assigned when storing it in the |buffers_| map - // during CreateSucceeded call. - base::flat_map<struct zwp_linux_buffer_params_v1*, uint32_t> - params_to_id_map_; - // It might happen that GPU asks to swap buffers, when a wl_buffer hasn't - // been created yet. Thus, store the request in a pending map. Once buffer - // is created, it will be attached to requested WaylandWindow based on the - // gfx::AcceleratedWidget. - base::flat_map<uint32_t, gfx::AcceleratedWidget> pending_buffer_map_; - std::unique_ptr<WaylandDataDeviceManager> data_device_manager_; std::unique_ptr<WaylandDataDevice> data_device_; std::unique_ptr<WaylandDataSource> data_source_; @@ -235,14 +147,6 @@ // Stores the callback to be invoked upon data reading from clipboard. RequestDataClosure read_clipboard_closure_; - mojo::Binding<ozone::mojom::WaylandConnection> binding_; - - std::vector<gfx::BufferFormat> buffer_formats_; - - // A callback, which is used to terminate a GPU process in case of invalid - // data sent by the GPU to the browser process. - base::OnceCallback<void(std::string)> terminate_gpu_cb_; - DISALLOW_COPY_AND_ASSIGN(WaylandConnection); };
diff --git a/ui/ozone/platform/wayland/wayland_connection_connector.cc b/ui/ozone/platform/wayland/wayland_connection_connector.cc deleted file mode 100644 index cee7bb4..0000000 --- a/ui/ozone/platform/wayland/wayland_connection_connector.cc +++ /dev/null
@@ -1,92 +0,0 @@ -// Copyright 2018 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 "ui/ozone/platform/wayland/wayland_connection_connector.h" - -#include "base/task_runner_util.h" -#include "ui/ozone/platform/wayland/wayland_connection.h" -#include "ui/ozone/public/interfaces/wayland/wayland_connection.mojom.h" - -namespace ui { - -namespace { - -// TODO(msisov): In the future when GpuProcessHost is moved to vizhost, remove -// this utility code. -using BinderCallback = ui::GpuPlatformSupportHost::GpuHostBindInterfaceCallback; - -void BindInterfaceInGpuProcess(const std::string& interface_name, - mojo::ScopedMessagePipeHandle interface_pipe, - const BinderCallback& binder_callback) { - return binder_callback.Run(interface_name, std::move(interface_pipe)); -} - -template <typename Interface> -void BindInterfaceInGpuProcess(mojo::InterfaceRequest<Interface> request, - const BinderCallback& binder_callback) { - BindInterfaceInGpuProcess( - Interface::Name_, std::move(request.PassMessagePipe()), binder_callback); -} - -} // namespace - -WaylandConnectionConnector::WaylandConnectionConnector( - WaylandConnection* connection) - : connection_(connection) {} - -WaylandConnectionConnector::~WaylandConnectionConnector() = default; - -void WaylandConnectionConnector::OnGpuProcessLaunched( - int host_id, - scoped_refptr<base::SingleThreadTaskRunner> ui_runner, - scoped_refptr<base::SingleThreadTaskRunner> send_runner, - const base::RepeatingCallback<void(IPC::Message*)>& send_callback) {} - -void WaylandConnectionConnector::OnChannelDestroyed(int host_id) { - // TODO(msisov): Handle restarting. - NOTIMPLEMENTED(); -} - -void WaylandConnectionConnector::OnMessageReceived( - const IPC::Message& message) { - NOTREACHED() << "This class should only be used with mojo transport but here " - "we're wrongly getting invoked to handle IPC communication."; -} - -void WaylandConnectionConnector::OnGpuServiceLaunched( - scoped_refptr<base::SingleThreadTaskRunner> ui_runner, - scoped_refptr<base::SingleThreadTaskRunner> io_runner, - GpuHostBindInterfaceCallback binder, - GpuHostTerminateCallback terminate_callback) { - terminate_callback_ = std::move(terminate_callback); - binder_ = std::move(binder); - - io_runner_ = io_runner; - auto on_terminate_gpu_cb = - base::BindOnce(&WaylandConnectionConnector::OnTerminateGpuProcess, - base::Unretained(this)); - connection_->SetTerminateGpuCallback(std::move(on_terminate_gpu_cb)); - - base::PostTaskAndReplyWithResult( - ui_runner.get(), FROM_HERE, - base::BindOnce(&WaylandConnection::BindInterface, - base::Unretained(connection_)), - base::BindOnce(&WaylandConnectionConnector::OnWaylandConnectionPtrBinded, - base::Unretained(this))); -} - -void WaylandConnectionConnector::OnWaylandConnectionPtrBinded( - ozone::mojom::WaylandConnectionPtr wc_ptr) const { - ozone::mojom::WaylandConnectionClientPtr wcp_ptr; - auto request = mojo::MakeRequest(&wcp_ptr); - BindInterfaceInGpuProcess(std::move(request), binder_); - wcp_ptr->SetWaylandConnection(std::move(wc_ptr)); -} - -void WaylandConnectionConnector::OnTerminateGpuProcess(std::string message) { - io_runner_->PostTask(FROM_HERE, base::BindOnce(std::move(terminate_callback_), - std::move(message))); -} - -} // namespace ui
diff --git a/ui/ozone/platform/wayland/wayland_connection_connector.h b/ui/ozone/platform/wayland/wayland_connection_connector.h deleted file mode 100644 index c8941ed..0000000 --- a/ui/ozone/platform/wayland/wayland_connection_connector.h +++ /dev/null
@@ -1,59 +0,0 @@ -// Copyright 2018 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 UI_OZONE_PLATFORM_WAYLAND_WAYLAND_CONNECTION_CONNECTOR_H_ -#define UI_OZONE_PLATFORM_WAYLAND_WAYLAND_CONNECTION_CONNECTOR_H_ - -#include "ui/ozone/public/gpu_platform_support_host.h" - -#include "ui/ozone/public/interfaces/wayland/wayland_connection.mojom.h" - -namespace ui { - -class WaylandConnection; - -// A connector class, which instantiates a connection between -// WaylandConnectionProxy on the GPU side and the WaylandConnection object on -// the browser process side. -class WaylandConnectionConnector : public GpuPlatformSupportHost { - public: - WaylandConnectionConnector(WaylandConnection* connection); - ~WaylandConnectionConnector() override; - - // GpuPlatformSupportHost: - void OnGpuProcessLaunched( - int host_id, - scoped_refptr<base::SingleThreadTaskRunner> ui_runner, - scoped_refptr<base::SingleThreadTaskRunner> send_runner, - const base::RepeatingCallback<void(IPC::Message*)>& send_callback) - override; - void OnChannelDestroyed(int host_id) override; - void OnMessageReceived(const IPC::Message& message) override; - void OnGpuServiceLaunched( - scoped_refptr<base::SingleThreadTaskRunner> ui_runner, - scoped_refptr<base::SingleThreadTaskRunner> io_runner, - GpuHostBindInterfaceCallback binder, - GpuHostTerminateCallback terminate_callback) override; - - private: - void OnWaylandConnectionPtrBinded( - ozone::mojom::WaylandConnectionPtr wc_ptr) const; - - void OnTerminateGpuProcess(std::string message); - - // Non-owning pointer, which is used to bind a mojo pointer to the - // WaylandConnection. - WaylandConnection* connection_ = nullptr; - - GpuHostBindInterfaceCallback binder_; - GpuHostTerminateCallback terminate_callback_; - - scoped_refptr<base::SingleThreadTaskRunner> io_runner_; - - DISALLOW_COPY_AND_ASSIGN(WaylandConnectionConnector); -}; - -} // namespace ui - -#endif // UI_OZONE_PLATFORM_WAYLAND_WAYLAND_CONNECTION_CONNECTOR_H_
diff --git a/ui/ozone/platform/wayland/wayland_object.cc b/ui/ozone/platform/wayland/wayland_object.cc index ec41d32..c9ec781 100644 --- a/ui/ozone/platform/wayland/wayland_object.cc +++ b/ui/ozone/platform/wayland/wayland_object.cc
@@ -4,7 +4,6 @@ #include "ui/ozone/platform/wayland/wayland_object.h" -#include <linux-dmabuf-unstable-v1-client-protocol.h> #include <wayland-client.h> #include <xdg-shell-unstable-v5-client-protocol.h> #include <xdg-shell-unstable-v6-client-protocol.h> @@ -127,11 +126,6 @@ const wl_interface* ObjectTraits<xdg_popup>::interface = &xdg_popup_interface; void (*ObjectTraits<xdg_popup>::deleter)(xdg_popup*) = &xdg_popup_destroy; -const wl_interface* ObjectTraits<zwp_linux_dmabuf_v1>::interface = - &zwp_linux_dmabuf_v1_interface; -void (*ObjectTraits<zwp_linux_dmabuf_v1>::deleter)(zwp_linux_dmabuf_v1*) = - &zwp_linux_dmabuf_v1_destroy; - const wl_interface* ObjectTraits<zxdg_shell_v6>::interface = &zxdg_shell_v6_interface; void (*ObjectTraits<zxdg_shell_v6>::deleter)(zxdg_shell_v6*) =
diff --git a/ui/ozone/platform/wayland/wayland_object.h b/ui/ozone/platform/wayland/wayland_object.h index df3f16e..6924c4a 100644 --- a/ui/ozone/platform/wayland/wayland_object.h +++ b/ui/ozone/platform/wayland/wayland_object.h
@@ -30,7 +30,6 @@ struct xdg_shell; struct xdg_surface; struct xdg_popup; -struct zwp_linux_dmabuf_v1; struct zxdg_shell_v6; struct zxdg_surface_v6; struct zxdg_toplevel_v6; @@ -175,12 +174,6 @@ }; template <> -struct ObjectTraits<zwp_linux_dmabuf_v1> { - static const wl_interface* interface; - static void (*deleter)(zwp_linux_dmabuf_v1*); -}; - -template <> struct ObjectTraits<zxdg_shell_v6> { static const wl_interface* interface; static void (*deleter)(zxdg_shell_v6*);
diff --git a/ui/ozone/platform/wayland/wayland_surface_factory.cc b/ui/ozone/platform/wayland/wayland_surface_factory.cc index 805d4608..6e9834e 100644 --- a/ui/ozone/platform/wayland/wayland_surface_factory.cc +++ b/ui/ozone/platform/wayland/wayland_surface_factory.cc
@@ -15,16 +15,11 @@ #include "ui/ozone/common/egl_util.h" #include "ui/ozone/common/gl_ozone_egl.h" #include "ui/ozone/platform/wayland/gl_surface_wayland.h" -#include "ui/ozone/platform/wayland/gpu/wayland_connection_proxy.h" +#include "ui/ozone/platform/wayland/wayland_connection.h" #include "ui/ozone/platform/wayland/wayland_object.h" #include "ui/ozone/platform/wayland/wayland_window.h" #include "ui/ozone/public/surface_ozone_canvas.h" -#if defined(WAYLAND_GBM) -#include "ui/ozone/platform/wayland/gpu/gbm_pixmap_wayland.h" -#include "ui/ozone/platform/wayland/gpu/gbm_surfaceless_wayland.h" -#endif - namespace ui { static void DeleteSharedMemory(void* pixels, void* context) { @@ -33,8 +28,7 @@ class WaylandCanvasSurface : public SurfaceOzoneCanvas { public: - WaylandCanvasSurface(WaylandConnectionProxy* connection, - WaylandWindow* window_); + WaylandCanvasSurface(WaylandConnection* connection, WaylandWindow* window_); ~WaylandCanvasSurface() override; // SurfaceOzoneCanvas @@ -44,7 +38,7 @@ std::unique_ptr<gfx::VSyncProvider> CreateVSyncProvider() override; private: - WaylandConnectionProxy* connection_; + WaylandConnection* connection_; WaylandWindow* window_; gfx::Size size_; @@ -55,7 +49,7 @@ DISALLOW_COPY_AND_ASSIGN(WaylandCanvasSurface); }; -WaylandCanvasSurface::WaylandCanvasSurface(WaylandConnectionProxy* connection, +WaylandCanvasSurface::WaylandCanvasSurface(WaylandConnection* connection, WaylandWindow* window) : connection_(connection), window_(window), @@ -134,27 +128,13 @@ class GLOzoneEGLWayland : public GLOzoneEGL { public: - GLOzoneEGLWayland(WaylandConnectionProxy* connection, - WaylandSurfaceFactory* surface_factory) - : connection_(connection), surface_factory_(surface_factory) {} + explicit GLOzoneEGLWayland(WaylandConnection* connection) + : connection_(connection) {} ~GLOzoneEGLWayland() override {} scoped_refptr<gl::GLSurface> CreateViewGLSurface( gfx::AcceleratedWidget widget) override; - scoped_refptr<gl::GLSurface> CreateSurfacelessViewGLSurface( - gfx::AcceleratedWidget window) override { -#if defined(WAYLAND_GBM) - // If there is a gbm device available, use surfaceless gl surface. - if (!connection_->gbm_device()) - return nullptr; - return gl::InitializeGLSurface( - new GbmSurfacelessWayland(surface_factory_, window)); -#else - return nullptr; -#endif - } - scoped_refptr<gl::GLSurface> CreateOffscreenGLSurface( const gfx::Size& size) override; @@ -163,8 +143,7 @@ bool LoadGLES2Bindings(gl::GLImplementation impl) override; private: - WaylandConnectionProxy* connection_ = nullptr; - WaylandSurfaceFactory* surface_factory_ = nullptr; + WaylandConnection* connection_; DISALLOW_COPY_AND_ASSIGN(GLOzoneEGLWayland); }; @@ -173,8 +152,7 @@ gfx::AcceleratedWidget widget) { DCHECK(connection_); WaylandWindow* window = connection_->GetWindow(widget); - if (!window) - return nullptr; + DCHECK(window); // The wl_egl_window needs to be created before the GLSurface so it can be // used in the GLSurface constructor. auto egl_window = CreateWaylandEglWindow(window); @@ -194,7 +172,7 @@ } intptr_t GLOzoneEGLWayland::GetNativeDisplay() { - return connection_->Display(); + return reinterpret_cast<intptr_t>(connection_->display()); } bool GLOzoneEGLWayland::LoadGLES2Bindings(gl::GLImplementation impl) { @@ -206,36 +184,14 @@ } // namespace -WaylandSurfaceFactory::WaylandSurfaceFactory(WaylandConnectionProxy* connection) +WaylandSurfaceFactory::WaylandSurfaceFactory(WaylandConnection* connection) : connection_(connection) { if (connection_) - egl_implementation_ = - std::make_unique<GLOzoneEGLWayland>(connection_, this); + egl_implementation_ = std::make_unique<GLOzoneEGLWayland>(connection_); } WaylandSurfaceFactory::~WaylandSurfaceFactory() {} -void WaylandSurfaceFactory::RegisterSurface(gfx::AcceleratedWidget widget, - GbmSurfacelessWayland* surface) { - widget_to_surface_map_.insert(std::make_pair(widget, surface)); -} - -void WaylandSurfaceFactory::UnregisterSurface(gfx::AcceleratedWidget widget) { - widget_to_surface_map_.erase(widget); -} - -GbmSurfacelessWayland* WaylandSurfaceFactory::GetSurface( - gfx::AcceleratedWidget widget) const { - auto it = widget_to_surface_map_.find(widget); - DCHECK(it != widget_to_surface_map_.end()); - return it->second; -} - -void WaylandSurfaceFactory::ScheduleBufferSwap(gfx::AcceleratedWidget widget, - uint32_t buffer_id) { - connection_->ScheduleBufferSwap(widget, buffer_id); -} - std::unique_ptr<SurfaceOzoneCanvas> WaylandSurfaceFactory::CreateCanvasForWidget(gfx::AcceleratedWidget widget) { if (!connection_) @@ -271,15 +227,8 @@ gfx::Size size, gfx::BufferFormat format, gfx::BufferUsage usage) { -#if defined(WAYLAND_GBM) - scoped_refptr<GbmPixmapWayland> pixmap = - base::MakeRefCounted<GbmPixmapWayland>(this, connection_); - if (!pixmap->InitializeBuffer(size, format, usage)) - return nullptr; - return pixmap; -#else + NOTIMPLEMENTED(); return nullptr; -#endif } scoped_refptr<gfx::NativePixmap>
diff --git a/ui/ozone/platform/wayland/wayland_surface_factory.h b/ui/ozone/platform/wayland/wayland_surface_factory.h index 3b569890..f320bc5 100644 --- a/ui/ozone/platform/wayland/wayland_surface_factory.h +++ b/ui/ozone/platform/wayland/wayland_surface_factory.h
@@ -10,28 +10,16 @@ #include "ui/gl/gl_surface.h" #include "ui/ozone/public/surface_factory_ozone.h" -#include "base/posix/eintr_wrapper.h" -#include "base/single_thread_task_runner.h" -#include "base/threading/sequenced_task_runner_handle.h" - namespace ui { -class WaylandConnectionProxy; -class GbmSurfacelessWayland; +class WaylandConnection; class WaylandSurfaceFactory : public SurfaceFactoryOzone { public: - explicit WaylandSurfaceFactory(WaylandConnectionProxy* connection); + explicit WaylandSurfaceFactory(WaylandConnection* connection); ~WaylandSurfaceFactory() override; - // These methods are used, when a dmabuf based approach is used. - void ScheduleBufferSwap(gfx::AcceleratedWidget widget, uint32_t buffer_id); - void RegisterSurface(gfx::AcceleratedWidget widget, - GbmSurfacelessWayland* surface); - void UnregisterSurface(gfx::AcceleratedWidget widget); - GbmSurfacelessWayland* GetSurface(gfx::AcceleratedWidget widget) const; - - // SurfaceFactoryOzone overrides: + // SurfaceFactoryOzone: std::vector<gl::GLImplementation> GetAllowedGLImplementations() override; GLOzone* GetGLOzone(gl::GLImplementation implementation) override; std::unique_ptr<SurfaceOzoneCanvas> CreateCanvasForWidget( @@ -48,12 +36,9 @@ const gfx::NativePixmapHandle& handle) override; private: - WaylandConnectionProxy* connection_ = nullptr; + WaylandConnection* connection_; std::unique_ptr<GLOzone> egl_implementation_; - std::map<gfx::AcceleratedWidget, GbmSurfacelessWayland*> - widget_to_surface_map_; - DISALLOW_COPY_AND_ASSIGN(WaylandSurfaceFactory); };
diff --git a/ui/ozone/platform/wayland/wayland_surface_factory_unittest.cc b/ui/ozone/platform/wayland/wayland_surface_factory_unittest.cc index e1365e7d..ac53749 100644 --- a/ui/ozone/platform/wayland/wayland_surface_factory_unittest.cc +++ b/ui/ozone/platform/wayland/wayland_surface_factory_unittest.cc
@@ -19,7 +19,7 @@ class WaylandSurfaceFactoryTest : public WaylandTest { public: - WaylandSurfaceFactoryTest() : surface_factory(connection_proxy_.get()) {} + WaylandSurfaceFactoryTest() : surface_factory(connection_.get()) {} ~WaylandSurfaceFactoryTest() override {}
diff --git a/ui/ozone/platform/wayland/wayland_test.cc b/ui/ozone/platform/wayland/wayland_test.cc index 8db8147..ff8d382 100644 --- a/ui/ozone/platform/wayland/wayland_test.cc +++ b/ui/ozone/platform/wayland/wayland_test.cc
@@ -29,7 +29,6 @@ std::make_unique<StubKeyboardLayoutEngine>()); #endif connection_.reset(new WaylandConnection); - connection_proxy_.reset(new WaylandConnectionProxy(connection_.get())); window_ = std::make_unique<WaylandWindow>(&delegate_, connection_.get()); }
diff --git a/ui/ozone/platform/wayland/wayland_test.h b/ui/ozone/platform/wayland/wayland_test.h index 26f44a5..20f7dfa4 100644 --- a/ui/ozone/platform/wayland/wayland_test.h +++ b/ui/ozone/platform/wayland/wayland_test.h
@@ -9,7 +9,6 @@ #include "testing/gtest/include/gtest/gtest.h" #include "ui/base/ui_features.h" #include "ui/ozone/platform/wayland/fake_server.h" -#include "ui/ozone/platform/wayland/gpu/wayland_connection_proxy.h" #include "ui/ozone/platform/wayland/wayland_connection.h" #include "ui/ozone/platform/wayland/wayland_window.h" #include "ui/ozone/test/mock_platform_window_delegate.h" @@ -44,7 +43,6 @@ wl::MockSurface* surface_; MockPlatformWindowDelegate delegate_; - std::unique_ptr<WaylandConnectionProxy> connection_proxy_; std::unique_ptr<WaylandConnection> connection_; std::unique_ptr<WaylandWindow> window_; gfx::AcceleratedWidget widget_ = gfx::kNullAcceleratedWidget;
diff --git a/ui/ozone/public/gpu_platform_support_host.cc b/ui/ozone/public/gpu_platform_support_host.cc index 0881946..586186c 100644 --- a/ui/ozone/public/gpu_platform_support_host.cc +++ b/ui/ozone/public/gpu_platform_support_host.cc
@@ -26,8 +26,7 @@ void OnGpuServiceLaunched( scoped_refptr<base::SingleThreadTaskRunner> ui_runner, scoped_refptr<base::SingleThreadTaskRunner> io_runner, - GpuHostBindInterfaceCallback binder, - GpuHostTerminateCallback terminate_callback) override {} + GpuHostBindInterfaceCallback binder) override {} }; } // namespace
diff --git a/ui/ozone/public/gpu_platform_support_host.h b/ui/ozone/public/gpu_platform_support_host.h index 2f81d97..f1120e74 100644 --- a/ui/ozone/public/gpu_platform_support_host.h +++ b/ui/ozone/public/gpu_platform_support_host.h
@@ -30,8 +30,6 @@ using GpuHostBindInterfaceCallback = base::RepeatingCallback<void(const std::string&, mojo::ScopedMessagePipeHandle)>; - using GpuHostTerminateCallback = - base::OnceCallback<void(const std::string& message)>; GpuPlatformSupportHost(); virtual ~GpuPlatformSupportHost(); @@ -57,8 +55,7 @@ virtual void OnGpuServiceLaunched( scoped_refptr<base::SingleThreadTaskRunner> host_runner, scoped_refptr<base::SingleThreadTaskRunner> io_runner, - GpuHostBindInterfaceCallback binder, - GpuHostTerminateCallback terminate_callback) = 0; + GpuHostBindInterfaceCallback binder) = 0; }; // create a stub implementation.
diff --git a/ui/ozone/public/interfaces/wayland/BUILD.gn b/ui/ozone/public/interfaces/wayland/BUILD.gn deleted file mode 100644 index c6f2360d..0000000 --- a/ui/ozone/public/interfaces/wayland/BUILD.gn +++ /dev/null
@@ -1,16 +0,0 @@ -# Copyright 2016 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. - -import("//mojo/public/tools/bindings/mojom.gni") - -mojom("wayland_interfaces") { - sources = [ - "wayland_connection.mojom", - ] - - public_deps = [ - "//mojo/public/mojom/base", - "//ui/gfx/mojo", - ] -}
diff --git a/ui/ozone/public/interfaces/wayland/OWNERS b/ui/ozone/public/interfaces/wayland/OWNERS deleted file mode 100644 index 08850f4..0000000 --- a/ui/ozone/public/interfaces/wayland/OWNERS +++ /dev/null
@@ -1,2 +0,0 @@ -per-file *.mojom=set noparent -per-file *.mojom=file://ipc/SECURITY_OWNERS
diff --git a/ui/ozone/public/interfaces/wayland/wayland_connection.mojom b/ui/ozone/public/interfaces/wayland/wayland_connection.mojom deleted file mode 100644 index fde5b12..0000000 --- a/ui/ozone/public/interfaces/wayland/wayland_connection.mojom +++ /dev/null
@@ -1,36 +0,0 @@ -// Copyright 2018 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. - -module ui.ozone.mojom; - -import "mojo/public/mojom/base/file.mojom"; -import "mojo/public/mojom/base/file_path.mojom"; -import "ui/gfx/mojo/accelerated_widget.mojom"; - -// Used by the GPU for communication with a WaylandConnection on the browser -// process. -interface WaylandConnection { - // Asks Wayland to create a wl_buffer based on the dmabuf |file| descriptor. - CreateZwpLinuxDmabuf(mojo_base.mojom.File file, - uint32 width, - uint32 height, - array<uint32> strides, - array<uint32> offsets, - uint32 format, - array<uint64> modifiers, - uint32 planes_count, - uint32 buffer_id); - - // Destroys a wl_buffer created by WaylandConnection based on the |buffer_id|. - DestroyZwpLinuxDmabuf(uint32 buffer_id); - - // Swaps wl_buffers for a WaylandWindow with the following |widget|. - ScheduleBufferSwap(gfx.mojom.AcceleratedWidget widget, uint32 buffer_id); -}; - -// Used by the browser process to provide the GPU process with a mojo ptr to a -// WaylandConnection, which lives on the browser process. -interface WaylandConnectionClient { - SetWaylandConnection(WaylandConnection wc_ptr); -};
diff --git a/ui/ozone/public/ozone_platform.cc b/ui/ozone/public/ozone_platform.cc index b924a7e8..b496a02 100644 --- a/ui/ozone/public/ozone_platform.cc +++ b/ui/ozone/public/ozone_platform.cc
@@ -22,7 +22,7 @@ base::LazyInstance<base::OnceCallback<void(OzonePlatform*)>>::Leaky instance_callback = LAZY_INSTANCE_INITIALIZER; -const OzonePlatform::PlatformProperties kDefaultPlatformProperties; +constexpr OzonePlatform::PlatformProperties kDefaultPlatformProperties; base::Lock& GetOzoneInstanceLock() { static base::Lock lock; @@ -31,23 +31,6 @@ } // namespace -OzonePlatform::PlatformProperties::PlatformProperties() = default; - -OzonePlatform::PlatformProperties::PlatformProperties( - bool needs_request, - bool custom_frame_default, - bool can_use_system_title_bar, - std::vector<gfx::BufferFormat> buffer_formats) - : needs_view_owner_request(needs_request), - custom_frame_pref_default(custom_frame_default), - use_system_title_bar(can_use_system_title_bar), - supported_buffer_formats(buffer_formats) {} - -OzonePlatform::PlatformProperties::~PlatformProperties() = default; - -OzonePlatform::PlatformProperties::PlatformProperties( - const PlatformProperties& other) = default; - OzonePlatform::OzonePlatform() { GetOzoneInstanceLock().AssertAcquired(); DCHECK(!instance_) << "There should only be a single OzonePlatform.";
diff --git a/ui/ozone/public/ozone_platform.h b/ui/ozone/public/ozone_platform.h index 8d776c83..ecf1fd85 100644 --- a/ui/ozone/public/ozone_platform.h +++ b/ui/ozone/public/ozone_platform.h
@@ -13,7 +13,6 @@ #include "services/service_manager/public/cpp/bind_source_info.h" #include "services/service_manager/public/cpp/binder_registry.h" #include "ui/events/system_input_injector.h" -#include "ui/gfx/buffer_types.h" #include "ui/gfx/native_widget_types.h" #include "ui/ozone/ozone_export.h" @@ -87,14 +86,6 @@ // Struct used to indicate platform properties. struct PlatformProperties { - PlatformProperties(); - PlatformProperties(bool needs_request, - bool custom_frame_default, - bool can_use_system_title_bar, - std::vector<gfx::BufferFormat> buffer_formats); - ~PlatformProperties(); - PlatformProperties(const PlatformProperties& other); - // Fuchsia only: set to true when the platforms requires // |view_owner_request| field in PlatformWindowInitProperties when creating // a window. @@ -107,9 +98,6 @@ // Determine whether switching between system and custom frames is // supported. bool use_system_title_bar = false; - - // Wayland only: carries buffer formats supported by a Wayland server. - std::vector<gfx::BufferFormat> supported_buffer_formats; }; // Ensures the OzonePlatform instance without doing any initialization.
diff --git a/ui/views/cocoa/bridged_native_widget.h b/ui/views/cocoa/bridged_native_widget.h index dca0f604..81d6f16 100644 --- a/ui/views/cocoa/bridged_native_widget.h +++ b/ui/views/cocoa/bridged_native_widget.h
@@ -18,10 +18,10 @@ #include "ui/base/ime/text_input_client.h" #import "ui/views/cocoa/bridged_native_widget_owner.h" #import "ui/views/cocoa/cocoa_mouse_capture_delegate.h" +#import "ui/views/cocoa/native_widget_mac_nswindow.h" #import "ui/views/focus/focus_manager.h" #include "ui/views/views_export.h" #include "ui/views/widget/widget.h" -#include "ui/views/window/dialog_observer.h" @class BridgedContentView; @class ModalShowAnimationWithLayer; @@ -39,14 +39,32 @@ class NativeWidgetMac; class View; +// The interface through which a NativeWidgetMac may interact with an NSWindow +// in another process. +// TODO(ccameron): Rename this to BridgedNativeWidget, and rename +// BridgedNativeWidget to BridgedNativeWidgetImpl. +class VIEWS_EXPORT BridgedNativeWidgetPublic { + public: + // Initialize the view to display compositor output. This will send the + // current visibility and dimensions (and any future updates) to the + // BridgedNativeWidgetHost. + virtual void InitCompositorView() = 0; + + // Specify the content to draw in the NSView. + virtual void SetCALayerParams(const gfx::CALayerParams& ca_layer_params) = 0; + + // Clear the touchbar. + virtual void ClearTouchBar() = 0; +}; + // A bridge to an NSWindow managed by an instance of NativeWidgetMac or // DesktopNativeWidgetMac. Serves as a helper class to bridge requests from the // NativeWidgetMac to the Cocoa window. Behaves a bit like an aura::Window. class VIEWS_EXPORT BridgedNativeWidget - : public ui::CATransactionCoordinator::PreCommitObserver, + : public BridgedNativeWidgetPublic, + public ui::CATransactionCoordinator::PreCommitObserver, public CocoaMouseCaptureDelegate, - public BridgedNativeWidgetOwner, - public DialogObserver { + public BridgedNativeWidgetOwner { public: // Contains NativeViewHost->gfx::NativeView associations. using AssociatedViews = std::map<const views::View*, NSView*>; @@ -68,12 +86,17 @@ BridgedNativeWidget(BridgedNativeWidgetHost* host, NativeWidgetMac* parent); ~BridgedNativeWidget() override; - // Initialize the bridge, "retains" ownership of |window|. - void Init(base::scoped_nsobject<NSWindow> window, - const Widget::InitParams& params); - - // Invoked at the end of Widget::Init(). - void OnWidgetInitDone(); + // Create the NSWindow using the specified style mask. + void CreateWindow(uint64_t window_style_mask); + // Initialize the NSWindow by taking ownership of the specified object. + // Either CreateWindow or SetWindow maybe used to initialize the NSWindow, + // and the initialization may happen only once. + // TODO(ccameron): When a BridgedNativeWidget is allocated across a process + // boundary, it will not be possible to call SetWindow. Move the relevant + // sub-classes so that they can be allocated via CreateWindow. + void SetWindow(base::scoped_nsobject<NativeWidgetMacNSWindow> window); + // Initialize the bridge (after the NSWindow has been created). + void Init(const Widget::InitParams& params); // Changes the bounds of the window and the hosted layer if present. The // origin is a location in screen coordinates except for "child" windows, @@ -167,7 +190,7 @@ NativeWidgetMac* native_widget_mac() { return native_widget_mac_; } BridgedContentView* ns_view() { return bridged_view_; } - NSWindow* ns_window() { return window_; } + NativeWidgetMacNSWindow* ns_window() { return window_; } TooltipManager* tooltip_manager() { return tooltip_manager_.get(); } @@ -211,16 +234,10 @@ bool ShouldWaitInPreCommit() override; base::TimeDelta PreCommitTimeout() override; - // views::BridgedNativeWidget: - // TODO(ccameron): Rename BridgedNativeWidget to BridgedNativeWidgetImpl, and - // make these methods be exposed via the BridgedNativeWidget interface. - // Initialize the view to display compositor output. This will send the - // current visibility and dimensions (and any future updates) to the - // BridgedNativeWidgetHost. - void InitCompositorView(); - - // Specify the content to draw in the NSView. - void SetCALayerParams(const gfx::CALayerParams& ca_layer_params); + // views::BridgedNativeWidgetPublic: + void InitCompositorView() override; + void SetCALayerParams(const gfx::CALayerParams& ca_layer_params) override; + void ClearTouchBar() override; // TODO(ccameron): This method exists temporarily as we move all direct access // of TextInputClient out of BridgedContentView. @@ -264,9 +281,6 @@ bool IsVisibleParent() const override; void RemoveChildWindow(BridgedNativeWidget* child) override; - // DialogObserver: - void OnDialogModelChanged() override; - // Set |layer()| to be visible or not visible based on |window_visible_|. If // the layer is not visible, then lock the compositor, so we don't draw any // new frames. @@ -274,7 +288,7 @@ BridgedNativeWidgetHost* const host_; // Weak. Owns this. NativeWidgetMac* const native_widget_mac_; // Weak. Owns |host_|. - base::scoped_nsobject<NSWindow> window_; + base::scoped_nsobject<NativeWidgetMacNSWindow> window_; base::scoped_nsobject<ViewsNSWindowDelegate> window_delegate_; base::scoped_nsobject<BridgedContentView> bridged_view_; base::scoped_nsobject<ModalShowAnimationWithLayer> show_animation_;
diff --git a/ui/views/cocoa/bridged_native_widget.mm b/ui/views/cocoa/bridged_native_widget.mm index 7ce8ae4..78b4d66 100644 --- a/ui/views/cocoa/bridged_native_widget.mm +++ b/ui/views/cocoa/bridged_native_widget.mm
@@ -18,6 +18,7 @@ #include "components/viz/common/surfaces/local_surface_id.h" #include "ui/accelerated_widget_mac/window_resize_helper_mac.h" #import "ui/base/cocoa/constrained_window/constrained_window_animation.h" +#import "ui/base/cocoa/window_size_constants.h" #include "ui/base/hit_test.h" #include "ui/base/layout.h" #include "ui/base/ui_base_switches.h" @@ -30,6 +31,7 @@ #import "ui/views/cocoa/cocoa_mouse_capture.h" #import "ui/views/cocoa/cocoa_window_move_loop.h" #import "ui/views/cocoa/drag_drop_client_mac.h" +#import "ui/views/cocoa/native_widget_mac_nswindow.h" #include "ui/views/cocoa/tooltip_manager_mac.h" #import "ui/views/cocoa/views_nswindow_delegate.h" #import "ui/views/cocoa/widget_owner_nswindow_adapter.h" @@ -38,7 +40,6 @@ #include "ui/views/widget/widget.h" #include "ui/views/widget/widget_aura_utils.h" #include "ui/views/widget/widget_delegate.h" -#include "ui/views/window/dialog_delegate.h" namespace { constexpr auto kUIPaintTimeout = base::TimeDelta::FromSeconds(5); @@ -247,16 +248,30 @@ SetRootView(nullptr); } -void BridgedNativeWidget::Init(base::scoped_nsobject<NSWindow> window, - const Widget::InitParams& params) { +void BridgedNativeWidget::CreateWindow(uint64_t window_style_mask) { + DCHECK(!window_); + window_.reset([[NativeWidgetMacNSWindow alloc] + initWithContentRect:ui::kWindowSizeDeterminedLater + styleMask:window_style_mask + backing:NSBackingStoreBuffered + defer:NO]); + [window_ setReleasedWhenClosed:NO]; // Owned by scoped_nsobject. + [window_ setDelegate:window_delegate_]; +} + +void BridgedNativeWidget::SetWindow( + base::scoped_nsobject<NativeWidgetMacNSWindow> window) { + DCHECK(!window_); + window_ = std::move(window); + [window_ setReleasedWhenClosed:NO]; // Owned by scoped_nsobject. + [window_ setDelegate:window_delegate_]; +} + +void BridgedNativeWidget::Init(const Widget::InitParams& params) { widget_type_ = params.type; is_translucent_window_ = params.opacity == Widget::InitParams::TRANSLUCENT_WINDOW; - DCHECK(!window_); - window_.swap(window); - [window_ setDelegate:window_delegate_]; - // Register for application hide notifications so that visibility can be // properly tracked. This is not done in the delegate so that the lifetime is // tied to the C++ object, rather than the delegate (which may be reference @@ -360,13 +375,6 @@ tooltip_manager_.reset(new TooltipManagerMac(this)); } -void BridgedNativeWidget::OnWidgetInitDone() { - DialogDelegate* dialog = - native_widget_mac_->GetWidget()->widget_delegate()->AsDialogDelegate(); - if (dialog) - dialog->AddObserver(this); -} - void BridgedNativeWidget::SetBounds(const gfx::Rect& new_bounds) { Widget* widget = native_widget_mac_->GetWidget(); // -[NSWindow contentMinSize] is only checked by Cocoa for user-initiated @@ -606,10 +614,7 @@ } void BridgedNativeWidget::OnWindowWillClose() { - Widget* widget = native_widget_mac_->GetWidget(); - if (DialogDelegate* dialog = widget->widget_delegate()->AsDialogDelegate()) - dialog->RemoveObserver(this); - native_widget_mac_->WindowDestroying(); + host_->OnWindowWillClose(); // Ensure BridgedNativeWidget does not have capture, otherwise // OnMouseCaptureLost() may reference a deleted |native_widget_mac_| when @@ -629,7 +634,7 @@ DCHECK(!show_animation_); [window_ setDelegate:nil]; - native_widget_mac_->WindowDestroyed(); + host_->OnWindowHasClosed(); // Note: |this| is deleted here. } @@ -1018,6 +1023,13 @@ } } +void BridgedNativeWidget::ClearTouchBar() { + if (@available(macOS 10.12.2, *)) { + if ([bridged_view_ respondsToSelector:@selector(setTouchBar:)]) + [bridged_view_ setTouchBar:nil]; + } +} + void BridgedNativeWidget::SetTextInputClient( ui::TextInputClient* text_input_client) { [bridged_view_ setTextInputClient:text_input_client]; @@ -1052,18 +1064,6 @@ } //////////////////////////////////////////////////////////////////////////////// -// BridgedNativeWidget, DialogObserver: - -void BridgedNativeWidget::OnDialogModelChanged() { - // Note it's only necessary to clear the TouchBar. If the OS needs it again, - // a new one will be created. - if (@available(macOS 10.12.2, *)) { - if ([bridged_view_ respondsToSelector:@selector(setTouchBar:)]) - [bridged_view_ setTouchBar:nil]; - } -} - -//////////////////////////////////////////////////////////////////////////////// // BridgedNativeWidget, private: void BridgedNativeWidget::RemoveOrDestroyChildren() {
diff --git a/ui/views/cocoa/bridged_native_widget_host.h b/ui/views/cocoa/bridged_native_widget_host.h index afcf0cff..ff9d53ad 100644 --- a/ui/views/cocoa/bridged_native_widget_host.h +++ b/ui/views/cocoa/bridged_native_widget_host.h
@@ -56,6 +56,12 @@ bool* found_word, gfx::DecoratedText* decorated_word, gfx::Point* baseline_point) = 0; + + // Called before the NSWindow is closed and destroyed. + virtual void OnWindowWillClose() = 0; + + // Called after the NSWindow has been closed and destroyed. + virtual void OnWindowHasClosed() = 0; }; } // namespace views
diff --git a/ui/views/cocoa/bridged_native_widget_host_impl.h b/ui/views/cocoa/bridged_native_widget_host_impl.h index 0e83d4d..ebc3c94a 100644 --- a/ui/views/cocoa/bridged_native_widget_host_impl.h +++ b/ui/views/cocoa/bridged_native_widget_host_impl.h
@@ -15,6 +15,7 @@ #include "ui/views/focus/focus_manager.h" #include "ui/views/views_export.h" #include "ui/views/widget/widget.h" +#include "ui/views/window/dialog_observer.h" namespace ui { class RecyclableCompositorMac; @@ -23,6 +24,7 @@ namespace views { class BridgedNativeWidget; +class BridgedNativeWidgetPublic; class NativeWidgetMac; // The portion of NativeWidgetMac that lives in the browser process. This @@ -30,6 +32,7 @@ // APIs, and which may live in an app shim process. class VIEWS_EXPORT BridgedNativeWidgetHostImpl : public BridgedNativeWidgetHost, + public DialogObserver, public FocusChangeListener, public ui::internal::InputMethodDelegate, public ui::LayerDelegate, @@ -43,7 +46,8 @@ // Provide direct access to the BridgedNativeWidget that this is hosting. // TODO(ccameron): Remove all accesses to this member, and replace them // with methods that may be sent across processes. - BridgedNativeWidget* bridge() const { return bridge_.get(); } + BridgedNativeWidget* bridge_impl() const { return bridge_impl_.get(); } + BridgedNativeWidgetPublic* bridge() const; // Set the root view (set during initialization and un-set during teardown). void SetRootView(views::View* root_view); @@ -55,6 +59,9 @@ // This does NOT take ownership of |focus_manager|. void SetFocusManager(FocusManager* focus_manager); + // Called when the owning Widget's Init method has completed. + void OnWidgetInitDone(); + // See widget.h for documentation. ui::InputMethod* GetInputMethod(); @@ -79,6 +86,11 @@ bool* found_word, gfx::DecoratedText* decorated_word, gfx::Point* baseline_point) override; + void OnWindowWillClose() override; + void OnWindowHasClosed() override; + + // DialogObserver: + void OnDialogModelChanged() override; // FocusChangeListener: void OnWillChangeFocus(View* focused_before, View* focused_now) override; @@ -102,7 +114,7 @@ // TODO(ccameron): Rather than instantiate a BridgedNativeWidget here, // we will instantiate a mojo BridgedNativeWidget interface to a Cocoa // instance that may be in another process. - std::unique_ptr<BridgedNativeWidget> bridge_; + std::unique_ptr<BridgedNativeWidget> bridge_impl_; std::unique_ptr<ui::InputMethod> input_method_; FocusManager* focus_manager_ = nullptr; // Weak. Owned by our Widget.
diff --git a/ui/views/cocoa/bridged_native_widget_host_impl.mm b/ui/views/cocoa/bridged_native_widget_host_impl.mm index 754a4044..707e2f4 100644 --- a/ui/views/cocoa/bridged_native_widget_host_impl.mm +++ b/ui/views/cocoa/bridged_native_widget_host_impl.mm
@@ -12,6 +12,8 @@ #include "ui/views/cocoa/bridged_native_widget.h" #include "ui/views/views_delegate.h" #include "ui/views/widget/native_widget_mac.h" +#include "ui/views/widget/widget_delegate.h" +#include "ui/views/window/dialog_delegate.h" #include "ui/views/word_lookup_client.h" namespace views { @@ -19,23 +21,27 @@ BridgedNativeWidgetHostImpl::BridgedNativeWidgetHostImpl( NativeWidgetMac* parent) : native_widget_mac_(parent), - bridge_(new BridgedNativeWidget(this, parent)) {} + bridge_impl_(new BridgedNativeWidget(this, parent)) {} BridgedNativeWidgetHostImpl::~BridgedNativeWidgetHostImpl() { // Destroy the bridge first to prevent any calls back into this during // destruction. // TODO(ccameron): When all communication from |bridge_| to this goes through // the BridgedNativeWidgetHost, this can be replaced with closing that pipe. - bridge_.reset(); + bridge_impl_.reset(); SetFocusManager(nullptr); DestroyCompositor(); } +BridgedNativeWidgetPublic* BridgedNativeWidgetHostImpl::bridge() const { + return bridge_impl_.get(); +} + void BridgedNativeWidgetHostImpl::SetRootView(views::View* root_view) { root_view_ = root_view; // TODO(ccameron): The BridgedNativeWidget should not need to know its root // view. - bridge_->SetRootView(root_view); + bridge_impl_->SetRootView(root_view); } void BridgedNativeWidgetHostImpl::CreateCompositor( @@ -69,7 +75,7 @@ // The compositor is initially locked (prevented from producing frames), and // is only unlocked when the BridgedNativeWidget calls back via // SetCompositorVisibility. - bridge_->InitCompositorView(); + bridge()->InitCompositorView(); } void BridgedNativeWidgetHostImpl::DestroyCompositor() { @@ -111,6 +117,12 @@ OnDidChangeFocus(nullptr, new_focus); } +void BridgedNativeWidgetHostImpl::OnWidgetInitDone() { + Widget* widget = native_widget_mac_->GetWidget(); + if (DialogDelegate* dialog = widget->widget_delegate()->AsDialogDelegate()) + dialog->AddObserver(this); +} + ui::InputMethod* BridgedNativeWidgetHostImpl::GetInputMethod() { if (!input_method_) { input_method_ = ui::CreateInputMethod(this, gfx::kNullAcceleratedWidget); @@ -228,8 +240,28 @@ *found_word = true; } +void BridgedNativeWidgetHostImpl::OnWindowWillClose() { + Widget* widget = native_widget_mac_->GetWidget(); + if (DialogDelegate* dialog = widget->widget_delegate()->AsDialogDelegate()) + dialog->RemoveObserver(this); + native_widget_mac_->WindowDestroying(); +} + +void BridgedNativeWidgetHostImpl::OnWindowHasClosed() { + native_widget_mac_->WindowDestroyed(); +} + //////////////////////////////////////////////////////////////////////////////// -// BridgedNativeWidget, FocusChangeListener: +// BridgedNativeWidgetHostImpl, DialogObserver: + +void BridgedNativeWidgetHostImpl::OnDialogModelChanged() { + // Note it's only necessary to clear the TouchBar. If the OS needs it again, + // a new one will be created. + bridge()->ClearTouchBar(); +} + +//////////////////////////////////////////////////////////////////////////////// +// BridgedNativeWidgetHostImpl, FocusChangeListener: void BridgedNativeWidgetHostImpl::OnWillChangeFocus(View* focused_before, View* focused_now) {} @@ -243,7 +275,7 @@ // Sanity check: When focus moves away from the widget (i.e. |focused_now| // is nil), then the textInputClient will be cleared. DCHECK(!!focused_now || !input_client); - bridge_->SetTextInputClient(input_client); + bridge_impl_->SetTextInputClient(input_client); } } @@ -282,7 +314,7 @@ const gfx::CALayerParams* ca_layer_params = compositor_->widget()->GetCALayerParams(); if (ca_layer_params) - bridge_->SetCALayerParams(*ca_layer_params); + bridge()->SetCALayerParams(*ca_layer_params); } } // namespace views
diff --git a/ui/views/cocoa/bridged_native_widget_unittest.mm b/ui/views/cocoa/bridged_native_widget_unittest.mm index 631b856..853aa25 100644 --- a/ui/views/cocoa/bridged_native_widget_unittest.mm +++ b/ui/views/cocoa/bridged_native_widget_unittest.mm
@@ -248,39 +248,6 @@ @end -// Class to override -[NSWindow toggleFullScreen:] to a no-op. This simulates -// NSWindow's behavior when attempting to toggle fullscreen state again, when -// the last attempt failed but Cocoa has not yet sent -// windowDidFailToEnterFullScreen:. -@interface BridgedNativeWidgetTestFullScreenWindow : NativeWidgetMacNSWindow { - @private - int ignoredToggleFullScreenCount_; -} -@property(readonly, nonatomic) int ignoredToggleFullScreenCount; -@end - -@implementation BridgedNativeWidgetTestFullScreenWindow - -@synthesize ignoredToggleFullScreenCount = ignoredToggleFullScreenCount_; - -- (void)performSelector:(SEL)aSelector - withObject:(id)anArgument - afterDelay:(NSTimeInterval)delay { - // This is used in simulations without a message loop. Don't start a message - // loop since that would expose the tests to system notifications and - // potential flakes. Instead, just pretend the message loop is flushed here. - if (aSelector == @selector(toggleFullScreen:)) - [self toggleFullScreen:anArgument]; - else - [super performSelector:aSelector withObject:anArgument afterDelay:delay]; -} - -- (void)toggleFullScreen:(id)sender { - ++ignoredToggleFullScreenCount_; -} - -@end - namespace views { namespace test { @@ -296,6 +263,9 @@ void InitNativeWidget(const Widget::InitParams& params) override { ownership_ = params.ownership; + bridge()->CreateWindow(NSBorderlessWindowMask); + bridge()->Init(params); + // Usually the bridge gets initialized here. It is skipped to run extra // checks in tests, and so that a second window isn't created. delegate()->OnNativeWidgetCreated(true); @@ -358,10 +328,18 @@ } void TearDown() override { + // ui::CocoaTest::TearDown will wait until all NSWindows are destroyed, so + // be sure to destroy the widget (which will destroy its NSWindow) + // beforehand. + widget_.reset(); ui::test::MaterialDesignControllerTestAPI::Uninitialize(); ui::CocoaTest::TearDown(); } + NSWindow* bridge_window() const { + return native_widget_mac_->bridge()->ns_window(); + } + protected: std::unique_ptr<Widget> widget_; MockNativeWidgetMac* native_widget_mac_; // Weak. Owned by |widget_|. @@ -566,13 +544,7 @@ BridgedNativeWidgetTestBase::SetUp(); view_.reset(new views::internal::RootView(widget_.get())); - base::scoped_nsobject<NSWindow> window([test_window() retain]); - - // BridgedNativeWidget expects to be initialized with a hidden (deferred) - // window. - [window orderOut:nil]; - EXPECT_FALSE([window delegate]); - bridge()->Init(window, init_params_); + base::scoped_nsobject<NSWindow> window([bridge_window() retain]); // The delegate should exist before setting the root view. EXPECT_TRUE([window delegate]); @@ -581,7 +553,7 @@ // Pretend it has been shown via NativeWidgetMac::Show(). [window orderFront:nil]; - [test_window() makePretendKeyWindowAndSetFirstResponder:bridge()->ns_view()]; + [window makeFirstResponder:bridge()->ns_view()]; } void BridgedNativeWidgetTest::TearDown() { @@ -741,8 +713,9 @@ // what TEST_VIEW usually does. TEST_F(BridgedNativeWidgetTest, BridgedNativeWidgetTest_TestViewAddRemove) { base::scoped_nsobject<BridgedContentView> view([bridge()->ns_view() retain]); - EXPECT_NSEQ([test_window() contentView], view); - EXPECT_NSEQ(test_window(), [view window]); + base::scoped_nsobject<NSWindow> window([bridge_window() retain]); + EXPECT_NSEQ([window contentView], view); + EXPECT_NSEQ(window, [view window]); // The superview of a contentView is an NSNextStepFrame. EXPECT_TRUE([view superview]); @@ -754,13 +727,13 @@ // Closing the window should tear down the C++ bridge, remove references to // any C++ objects in the ObjectiveC object, and remove it from the hierarchy. - [test_window() close]; + [window close]; EXPECT_FALSE([view hostedView]); EXPECT_FALSE([view superview]); EXPECT_FALSE([view window]); EXPECT_EQ(0u, [[view trackingAreas] count]); - EXPECT_FALSE([test_window() contentView]); - EXPECT_FALSE([test_window() delegate]); + EXPECT_FALSE([window contentView]); + EXPECT_FALSE([window delegate]); } TEST_F(BridgedNativeWidgetTest, BridgedNativeWidgetTest_TestViewDisplay) { @@ -772,8 +745,8 @@ const int kTestNewWidth = 400; const int kTestNewHeight = 300; - // |test_window()| is borderless, so these should align. - NSSize window_size = [test_window() frame].size; + // |bridge_window()| is borderless, so these should align. + NSSize window_size = [bridge_window() frame].size; EXPECT_EQ(view_->width(), static_cast<int>(window_size.width)); EXPECT_EQ(view_->height(), static_cast<int>(window_size.height)); @@ -781,8 +754,8 @@ EXPECT_NE(kTestNewWidth, view_->width()); EXPECT_NE(kTestNewHeight, view_->height()); - [test_window() setFrame:NSMakeRect(0, 0, kTestNewWidth, kTestNewHeight) - display:NO]; + [bridge_window() setFrame:NSMakeRect(0, 0, kTestNewWidth, kTestNewHeight) + display:NO]; EXPECT_EQ(kTestNewWidth, view_->width()); EXPECT_EQ(kTestNewHeight, view_->height()); } @@ -798,13 +771,7 @@ : BridgedNativeWidgetTestBase(SkipInitialization()) {} // Prepares a new |window_| and |widget_| for a call to PerformInit(). - void CreateNewWidgetToInit(NSUInteger style_mask) { - window_.reset( - [[NSWindow alloc] initWithContentRect:ui::kWindowSizeDeterminedLater - styleMask:style_mask - backing:NSBackingStoreBuffered - defer:NO]); - [window_ setReleasedWhenClosed:NO]; // Owned by scoped_nsobject. + void CreateNewWidgetToInit() { widget_.reset(new Widget); native_widget_mac_ = new MockNativeWidgetMac(widget_.get()); init_params_.native_widget = native_widget_mac_; @@ -812,12 +779,8 @@ void PerformInit() { widget_->Init(init_params_); - bridge()->Init(window_, init_params_); } - protected: - base::scoped_nsobject<NSWindow> window_; - private: DISALLOW_COPY_AND_ASSIGN(BridgedNativeWidgetInitTest); }; @@ -842,34 +805,32 @@ EXPECT_EQ(Widget::InitParams::OPAQUE_WINDOW, init_params_.opacity); EXPECT_EQ(Widget::InitParams::SHADOW_TYPE_DEFAULT, init_params_.shadow_type); - CreateNewWidgetToInit(NSBorderlessWindowMask); - EXPECT_FALSE([window_ hasShadow]); // Default for NSBorderlessWindowMask. + CreateNewWidgetToInit(); + EXPECT_FALSE( + [bridge_window() hasShadow]); // Default for NSBorderlessWindowMask. PerformInit(); // Borderless is 0, so isn't really a mask. Check that nothing is set. - EXPECT_EQ(NSBorderlessWindowMask, [window_ styleMask]); - EXPECT_TRUE([window_ hasShadow]); // SHADOW_TYPE_DEFAULT means a shadow. + EXPECT_EQ(NSBorderlessWindowMask, [bridge_window() styleMask]); + EXPECT_TRUE( + [bridge_window() hasShadow]); // SHADOW_TYPE_DEFAULT means a shadow. - CreateNewWidgetToInit(NSBorderlessWindowMask); + CreateNewWidgetToInit(); init_params_.shadow_type = Widget::InitParams::SHADOW_TYPE_NONE; PerformInit(); - EXPECT_FALSE([window_ hasShadow]); // Preserves lack of shadow. + EXPECT_FALSE([bridge_window() hasShadow]); // Preserves lack of shadow. // Default for Widget::InitParams::TYPE_WINDOW. - NSUInteger kBorderedMask = - NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | - NSResizableWindowMask | NSTexturedBackgroundWindowMask; - CreateNewWidgetToInit(kBorderedMask); - EXPECT_TRUE([window_ hasShadow]); // Default for non-borderless. + CreateNewWidgetToInit(); PerformInit(); - EXPECT_FALSE([window_ hasShadow]); // SHADOW_TYPE_NONE removes shadow. + EXPECT_FALSE( + [bridge_window() hasShadow]); // SHADOW_TYPE_NONE removes shadow. init_params_.shadow_type = Widget::InitParams::SHADOW_TYPE_DEFAULT; - CreateNewWidgetToInit(kBorderedMask); + CreateNewWidgetToInit(); PerformInit(); - EXPECT_TRUE([window_ hasShadow]); // Preserves shadow. + EXPECT_TRUE([bridge_window() hasShadow]); // Preserves shadow. - window_.reset(); widget_.reset(); } @@ -1581,18 +1542,10 @@ // mashing Ctrl+Left/Right to keep OSX in a transition between Spaces to cause // the fullscreen transition to fail. TEST_F(BridgedNativeWidgetSimulateFullscreenTest, FailToEnterAndExit) { - base::scoped_nsobject<NSWindow> owned_window( - [[BridgedNativeWidgetTestFullScreenWindow alloc] - initWithContentRect:NSMakeRect(50, 50, 400, 300) - styleMask:NSBorderlessWindowMask - backing:NSBackingStoreBuffered - defer:NO]); - [owned_window setReleasedWhenClosed:NO]; // Owned by scoped_nsobject. - bridge()->Init(owned_window, init_params_); // Transfers ownership. - - BridgedNativeWidgetTestFullScreenWindow* window = - base::mac::ObjCCastStrict<BridgedNativeWidgetTestFullScreenWindow>( + NativeWidgetMacNSWindow* window = + base::mac::ObjCCastStrict<NativeWidgetMacNSWindow>( widget_->GetNativeWindow()); + [window disableToggleFullScreenForTesting]; widget_->Show(); NSNotificationCenter* center = [NSNotificationCenter defaultCenter]; @@ -1606,11 +1559,11 @@ // On a failure, Cocoa starts by sending an unexpected *exit* fullscreen, and // BridgedNativeWidget will think it's just a delayed transition and try to go // back into fullscreen but get ignored by Cocoa. - EXPECT_EQ(0, [window ignoredToggleFullScreenCount]); + EXPECT_EQ(0, [window toggleFullScreenCountForTesting]); EXPECT_TRUE(bridge()->target_fullscreen_state()); [center postNotificationName:NSWindowDidExitFullScreenNotification object:window]; - EXPECT_EQ(1, [window ignoredToggleFullScreenCount]); + EXPECT_EQ(1, [window toggleFullScreenCountForTesting]); EXPECT_FALSE(bridge()->target_fullscreen_state()); // Cocoa follows up with a failure message sent to the NSWindowDelegate (there @@ -1639,7 +1592,7 @@ EXPECT_FALSE(bridge()->target_fullscreen_state()); [center postNotificationName:NSWindowDidExitFullScreenNotification object:window]; - EXPECT_EQ(1, [window ignoredToggleFullScreenCount]); // No change. + EXPECT_EQ(1, [window toggleFullScreenCountForTesting]); // No change. EXPECT_FALSE(bridge()->target_fullscreen_state()); widget_->CloseNow();
diff --git a/ui/views/cocoa/native_widget_mac_nswindow.h b/ui/views/cocoa/native_widget_mac_nswindow.h index 8a0f51b7..2bd552f 100644 --- a/ui/views/cocoa/native_widget_mac_nswindow.h +++ b/ui/views/cocoa/native_widget_mac_nswindow.h
@@ -47,6 +47,16 @@ // create one. - (void)setWindowTouchBarDelegate:(id<WindowTouchBarDelegate>)delegate; +// Override -[NSWindow toggleFullScreen:] to be a no-op for testing. +- (void)disableToggleFullScreenForTesting; + +// Methods to query properties for tests. +// TODO(ccameron): It may be more appropriate to put testing methods into a +// separate subclass. +@property(readonly, nonatomic) int invalidateShadowCountForTesting; +@property(readonly, nonatomic) int orderWindowCountForTesting; +@property(readonly, nonatomic) int toggleFullScreenCountForTesting; +@property(assign, nonatomic) bool* deallocFlagForTesting; @end #endif // UI_VIEWS_COCOA_NATIVE_WIDGET_MAC_NSWINDOW_H_
diff --git a/ui/views/cocoa/native_widget_mac_nswindow.mm b/ui/views/cocoa/native_widget_mac_nswindow.mm index ea244d9..5531c6d 100644 --- a/ui/views/cocoa/native_widget_mac_nswindow.mm +++ b/ui/views/cocoa/native_widget_mac_nswindow.mm
@@ -82,7 +82,18 @@ base::scoped_nsobject<CommandDispatcher> commandDispatcher_; base::scoped_nsprotocol<id<UserInterfaceItemCommandHandler>> commandHandler_; id<WindowTouchBarDelegate> touchBarDelegate_; // Weak. + + BOOL toggleFullscreenDisabledForTesting_; + + int invalidateShadowCountForTesting_; + int orderWindowCountForTesting_; + int toggleFullScreenCountForTesting_; + bool* deallocFlagForTesting_; } +@synthesize invalidateShadowCountForTesting = invalidateShadowCountForTesting_; +@synthesize orderWindowCountForTesting = orderWindowCountForTesting_; +@synthesize toggleFullScreenCountForTesting = toggleFullScreenCountForTesting_; +@synthesize deallocFlagForTesting = deallocFlagForTesting_; - (instancetype)initWithContentRect:(NSRect)contentRect styleMask:(NSUInteger)windowStyle @@ -98,8 +109,13 @@ } // This override doesn't do anything, but keeping it helps diagnose lifetime -// issues in crash stacktraces by inserting a symbol on NativeWidgetMacNSWindow. +// issues in crash stacktraces by inserting a symbol on NativeWidgetMacNSWindow, +// and adds hooks for tests. - (void)dealloc { + if (deallocFlagForTesting_) { + DCHECK(!*deallocFlagForTesting_); + *deallocFlagForTesting_ = true; + } [super dealloc]; } @@ -124,6 +140,10 @@ touchBarDelegate_ = delegate; } +- (void)disableToggleFullScreenForTesting { + toggleFullscreenDisabledForTesting_ = YES; +} + // Private methods. - (ViewsNSWindowDelegate*)viewsNSWindowDelegate { @@ -225,10 +245,36 @@ // when ordering in a window for the first time. - (void)orderWindow:(NSWindowOrderingMode)orderingMode relativeTo:(NSInteger)otherWindowNumber { + ++orderWindowCountForTesting_; [super orderWindow:orderingMode relativeTo:otherWindowNumber]; [[self viewsNSWindowDelegate] onWindowOrderChanged:nil]; } +- (void)invalidateShadow { + ++invalidateShadowCountForTesting_; + [super invalidateShadow]; +} + +- (void)performSelector:(SEL)aSelector + withObject:(id)anArgument + afterDelay:(NSTimeInterval)delay { + if (toggleFullscreenDisabledForTesting_ && aSelector == @selector + (toggleFullScreen:)) { + // This is used in simulations without a message loop. Don't start a message + // loop since that would expose the tests to system notifications and + // potential flakes. Instead, just pretend the message loop is flushed here. + [self toggleFullScreen:anArgument]; + } else { + [super performSelector:aSelector withObject:anArgument afterDelay:delay]; + } +} + +- (void)toggleFullScreen:(id)sender { + ++toggleFullScreenCountForTesting_; + if (!toggleFullscreenDisabledForTesting_) + [super toggleFullScreen:sender]; +} + // NSResponder implementation. - (BOOL)performKeyEquivalent:(NSEvent*)event {
diff --git a/ui/views/widget/native_widget_mac.mm b/ui/views/widget/native_widget_mac.mm index 36184ec..a7742012 100644 --- a/ui/views/widget/native_widget_mac.mm +++ b/ui/views/widget/native_widget_mac.mm
@@ -28,7 +28,6 @@ #import "ui/views/cocoa/bridged_native_widget_host_impl.h" #include "ui/views/cocoa/cocoa_mouse_capture.h" #import "ui/views/cocoa/drag_drop_client_mac.h" -#import "ui/views/cocoa/native_widget_mac_nswindow.h" #import "ui/views/cocoa/views_nswindow_delegate.h" #include "ui/views/widget/drop_helper.h" #include "ui/views/widget/widget_delegate.h" @@ -129,9 +128,10 @@ void NativeWidgetMac::InitNativeWidget(const Widget::InitParams& params) { ownership_ = params.ownership; name_ = params.name; - base::scoped_nsobject<NSWindow> window([CreateNSWindow(params) retain]); - [window setReleasedWhenClosed:NO]; // Owned by scoped_nsobject. - bridge()->Init(window, params); + base::scoped_nsobject<NativeWidgetMacNSWindow> window( + [CreateNSWindow(params) retain]); + bridge()->SetWindow(window); + bridge()->Init(params); // Only set always-on-top here if it is true since setting it may affect how // the window is treated by Expose. @@ -152,7 +152,7 @@ void NativeWidgetMac::OnWidgetInitDone() { OnSizeConstraintsChanged(); - bridge()->OnWidgetInitDone(); + bridge_host_->OnWidgetInitDone(); } NonClientFrameView* NativeWidgetMac::CreateNonClientFrameView() { @@ -664,7 +664,7 @@ } BridgedNativeWidget* NativeWidgetMac::bridge() const { - return bridge_host_ ? bridge_host_->bridge() : nullptr; + return bridge_host_ ? bridge_host_->bridge_impl() : nullptr; } ////////////////////////////////////////////////////////////////////////////////
diff --git a/ui/views/widget/native_widget_mac_unittest.mm b/ui/views/widget/native_widget_mac_unittest.mm index 48fdedd..1296c85 100644 --- a/ui/views/widget/native_widget_mac_unittest.mm +++ b/ui/views/widget/native_widget_mac_unittest.mm
@@ -56,18 +56,6 @@ - (BOOL)_isTitleHidden; @end -// Test NSWindow that provides hooks via method overrides to verify behavior. -@interface NativeWidgetMacTestWindow : NativeWidgetMacNSWindow { - @private - int invalidateShadowCount_; - int orderWindowCount_; - bool* deallocFlag_; -} -@property(readonly, nonatomic) int invalidateShadowCount; -@property(readonly, nonatomic) int orderWindowCount; -@property(assign, nonatomic) bool* deallocFlag; -@end - // Used to mock BridgedContentView so that calls to drawRect: can be // intercepted. @interface MockBridgedView : NSView { @@ -121,33 +109,6 @@ DISALLOW_COPY_AND_ASSIGN(BridgedNativeWidgetTestApi); }; -// Custom native_widget to create a NativeWidgetMacTestWindow. -class TestWindowNativeWidgetMac : public NativeWidgetMac { - public: - explicit TestWindowNativeWidgetMac(Widget* delegate) - : NativeWidgetMac(delegate) {} - - protected: - // NativeWidgetMac: - NativeWidgetMacNSWindow* CreateNSWindow( - const Widget::InitParams& params) override { - NSUInteger style_mask = NSBorderlessWindowMask; - if (params.type == Widget::InitParams::TYPE_WINDOW) { - style_mask = NSTexturedBackgroundWindowMask | NSTitledWindowMask | - NSClosableWindowMask | NSMiniaturizableWindowMask | - NSResizableWindowMask; - } - return [[[NativeWidgetMacTestWindow alloc] - initWithContentRect:ui::kWindowSizeDeterminedLater - styleMask:style_mask - backing:NSBackingStoreBuffered - defer:NO] autorelease]; - } - - private: - DISALLOW_COPY_AND_ASSIGN(TestWindowNativeWidgetMac); -}; - // Tests for parts of NativeWidgetMac not covered by BridgedNativeWidget, which // need access to Cocoa APIs. class NativeWidgetMacTest : public WidgetTest { @@ -174,14 +135,14 @@ return MakeNativeParentWithStyle(NSBorderlessWindowMask); } - // Create a Widget backed by the NativeWidgetMacTestWindow NSWindow subclass. + // Create a Widget backed by the NativeWidgetMacNSWindow NSWindow subclass. Widget* CreateWidgetWithTestWindow(Widget::InitParams params, - NativeWidgetMacTestWindow** window) { + NativeWidgetMacNSWindow** window) { Widget* widget = new Widget; - params.native_widget = new TestWindowNativeWidgetMac(widget); + params.native_widget = new NativeWidgetMac(widget); widget->Init(params); widget->Show(); - *window = base::mac::ObjCCastStrict<NativeWidgetMacTestWindow>( + *window = base::mac::ObjCCastStrict<NativeWidgetMacNSWindow>( widget->GetNativeWindow()); EXPECT_TRUE(*window); return widget; @@ -469,8 +430,8 @@ // Test that ShowInactive() on already-visible child widgets is ignored, since // it may cause a space transition. See https://crbug.com/866760. TEST_F(NativeWidgetMacTest, ShowInactiveOnChildWidget) { - NativeWidgetMacTestWindow* parent_window; - NativeWidgetMacTestWindow* child_window; + NativeWidgetMacNSWindow* parent_window; + NativeWidgetMacNSWindow* child_window; Widget::InitParams init_params = CreateParams(Widget::InitParams::TYPE_WINDOW); @@ -478,28 +439,29 @@ Widget* parent = CreateWidgetWithTestWindow(init_params, &parent_window); // CreateWidgetWithTestWindow calls Show() - EXPECT_EQ(1, [parent_window orderWindowCount]); + EXPECT_EQ(1, [parent_window orderWindowCountForTesting]); init_params.parent = parent->GetNativeView(); Widget* child = CreateWidgetWithTestWindow(init_params, &child_window); // The child is ordered twice, once by Show() and again (by AppKit) when it is // registered as a child window. - EXPECT_EQ(2, [child_window orderWindowCount]); + EXPECT_EQ(2, [child_window orderWindowCountForTesting]); // Parent is unchanged. - EXPECT_EQ(1, [parent_window orderWindowCount]); + EXPECT_EQ(1, [parent_window orderWindowCountForTesting]); // ShowInactive() on a visible regular window may serve to raise its stacking // order without taking focus, so it should invoke -[NSWindow orderWindow:..]. parent->ShowInactive(); - EXPECT_EQ(2, [parent_window orderWindowCount]); // Increases. + EXPECT_EQ(2, [parent_window orderWindowCountForTesting]); // Increases. // However, ShowInactive() on the child should have no effect. It should // already be in a correct stacking order and we must avoid a Space switch. child->ShowInactive(); - EXPECT_EQ(2, [child_window orderWindowCount]); // No change. - EXPECT_EQ(2, [parent_window orderWindowCount]); // Parent also unchanged. + EXPECT_EQ(2, [child_window orderWindowCountForTesting]); // No change. + EXPECT_EQ( + 2, [parent_window orderWindowCountForTesting]); // Parent also unchanged. parent->CloseNow(); } @@ -876,13 +838,13 @@ TestNativeParentWindow* native_parent = MakeNativeParent(); [native_parent setDeallocFlag:&native_parent_dealloced]; - NativeWidgetMacTestWindow* window; + NativeWidgetMacNSWindow* window; Widget::InitParams init_params = CreateParams(Widget::InitParams::TYPE_POPUP); init_params.parent = [native_parent_ contentView]; init_params.bounds = gfx::Rect(0, 0, 100, 200); CreateWidgetWithTestWindow(init_params, &window); - [window setDeallocFlag:&child_dealloced]; + [window setDeallocFlagForTesting:&child_dealloced]; } { // On 10.11, closing a weak reference on the parent window works, but older @@ -1795,7 +1757,7 @@ // Test calls to invalidate the shadow when composited frames arrive. TEST_F(NativeWidgetMacTest, InvalidateShadow) { - NativeWidgetMacTestWindow* window; + NativeWidgetMacNSWindow* window; const gfx::Rect rect(0, 0, 100, 200); Widget::InitParams init_params = CreateParams(Widget::InitParams::TYPE_WINDOW_FRAMELESS); @@ -1806,7 +1768,7 @@ BridgedNativeWidgetTestApi(window).SimulateFrameSwap(rect.size()); // Default is an opaque window, so shadow doesn't need to be invalidated. - EXPECT_EQ(0, [window invalidateShadowCount]); + EXPECT_EQ(0, [window invalidateShadowCountForTesting]); widget->CloseNow(); init_params.opacity = Widget::InitParams::TRANSLUCENT_WINDOW; @@ -1814,40 +1776,40 @@ BridgedNativeWidgetTestApi test_api(window); // First paint on a translucent window needs to invalidate the shadow. Once. - EXPECT_EQ(0, [window invalidateShadowCount]); + EXPECT_EQ(0, [window invalidateShadowCountForTesting]); test_api.SimulateFrameSwap(rect.size()); - EXPECT_EQ(1, [window invalidateShadowCount]); + EXPECT_EQ(1, [window invalidateShadowCountForTesting]); test_api.SimulateFrameSwap(rect.size()); - EXPECT_EQ(1, [window invalidateShadowCount]); + EXPECT_EQ(1, [window invalidateShadowCountForTesting]); // Resizing the window also needs to trigger a shadow invalidation. [window setContentSize:NSMakeSize(123, 456)]; // A "late" frame swap at the old size should do nothing. test_api.SimulateFrameSwap(rect.size()); - EXPECT_EQ(1, [window invalidateShadowCount]); + EXPECT_EQ(1, [window invalidateShadowCountForTesting]); test_api.SimulateFrameSwap(gfx::Size(123, 456)); - EXPECT_EQ(2, [window invalidateShadowCount]); + EXPECT_EQ(2, [window invalidateShadowCountForTesting]); test_api.SimulateFrameSwap(gfx::Size(123, 456)); - EXPECT_EQ(2, [window invalidateShadowCount]); + EXPECT_EQ(2, [window invalidateShadowCountForTesting]); // Hiding the window does not require shadow invalidation. widget->Hide(); test_api.SimulateFrameSwap(gfx::Size(123, 456)); - EXPECT_EQ(2, [window invalidateShadowCount]); + EXPECT_EQ(2, [window invalidateShadowCountForTesting]); // Showing a translucent window after hiding it, should trigger shadow // invalidation. widget->Show(); test_api.SimulateFrameSwap(gfx::Size(123, 456)); - EXPECT_EQ(3, [window invalidateShadowCount]); + EXPECT_EQ(3, [window invalidateShadowCountForTesting]); widget->CloseNow(); } // Test that the contentView opacity corresponds to the window type. TEST_F(NativeWidgetMacTest, ContentOpacity) { - NativeWidgetMacTestWindow* window; + NativeWidgetMacNSWindow* window; Widget::InitParams init_params = CreateParams(Widget::InitParams::TYPE_WINDOW_FRAMELESS); @@ -2376,33 +2338,6 @@ } @end -@implementation NativeWidgetMacTestWindow - -@synthesize invalidateShadowCount = invalidateShadowCount_; -@synthesize orderWindowCount = orderWindowCount_; -@synthesize deallocFlag = deallocFlag_; - -- (void)dealloc { - if (deallocFlag_) { - DCHECK(!*deallocFlag_); - *deallocFlag_ = true; - } - [super dealloc]; -} - -- (void)invalidateShadow { - ++invalidateShadowCount_; - [super invalidateShadow]; -} - -- (void)orderWindow:(NSWindowOrderingMode)orderingMode - relativeTo:(NSInteger)otherWindowNumber { - ++orderWindowCount_; - [super orderWindow:orderingMode relativeTo:otherWindowNumber]; -} - -@end - @implementation MockBridgedView @synthesize drawRectCount = drawRectCount_;