diff --git a/DEPS b/DEPS index b55419f21..29b2300 100644 --- a/DEPS +++ b/DEPS
@@ -78,7 +78,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': '1fa9c434fc0dbe28342c28b7d08cb9361f80c4e2', + 'skia_revision': '92c7fa6b009b3ea4e93ca179153f837c2d9d7962', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. @@ -134,7 +134,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling catapult # and whatever else without interference from each other. - 'catapult_revision': '5626f3590eea9631f90a98549c73334577994819', + 'catapult_revision': '3b3f9e1e789dbed2726dcd3c97d9dcd080ca7f23', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other.
diff --git a/ash/display/display_manager_unittest.cc b/ash/display/display_manager_unittest.cc index 72031e2..8801722d 100644 --- a/ash/display/display_manager_unittest.cc +++ b/ash/display/display_manager_unittest.cc
@@ -2316,30 +2316,6 @@ Shell::Get()->SetCursorCompositingEnabled(false); } -TEST_F(DisplayManagerTest, HardwareMirrorDetection) { - // Disable restoring mirror mode to prevent interference from previous - // display configuration. - display_manager()->set_disable_restoring_mirror_mode_for_test(true); - - UpdateDisplay("500x500,400x400"); - EXPECT_FALSE(display_manager()->GetCurrentDisplayLayout().mirrored); - EXPECT_EQ(2, display::Screen::GetScreen()->GetNumDisplays()); - EXPECT_EQ(2U, display_manager()->num_connected_displays()); - - // Hardware mirroring. - UpdateDisplay("1+0-500x500,1+0-500x500"); - EXPECT_TRUE(display_manager()->GetCurrentDisplayLayout().mirrored); - EXPECT_EQ(1, display::Screen::GetScreen()->GetNumDisplays()); - EXPECT_EQ(2U, display_manager()->num_connected_displays()); - - UpdateDisplay("500x500,500x500"); - EXPECT_FALSE(display_manager()->GetCurrentDisplayLayout().mirrored); - EXPECT_EQ(2, display::Screen::GetScreen()->GetNumDisplays()); - EXPECT_EQ(2U, display_manager()->num_connected_displays()); - - display_manager()->set_disable_restoring_mirror_mode_for_test(false); -} - TEST_F(DisplayManagerTest, InvertLayout) { EXPECT_EQ("left, 0", display::DisplayPlacement(display::DisplayPlacement::RIGHT, 0) @@ -2553,7 +2529,6 @@ display::DisplayIdList list = display::test::CreateDisplayIdList2(1, 2); display::DisplayLayoutBuilder builder( display_manager()->layout_store()->GetRegisteredDisplayLayout(list)); - builder.SetMirrored(false); display_manager()->layout_store()->RegisterLayoutForDisplayIdList( list, builder.Build()); d2.SetBounds(gfx::Rect(0, 500, 500, 500)); @@ -3497,9 +3472,8 @@ const display::DisplayIdList current_list = display_manager()->GetCurrentDisplayIdList(); - display_manager()->layout_store()->UpdateMultiDisplayState( - current_list, true /* mirrored */, false /* unified */); - EXPECT_FALSE(display_manager()->GetCurrentDisplayLayout().mirrored); + display_manager()->layout_store()->UpdateDefaultUnified(current_list, + false /* unified */); EXPECT_EQ(display::MULTIPLE_DISPLAY_STATE_DUAL_MIRROR, observer.GetStateForDisplayIds(outputs));
diff --git a/ash/display/window_tree_host_manager.cc b/ash/display/window_tree_host_manager.cc index cca2c80e..f911d96 100644 --- a/ash/display/window_tree_host_manager.cc +++ b/ash/display/window_tree_host_manager.cc
@@ -718,8 +718,7 @@ display::DisplayIdList list = display_manager->GetCurrentDisplayIdList(); const display::DisplayLayout& layout = layout_store->GetRegisteredDisplayLayout(list); - layout_store->UpdateMultiDisplayState( - list, display_manager->IsInMirrorMode(), layout.default_unified); + layout_store->UpdateDefaultUnified(list, layout.default_unified); if (display::Screen::GetScreen()->GetNumDisplays() > 1) { SetPrimaryDisplayId(layout.primary_id == display::kInvalidDisplayId ? list[0]
diff --git a/chrome/browser/chromeos/display/display_preferences_unittest.cc b/chrome/browser/chromeos/display/display_preferences_unittest.cc index 53483ed1..1ff00147 100644 --- a/chrome/browser/chromeos/display/display_preferences_unittest.cc +++ b/chrome/browser/chromeos/display/display_preferences_unittest.cc
@@ -48,7 +48,6 @@ namespace chromeos { namespace { const char kPrimaryIdKey[] = "primary-id"; -const char kMirroredKey[] = "mirrored"; const char kPositionKey[] = "position"; const char kOffsetKey[] = "offset"; const char kPlacementDisplayIdKey[] = "placement.display_id"; @@ -384,10 +383,6 @@ EXPECT_EQ(dummy_layout->placement_list[0].offset, stored_layout.placement_list[0].offset); - bool mirrored = true; - EXPECT_TRUE(layout_value->GetBoolean(kMirroredKey, &mirrored)); - EXPECT_FALSE(mirrored); - const base::ListValue* external_display_mirror_info = local_state()->GetList(prefs::kExternalDisplayMirrorInfo); EXPECT_EQ(0U, external_display_mirror_info->GetSize()); @@ -499,9 +494,6 @@ if (true) return; - mirrored = true; - EXPECT_TRUE(layout_value->GetBoolean(kMirroredKey, &mirrored)); - EXPECT_FALSE(mirrored); std::string primary_id_str; EXPECT_TRUE(layout_value->GetString(kPrimaryIdKey, &primary_id_str)); EXPECT_EQ(base::Int64ToString(id2), primary_id_str); @@ -526,9 +518,6 @@ EXPECT_TRUE(layout_value->GetString(kPlacementParentDisplayIdKey, &id)); EXPECT_EQ(base::Int64ToString(id2), id); - mirrored = false; - EXPECT_TRUE(layout_value->GetBoolean(kMirroredKey, &mirrored)); - EXPECT_TRUE(mirrored); EXPECT_TRUE(layout_value->GetString(kPrimaryIdKey, &primary_id_str)); EXPECT_EQ(base::Int64ToString(id2), primary_id_str); @@ -565,9 +554,6 @@ EXPECT_EQ("right", position); EXPECT_TRUE(layout_value->GetInteger(kOffsetKey, &offset)); EXPECT_EQ(0, offset); - mirrored = true; - EXPECT_TRUE(layout_value->GetBoolean(kMirroredKey, &mirrored)); - EXPECT_FALSE(mirrored); EXPECT_TRUE(layout_value->GetString(kPrimaryIdKey, &primary_id_str)); EXPECT_EQ(base::Int64ToString(id1), primary_id_str); @@ -591,9 +577,6 @@ EXPECT_EQ("right", position); EXPECT_TRUE(layout_value->GetInteger(kOffsetKey, &offset)); EXPECT_EQ(0, offset); - mirrored = true; - EXPECT_TRUE(layout_value->GetBoolean(kMirroredKey, &mirrored)); - EXPECT_FALSE(mirrored); EXPECT_TRUE(layout_value->GetString(kPrimaryIdKey, &primary_id_str)); EXPECT_EQ(base::Int64ToString(id1), primary_id_str); @@ -1038,7 +1021,6 @@ display::DisplayLayout stored_layout; EXPECT_TRUE(display::JsonToDisplayLayout(*new_value, &stored_layout)); EXPECT_TRUE(stored_layout.default_unified); - EXPECT_FALSE(stored_layout.mirrored); const base::DictionaryValue* displays = local_state()->GetDictionary(prefs::kDisplayProperties); @@ -1060,14 +1042,12 @@ display::DisplayIdListToString(list), &new_value)); EXPECT_TRUE(display::JsonToDisplayLayout(*new_value, &stored_layout)); EXPECT_TRUE(stored_layout.default_unified); - EXPECT_TRUE(stored_layout.mirrored); display_manager()->SetMirrorMode(false); ASSERT_TRUE(secondary_displays->GetDictionary( display::DisplayIdListToString(list), &new_value)); EXPECT_TRUE(display::JsonToDisplayLayout(*new_value, &stored_layout)); EXPECT_TRUE(stored_layout.default_unified); - EXPECT_FALSE(stored_layout.mirrored); // Exit unified mode. display_manager()->SetDefaultMultiDisplayModeForCurrentDisplays( @@ -1076,7 +1056,6 @@ display::DisplayIdListToString(list), &new_value)); EXPECT_TRUE(display::JsonToDisplayLayout(*new_value, &stored_layout)); EXPECT_FALSE(stored_layout.default_unified); - EXPECT_FALSE(stored_layout.mirrored); } TEST_F(DisplayPreferencesTest, RestoreUnifiedMode) { @@ -1215,11 +1194,6 @@ // Make sure the mirror mode is not saved in the preference. display::DisplayIdList list = display_manager()->GetCurrentDisplayIdList(); ASSERT_EQ(2u, list.size()); - base::Value* value; - EXPECT_TRUE(GetDisplayPropertyFromList(list, "mirrored", &value)); - bool mirrored; - EXPECT_TRUE(value->GetAsBoolean(&mirrored)); - EXPECT_FALSE(mirrored); // Exiting the tablet mode should exit mirror mode. controller->EnableTabletModeWindowManager(false);
diff --git a/chrome/browser/extensions/active_tab_unittest.cc b/chrome/browser/extensions/active_tab_unittest.cc index f043480a..819217e3 100644 --- a/chrome/browser/extensions/active_tab_unittest.cc +++ b/chrome/browser/extensions/active_tab_unittest.cc
@@ -446,7 +446,7 @@ #if defined(OS_CHROMEOS) // Test that the platform delegate is being set and the permission is prompted // for. -TEST_F(ActiveTabTest, DelegateIsSet) { +TEST_F(ActiveTabTest, DISABLED_DelegateIsSet) { // Necessary to prevent instantiation of ProfileSyncService, which messes with // our signin state below. base::CommandLine::ForCurrentProcess()->AppendSwitch(switches::kDisableSync);
diff --git a/chrome/browser/printing/pdf_to_emf_converter.cc b/chrome/browser/printing/pdf_to_emf_converter.cc index c90ded9..b2e4d2b 100644 --- a/chrome/browser/printing/pdf_to_emf_converter.cc +++ b/chrome/browser/printing/pdf_to_emf_converter.cc
@@ -8,6 +8,7 @@ #include <windows.h> #include <memory> +#include <string> #include <utility> #include <vector> @@ -262,10 +263,6 @@ void OnTempFileReady(GetPageCallbackData* callback_data, ScopedTempFile temp_file); - // Additional message handler needed for Pdf to Emf - void OnPreCacheFontCharacters(const LOGFONT& log_font, - const base::string16& characters); - scoped_refptr<RefCountedTempDir> temp_dir_; PdfRenderSettings settings_; @@ -560,37 +557,6 @@ Stop(); } -void PdfConverterImpl::OnPreCacheFontCharacters(const LOGFONT& font, - const base::string16& str) { - // TODO(scottmg): pdf/ppapi still require the renderer to be able to precache - // GDI fonts (http://crbug.com/383227), even when using DirectWrite. - // Eventually this shouldn't be added and should be moved to - // FontCacheDispatcher too. http://crbug.com/356346. - - // First, comments from FontCacheDispatcher::OnPreCacheFont do apply here too. - // Except that for True Type fonts, - // GetTextMetrics will not load the font in memory. - // The only way windows seem to load properly, it is to create a similar - // device (like the one in which we print), then do an ExtTextOut, - // as we do in the printing thread, which is sandboxed. - HDC hdc = CreateEnhMetaFile(nullptr, nullptr, nullptr, nullptr); - HFONT font_handle = CreateFontIndirect(&font); - DCHECK(font_handle != nullptr); - - HGDIOBJ old_font = SelectObject(hdc, font_handle); - DCHECK(old_font != nullptr); - - ExtTextOut(hdc, 0, 0, ETO_GLYPH_INDEX, 0, str.c_str(), str.length(), nullptr); - - SelectObject(hdc, old_font); - DeleteObject(font_handle); - - HENHMETAFILE metafile = CloseEnhMetaFile(hdc); - - if (metafile) - DeleteEnhMetaFile(metafile); -} - } // namespace PdfConverter::~PdfConverter() = default;
diff --git a/chrome/browser/resources/chromeos/chromevox/chromevox/background/background.js b/chrome/browser/resources/chromeos/chromevox/chromevox/background/background.js index 381a28d..0bae33d 100644 --- a/chrome/browser/resources/chromeos/chromevox/chromevox/background/background.js +++ b/chrome/browser/resources/chromeos/chromevox/chromevox/background/background.js
@@ -10,7 +10,6 @@ goog.require('ChromeVoxState'); goog.require('Msgs'); -goog.require('constants'); goog.require('cvox.AbstractEarcons'); goog.require('cvox.BrailleBackground'); goog.require('cvox.BrailleCaptionsBackground'); @@ -88,7 +87,7 @@ cvox.BrailleCaptionsBackground.setActive(!!value); } else if (pref == 'position') { cvox.ChromeVox.position = - /** @type {Object<string, constants.Point>} */ (JSON.parse( + /** @type {Object<string, cvox.Point>} */ (JSON.parse( /** @type {string} */ (value))); } window['prefs'].setPref(pref, value);
diff --git a/chrome/browser/resources/chromeos/chromevox/common/chromevox.js b/chrome/browser/resources/chromeos/chromevox/common/chromevox.js index 37cb604f..1dcb41b 100644 --- a/chrome/browser/resources/chromeos/chromevox/common/chromevox.js +++ b/chrome/browser/resources/chromeos/chromevox/common/chromevox.js
@@ -9,7 +9,6 @@ */ goog.provide('cvox.ChromeVox'); -goog.require('constants'); // Forward declarations. // TODO (stoarca): Put these in a separate file and pass that @@ -133,7 +132,11 @@ */ cvox.ChromeVox.keyEcho = {}; /** - * @type {Object<string, constants.Point>} + * @typedef {{x: number, y: number}} + */ +cvox.Point; +/** + * @type {Object<string, cvox.Point>} */ cvox.ChromeVox.position = {}; /**
diff --git a/chrome/browser/resources/chromeos/chromevox/cvox2/background/automation_predicate.js b/chrome/browser/resources/chromeos/chromevox/cvox2/background/automation_predicate.js index 5be61ec..e05adba 100644 --- a/chrome/browser/resources/chromeos/chromevox/cvox2/background/automation_predicate.js +++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/automation_predicate.js
@@ -144,7 +144,7 @@ * @return {boolean} */ AutomationPredicate.visitedLink = function(node) { - return node.state[State.VISITED]; + return node.state.visited; }; /**
diff --git a/chrome/browser/resources/chromeos/chromevox/cvox2/background/automation_util.js b/chrome/browser/resources/chromeos/chromevox/cvox2/background/automation_util.js index 7f439ca1..903c414 100644 --- a/chrome/browser/resources/chromeos/chromevox/cvox2/background/automation_util.js +++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/automation_util.js
@@ -259,7 +259,7 @@ * with respect to their parents, the hit test considers all children before * their parents when looking for a matching node. * @param {AutomationNode} node Subtree to search. - * @param {constants.Point} point + * @param {cvox.Point} point * @return {AutomationNode} */ AutomationUtil.hitTest = function(node, point) {
diff --git a/chrome/browser/resources/chromeos/chromevox/cvox2/background/constants.js b/chrome/browser/resources/chromeos/chromevox/cvox2/background/constants.js index 6d44861..762ca88e 100644 --- a/chrome/browser/resources/chromeos/chromevox/cvox2/background/constants.js +++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/constants.js
@@ -21,12 +21,6 @@ }; /** - * Represents a point. - * @typedef {{x: (number), y: (number)}} - */ -constants.Point; - -/** * If a node contains more characters than this, it should not be visited during * object navigation. *
diff --git a/chrome/browser/resources/chromeos/select_to_speak/BUILD.gn b/chrome/browser/resources/chromeos/select_to_speak/BUILD.gn index e0a5937fc..a30ce42d 100644 --- a/chrome/browser/resources/chromeos/select_to_speak/BUILD.gn +++ b/chrome/browser/resources/chromeos/select_to_speak/BUILD.gn
@@ -26,10 +26,6 @@ mode = "copy" dest_dir = select_to_speak_out_dir sources = [ - "../chromevox/cvox2/background/automation_predicate.js", - "../chromevox/cvox2/background/automation_util.js", - "../chromevox/cvox2/background/constants.js", - "../chromevox/cvox2/background/tree_walker.js", "checked.png", "options.css", "options.html",
diff --git a/chrome/browser/resources/chromeos/select_to_speak/closure_shim.js b/chrome/browser/resources/chromeos/select_to_speak/closure_shim.js deleted file mode 100644 index e04ffc8..0000000 --- a/chrome/browser/resources/chromeos/select_to_speak/closure_shim.js +++ /dev/null
@@ -1,19 +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. - -/** - * Provides a shim to allow select-to-speak to use closure files. - */ - -var goog = {}; - -goog.provide = function(n) { - window[n] = {}; -}; - -goog.require = function() {}; - -goog.scope = function(c) { - c(); -};
diff --git a/chrome/browser/resources/chromeos/select_to_speak/compiled_resources2.gyp b/chrome/browser/resources/chromeos/select_to_speak/compiled_resources2.gyp index 4284ec0..a581105 100644 --- a/chrome/browser/resources/chromeos/select_to_speak/compiled_resources2.gyp +++ b/chrome/browser/resources/chromeos/select_to_speak/compiled_resources2.gyp
@@ -6,8 +6,6 @@ { 'target_name': 'select_to_speak', 'dependencies': [ - '../chromevox/cvox2/background/constants', - '../chromevox/cvox2/background/automation_util', 'externs', 'paragraph_utils', '<(EXTERNS_GYP):accessibility_private', @@ -42,43 +40,5 @@ ], 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], }, - { - 'target_name': '../chromevox/cvox2/background/automation_util', - 'dependencies': [ - '../chromevox/cvox2/background/automation_predicate', - '../chromevox/cvox2/background/tree_walker', - '../chromevox/cvox2/background/constants', - '<(EXTERNS_GYP):automation', - '<(EXTERNS_GYP):chrome_extensions', - ], - 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], - }, - { - 'target_name': '../chromevox/cvox2/background/tree_walker', - 'dependencies': [ - '../chromevox/cvox2/background/automation_predicate', - '../chromevox/cvox2/background/constants', - '<(EXTERNS_GYP):automation', - '<(EXTERNS_GYP):chrome_extensions', - ], - 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], - }, - { - 'target_name': '../chromevox/cvox2/background/automation_predicate', - 'dependencies': [ - '../chromevox/cvox2/background/constants', - '<(EXTERNS_GYP):automation', - '<(EXTERNS_GYP):chrome_extensions', - ], - 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], - }, - { - 'target_name': '../chromevox/cvox2/background/constants', - 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], - }, - { - 'target_name': 'closure_shim', - 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], - }, ], }
diff --git a/chrome/browser/resources/chromeos/select_to_speak/manifest.json.jinja2 b/chrome/browser/resources/chromeos/select_to_speak/manifest.json.jinja2 index 3461a8fc..e0b3ef43 100644 --- a/chrome/browser/resources/chromeos/select_to_speak/manifest.json.jinja2 +++ b/chrome/browser/resources/chromeos/select_to_speak/manifest.json.jinja2
@@ -11,11 +11,6 @@ {% endif %} "background": { "scripts": [ - "closure_shim.js", - "constants.js", - "automation_predicate.js", - "tree_walker.js", - "automation_util.js", "paragraph_utils.js", "select_to_speak.js", "select_to_speak_main.js"
diff --git a/chrome/browser/ui/webui/extensions/extension_settings_browsertest.cc b/chrome/browser/ui/webui/extensions/extension_settings_browsertest.cc index a918a77..90d091e 100644 --- a/chrome/browser/ui/webui/extensions/extension_settings_browsertest.cc +++ b/chrome/browser/ui/webui/extensions/extension_settings_browsertest.cc
@@ -4,7 +4,11 @@ #include "chrome/browser/ui/webui/extensions/extension_settings_browsertest.h" +#include <string> + #include "base/path_service.h" +#include "base/strings/string_util.h" +#include "base/threading/thread_restrictions.h" #include "chrome/browser/extensions/chrome_test_extension_loader.h" #include "chrome/browser/extensions/unpacked_installer.h" #include "chrome/browser/profiles/profile.h" @@ -12,6 +16,10 @@ #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/browser/ui/web_contents_sizer.h" #include "chrome/common/chrome_paths.h" +#include "chrome/test/base/ui_test_utils.h" +#include "content/public/browser/render_frame_host.h" +#include "content/public/browser/web_contents.h" +#include "content/public/test/browser_test_utils.h" #include "extensions/browser/extension_dialog_auto_confirm.h" #include "extensions/browser/extension_system.h" @@ -58,9 +66,12 @@ test_data_dir_.AppendASCII("platform_apps").AppendASCII("minimal"))); } -void ExtensionSettingsUIBrowserTest::InstallExtensionWithInPageOptions() { - EXPECT_TRUE( - InstallExtension(test_data_dir_.AppendASCII("options_page_in_view"))); +const extensions::Extension* +ExtensionSettingsUIBrowserTest::InstallExtensionWithInPageOptions() { + const extensions::Extension* extension = + InstallExtension(test_data_dir_.AppendASCII("options_page_in_view")); + EXPECT_TRUE(extension); + return extension; } void ExtensionSettingsUIBrowserTest::AddManagedPolicyProvider() { @@ -92,3 +103,59 @@ loader.set_ignore_manifest_warnings(true); return loader.LoadExtension(path).get(); } + +// Tests that viewing a source of the options page works fine. +// This is a regression test for https://crbug.com/796080. +IN_PROC_BROWSER_TEST_F(ExtensionSettingsUIBrowserTest, ViewSource) { + // Navigate to an in-page (guest-view-based) extension options page + // and grab the WebContents hosting the options page. + const extensions::Extension* extension = InstallExtensionWithInPageOptions(); + GURL options_url("chrome://extensions/?options=" + extension->id()); + content::WebContents* options_contents = nullptr; + { + content::WebContentsAddedObserver options_contents_added_observer; + ui_test_utils::NavigateToURL(browser(), options_url); + options_contents = options_contents_added_observer.GetWebContents(); + } + ASSERT_TRUE(options_contents); + content::WaitForLoadStop(options_contents); + EXPECT_EQ(extension->GetResourceURL("options.html"), + options_contents->GetLastCommittedURL()); + + // Open the view-source of the options page. + int old_tabs_count = browser()->tab_strip_model()->count(); + content::WebContentsAddedObserver view_source_contents_added_observer; + options_contents->GetMainFrame()->ViewSource(); + content::WebContents* view_source_contents = + view_source_contents_added_observer.GetWebContents(); + ASSERT_TRUE(view_source_contents); + content::WaitForLoadStop(view_source_contents); + + // Verify that the view-source is present in the tab-strip. + int new_tabs_count = browser()->tab_strip_model()->count(); + EXPECT_EQ(new_tabs_count, old_tabs_count + 1); + EXPECT_EQ(view_source_contents, + browser()->tab_strip_model()->GetActiveWebContents()); + + // Verify the contents of the view-source tab. + std::string actual_source_text; + std::string view_source_extraction_script = R"( + output = ""; + document.querySelectorAll(".line-content").forEach(function(elem) { + output += elem.innerText; + }); + domAutomationController.send(output); )"; + EXPECT_TRUE(content::ExecuteScriptAndExtractString( + view_source_contents, view_source_extraction_script, + &actual_source_text)); + base::FilePath source_path = + test_data_dir().AppendASCII("options_page_in_view/options.html"); + std::string expected_source_text; + { + base::ScopedAllowBlockingForTesting scoped_allow_blocking; + EXPECT_TRUE(base::ReadFileToString(source_path, &expected_source_text)); + } + EXPECT_TRUE( + base::RemoveChars(expected_source_text, "\n", &expected_source_text)); + EXPECT_EQ(expected_source_text, actual_source_text); +}
diff --git a/chrome/browser/ui/webui/extensions/extension_settings_browsertest.h b/chrome/browser/ui/webui/extensions/extension_settings_browsertest.h index a971fcbc..6a2a64c 100644 --- a/chrome/browser/ui/webui/extensions/extension_settings_browsertest.h +++ b/chrome/browser/ui/webui/extensions/extension_settings_browsertest.h
@@ -39,7 +39,9 @@ void InstallPlatformApp(); - void InstallExtensionWithInPageOptions(); + // Installs chrome/test/data/extensions/options_page_in_view extension + // and returns it back to the caller. Can return null upon failure. + const extensions::Extension* InstallExtensionWithInPageOptions(); void AddManagedPolicyProvider(); @@ -51,6 +53,8 @@ // Shrinks the web contents view in order to ensure vertical overflow. void ShrinkWebContentsView(); + const base::FilePath& test_data_dir() { return test_data_dir_; } + private: const extensions::Extension* InstallExtension(const base::FilePath& path);
diff --git a/chrome/service/service_utility_process_host.cc b/chrome/service/service_utility_process_host.cc index e54e6cd..e991854 100644 --- a/chrome/service/service_utility_process_host.cc +++ b/chrome/service/service_utility_process_host.cc
@@ -7,6 +7,7 @@ #include <stdint.h> #include <utility> +#include <vector> #include "base/bind.h" #include "base/command_line.h" @@ -24,7 +25,6 @@ #include "base/task_runner_util.h" #include "base/threading/thread_task_runner_handle.h" #include "base/win/win_util.h" -#include "build/build_config.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/chrome_utility_printing_messages.h" #include "content/public/common/child_process_host.h" @@ -95,8 +95,7 @@ class ServiceUtilityProcessHost::PdfToEmfState { public: - explicit PdfToEmfState(ServiceUtilityProcessHost* host) - : host_(host), page_count_(0), current_page_(0), pages_in_progress_(0) {} + explicit PdfToEmfState(ServiceUtilityProcessHost* host) : host_(host) {} ~PdfToEmfState() { Stop(); } bool Start(base::File pdf_file, @@ -162,11 +161,11 @@ } base::ScopedTempDir temp_dir_; - ServiceUtilityProcessHost* host_; + ServiceUtilityProcessHost* const host_; base::queue<base::File> emf_files_; - int page_count_; - int current_page_; - int pages_in_progress_; + int page_count_ = 0; + int current_page_ = 0; + int pages_in_progress_ = 0; }; ServiceUtilityProcessHost::ServiceUtilityProcessHost( @@ -196,7 +195,7 @@ DCHECK(!waiting_for_reply_); waiting_for_reply_ = true; - pdf_to_emf_state_.reset(new PdfToEmfState(this)); + pdf_to_emf_state_ = std::make_unique<PdfToEmfState>(this); return pdf_to_emf_state_->Start(std::move(pdf_file), render_settings); } @@ -388,12 +387,10 @@ void ServiceUtilityProcessHost::OnPDFToEmfFinished(bool success) { if (!waiting_for_reply_) return; + waiting_for_reply_ = false; - if (success) { - ReportUmaEvent(SERVICE_UTILITY_METAFILE_SUCCEEDED); - } else { - ReportUmaEvent(SERVICE_UTILITY_METAFILE_FAILED); - } + ReportUmaEvent(success ? SERVICE_UTILITY_METAFILE_SUCCEEDED + : SERVICE_UTILITY_METAFILE_FAILED); client_task_runner_->PostTask( FROM_HERE, base::Bind(&Client::OnRenderPDFPagesToMetafileDone, client_.get(), success));
diff --git a/content/browser/renderer_host/render_widget_host_input_event_router.cc b/content/browser/renderer_host/render_widget_host_input_event_router.cc index a261ebdc..eb2bc32 100644 --- a/content/browser/renderer_host/render_widget_host_input_event_router.cc +++ b/content/browser/renderer_host/render_widget_host_input_event_router.cc
@@ -26,7 +26,7 @@ namespace { void TransformEventTouchPositions(blink::WebTouchEvent* event, - const gfx::Vector2d& delta) { + const gfx::Vector2dF& delta) { for (unsigned i = 0; i < event->touches_length; ++i) { event->touches[i].SetPositionInWidget( event->touches[i].PositionInWidget().x + delta.x(), @@ -233,20 +233,6 @@ RenderWidgetHostViewBase* RenderWidgetHostInputEventRouter::FindViewAtLocation( RenderWidgetHostViewBase* root_view, - const gfx::Point& point, - const gfx::Point& point_in_screen, - viz::EventSource source, - gfx::Point* transformed_point) const { - gfx::PointF temp_point(*transformed_point); - RenderWidgetHostViewBase* view = - FindViewAtLocation(root_view, gfx::PointF(point), - gfx::PointF(point_in_screen), source, &temp_point); - *transformed_point = gfx::ToFlooredPoint(temp_point); - return view; -} - -RenderWidgetHostViewBase* RenderWidgetHostInputEventRouter::FindViewAtLocation( - RenderWidgetHostViewBase* root_view, const gfx::PointF& point, const gfx::PointF& point_in_screen, viz::EventSource source, @@ -365,8 +351,7 @@ wheel_target_.target = FindViewAtLocation( root_view, event->PositionInWidget(), event->PositionInScreen(), viz::EventSource::MOUSE, &transformed_point); - wheel_target_.delta = - gfx::ToFlooredVector2d(transformed_point - event->PositionInWidget()); + wheel_target_.delta = transformed_point - event->PositionInWidget(); target = wheel_target_.target; } else { if (wheel_target_.target) { @@ -494,10 +479,10 @@ // Since this is the first touch, it defines the target for the rest // of this sequence. DCHECK(!touch_target_.target); - gfx::Point transformed_point; - gfx::Point original_point(event->touches[0].PositionInWidget().x, - event->touches[0].PositionInWidget().y); - gfx::Point original_point_in_screen( + gfx::PointF transformed_point; + gfx::PointF original_point(event->touches[0].PositionInWidget().x, + event->touches[0].PositionInWidget().y); + gfx::PointF original_point_in_screen( event->touches[0].PositionInScreen().x, event->touches[0].PositionInScreen().y); touch_target_.target = FindViewAtLocation( @@ -1018,9 +1003,9 @@ // gesture start, then the target must be recalculated. if (event->unique_touch_event_id == 0 || (no_matching_id && is_gesture_start)) { - gfx::Point transformed_point; - gfx::Point original_point(event->x, event->y); - gfx::Point original_point_in_screen(event->global_x, event->global_y); + gfx::PointF transformed_point; + gfx::PointF original_point(event->x, event->y); + gfx::PointF original_point_in_screen(event->global_x, event->global_y); touchscreen_gesture_target_.target = FindViewAtLocation(root_view, original_point, original_point_in_screen, viz::EventSource::TOUCH, &transformed_point); @@ -1059,9 +1044,9 @@ if (event->GetType() == blink::WebInputEvent::kGesturePinchBegin || event->GetType() == blink::WebInputEvent::kGestureFlingStart) { - gfx::Point transformed_point; - gfx::Point original_point(event->x, event->y); - gfx::Point original_point_in_screen(event->global_x, event->global_y); + gfx::PointF transformed_point; + gfx::PointF original_point(event->x, event->y); + gfx::PointF original_point_in_screen(event->global_x, event->global_y); touchpad_gesture_target_.target = FindViewAtLocation(root_view, original_point, original_point_in_screen, viz::EventSource::TOUCH, &transformed_point);
diff --git a/content/browser/renderer_host/render_widget_host_input_event_router.h b/content/browser/renderer_host/render_widget_host_input_event_router.h index 7b8a2c8..b4b5d33 100644 --- a/content/browser/renderer_host/render_widget_host_input_event_router.h +++ b/content/browser/renderer_host/render_widget_host_input_event_router.h
@@ -124,7 +124,7 @@ viz::FrameSinkIdHash>; struct TargetData { RenderWidgetHostViewBase* target; - gfx::Vector2d delta; + gfx::Vector2dF delta; TargetData() : target(nullptr) {} }; @@ -138,13 +138,6 @@ RenderWidgetHostViewBase* FindViewAtLocation( RenderWidgetHostViewBase* root_view, - const gfx::Point& point, - const gfx::Point& point_in_screen, - viz::EventSource source, - gfx::Point* transformed_point) const; - - RenderWidgetHostViewBase* FindViewAtLocation( - RenderWidgetHostViewBase* root_view, const gfx::PointF& point, const gfx::PointF& point_in_screen, viz::EventSource source,
diff --git a/extensions/browser/guest_view/extension_options/extension_options_guest.cc b/extensions/browser/guest_view/extension_options/extension_options_guest.cc index 259fcba..1a74872 100644 --- a/extensions/browser/guest_view/extension_options/extension_options_guest.cc +++ b/extensions/browser/guest_view/extension_options/extension_options_guest.cc
@@ -152,6 +152,20 @@ options.ToValue())); } +void ExtensionOptionsGuest::AddNewContents(WebContents* source, + WebContents* new_contents, + WindowOpenDisposition disposition, + const gfx::Rect& initial_rect, + bool user_gesture, + bool* was_blocked) { + if (!attached() || !embedder_web_contents()->GetDelegate()) + return; + + embedder_web_contents()->GetDelegate()->AddNewContents( + source, new_contents, disposition, initial_rect, user_gesture, + was_blocked); +} + WebContents* ExtensionOptionsGuest::OpenURLFromTab( WebContents* source, const content::OpenURLParams& params) {
diff --git a/extensions/browser/guest_view/extension_options/extension_options_guest.h b/extensions/browser/guest_view/extension_options/extension_options_guest.h index ed9e3bb..12250fc1 100644 --- a/extensions/browser/guest_view/extension_options/extension_options_guest.h +++ b/extensions/browser/guest_view/extension_options/extension_options_guest.h
@@ -7,6 +7,8 @@ #include <stdint.h> +#include <memory> + #include "base/macros.h" #include "components/guest_view/browser/guest_view.h" #include "extensions/browser/guest_view/extension_options/extension_options_guest_delegate.h" @@ -36,6 +38,12 @@ void OnPreferredSizeChanged(const gfx::Size& pref_size) final; // content::WebContentsDelegate implementation. + void AddNewContents(content::WebContents* source, + content::WebContents* new_contents, + WindowOpenDisposition disposition, + const gfx::Rect& initial_rect, + bool user_gesture, + bool* was_blocked) final; content::WebContents* OpenURLFromTab( content::WebContents* source, const content::OpenURLParams& params) final;
diff --git a/third_party/WebKit/Source/core/editing/SurroundingTextTest.cpp b/third_party/WebKit/Source/core/editing/SurroundingTextTest.cpp index a42052aa..918310b 100644 --- a/third_party/WebKit/Source/core/editing/SurroundingTextTest.cpp +++ b/third_party/WebKit/Source/core/editing/SurroundingTextTest.cpp
@@ -11,7 +11,6 @@ #include "core/editing/EphemeralRange.h" #include "core/editing/Position.h" #include "core/editing/SelectionTemplate.h" -#include "core/editing/VisibleSelection.h" #include "core/html/HTMLElement.h" #include "core/html/forms/TextControlElement.h" #include "core/testing/DummyPageHolder.h" @@ -23,8 +22,8 @@ protected: Document& GetDocument() const { return dummy_page_holder_->GetDocument(); } void SetHTML(const String&); - VisibleSelection Select(int offset) { return Select(offset, offset); } - VisibleSelection Select(int start, int end); + EphemeralRange Select(int offset) { return Select(offset, offset); } + EphemeralRange Select(int start, int end); private: void SetUp() override; @@ -41,21 +40,18 @@ GetDocument().UpdateStyleAndLayout(); } -VisibleSelection SurroundingTextTest::Select(int start, int end) { +EphemeralRange SurroundingTextTest::Select(int start, int end) { Element* element = GetDocument().getElementById("selection"); - return CreateVisibleSelection( - SelectionInDOMTree::Builder() - .Collapse(Position(ToText(element->firstChild()), start)) - .Extend(Position(ToText(element->firstChild()), end)) - .Build()); + return EphemeralRange(Position(element->firstChild(), start), + Position(element->firstChild(), end)); } TEST_F(SurroundingTextTest, BasicCaretSelection) { SetHTML(String("<p id='selection'>foo bar</p>")); { - VisibleSelection selection = Select(0); - SurroundingText surrounding_text(EphemeralRange(selection.Start()), 1); + EphemeralRange selection = Select(0); + SurroundingText surrounding_text(selection, 1); EXPECT_EQ("f", surrounding_text.Content()); EXPECT_EQ(0u, surrounding_text.StartOffsetInContent()); @@ -63,8 +59,8 @@ } { - VisibleSelection selection = Select(0); - SurroundingText surrounding_text(EphemeralRange(selection.Start()), 5); + EphemeralRange selection = Select(0); + SurroundingText surrounding_text(selection, 5); // maxlength/2 is used on the left and right. EXPECT_EQ("foo", surrounding_text.Content().SimplifyWhiteSpace()); @@ -73,8 +69,8 @@ } { - VisibleSelection selection = Select(0); - SurroundingText surrounding_text(EphemeralRange(selection.Start()), 42); + EphemeralRange selection = Select(0); + SurroundingText surrounding_text(selection, 42); EXPECT_EQ("foo bar", surrounding_text.Content().SimplifyWhiteSpace()); EXPECT_EQ(1u, surrounding_text.StartOffsetInContent()); @@ -82,8 +78,8 @@ } { - VisibleSelection selection = Select(7); - SurroundingText surrounding_text(EphemeralRange(selection.Start()), 42); + EphemeralRange selection = Select(7); + SurroundingText surrounding_text(selection, 42); EXPECT_EQ("foo bar", surrounding_text.Content().SimplifyWhiteSpace()); EXPECT_EQ(8u, surrounding_text.StartOffsetInContent()); @@ -91,8 +87,8 @@ } { - VisibleSelection selection = Select(6); - SurroundingText surrounding_text(EphemeralRange(selection.Start()), 2); + EphemeralRange selection = Select(6); + SurroundingText surrounding_text(selection, 2); EXPECT_EQ("ar", surrounding_text.Content()); EXPECT_EQ(1u, surrounding_text.StartOffsetInContent()); @@ -100,8 +96,8 @@ } { - VisibleSelection selection = Select(6); - SurroundingText surrounding_text(EphemeralRange(selection.Start()), 42); + EphemeralRange selection = Select(6); + SurroundingText surrounding_text(selection, 42); EXPECT_EQ("foo bar", surrounding_text.Content().SimplifyWhiteSpace()); EXPECT_EQ(7u, surrounding_text.StartOffsetInContent()); @@ -113,8 +109,8 @@ SetHTML(String("<p id='selection'>Lorem ipsum dolor sit amet</p>")); { - VisibleSelection selection = Select(0, 5); - SurroundingText surrounding_text(FirstEphemeralRangeOf(selection), 1); + EphemeralRange selection = Select(0, 5); + SurroundingText surrounding_text(selection, 1); EXPECT_EQ("Lorem ", surrounding_text.Content()); EXPECT_EQ(0u, surrounding_text.StartOffsetInContent()); @@ -122,8 +118,8 @@ } { - VisibleSelection selection = Select(0, 5); - SurroundingText surrounding_text(FirstEphemeralRangeOf(selection), 5); + EphemeralRange selection = Select(0, 5); + SurroundingText surrounding_text(selection, 5); EXPECT_EQ("Lorem ip", surrounding_text.Content().SimplifyWhiteSpace()); EXPECT_EQ(1u, surrounding_text.StartOffsetInContent()); @@ -131,8 +127,8 @@ } { - VisibleSelection selection = Select(0, 5); - SurroundingText surrounding_text(FirstEphemeralRangeOf(selection), 42); + EphemeralRange selection = Select(0, 5); + SurroundingText surrounding_text(selection, 42); EXPECT_EQ("Lorem ipsum dolor sit amet", surrounding_text.Content().SimplifyWhiteSpace()); @@ -141,8 +137,8 @@ } { - VisibleSelection selection = Select(6, 11); - SurroundingText surrounding_text(FirstEphemeralRangeOf(selection), 2); + EphemeralRange selection = Select(6, 11); + SurroundingText surrounding_text(selection, 2); EXPECT_EQ(" ipsum ", surrounding_text.Content()); EXPECT_EQ(1u, surrounding_text.StartOffsetInContent()); @@ -150,8 +146,8 @@ } { - VisibleSelection selection = Select(6, 11); - SurroundingText surrounding_text(FirstEphemeralRangeOf(selection), 42); + EphemeralRange selection = Select(6, 11); + SurroundingText surrounding_text(selection, 42); EXPECT_EQ("Lorem ipsum dolor sit amet", surrounding_text.Content().SimplifyWhiteSpace()); @@ -161,8 +157,8 @@ { // Last word. - VisibleSelection selection = Select(22, 26); - SurroundingText surrounding_text(FirstEphemeralRangeOf(selection), 8); + EphemeralRange selection = Select(22, 26); + SurroundingText surrounding_text(selection, 8); EXPECT_EQ("sit amet", surrounding_text.Content()); EXPECT_EQ(4u, surrounding_text.StartOffsetInContent()); @@ -176,8 +172,8 @@ "selected node</div>")); { - VisibleSelection selection = Select(0); - SurroundingText surrounding_text(EphemeralRange(selection.Start()), 1); + EphemeralRange selection = Select(0); + SurroundingText surrounding_text(selection, 1); EXPECT_EQ("f", surrounding_text.Content()); EXPECT_EQ(0u, surrounding_text.StartOffsetInContent()); @@ -185,8 +181,8 @@ } { - VisibleSelection selection = Select(0); - SurroundingText surrounding_text(EphemeralRange(selection.Start()), 5); + EphemeralRange selection = Select(0); + SurroundingText surrounding_text(selection, 5); EXPECT_EQ("foo", surrounding_text.Content().SimplifyWhiteSpace()); EXPECT_EQ(1u, surrounding_text.StartOffsetInContent()); @@ -194,8 +190,8 @@ } { - VisibleSelection selection = Select(0); - SurroundingText surrounding_text(EphemeralRange(selection.Start()), 1337); + EphemeralRange selection = Select(0); + SurroundingText surrounding_text(selection, 1337); EXPECT_EQ("This is outside of foo bar the selected node", surrounding_text.Content().SimplifyWhiteSpace()); @@ -204,8 +200,8 @@ } { - VisibleSelection selection = Select(6); - SurroundingText surrounding_text(EphemeralRange(selection.Start()), 2); + EphemeralRange selection = Select(6); + SurroundingText surrounding_text(selection, 2); EXPECT_EQ("ar", surrounding_text.Content()); EXPECT_EQ(1u, surrounding_text.StartOffsetInContent()); @@ -213,8 +209,8 @@ } { - VisibleSelection selection = Select(6); - SurroundingText surrounding_text(EphemeralRange(selection.Start()), 1337); + EphemeralRange selection = Select(6); + SurroundingText surrounding_text(selection, 1337); EXPECT_EQ("This is outside of foo bar the selected node", surrounding_text.Content().SimplifyWhiteSpace()); @@ -229,8 +225,8 @@ "selected node</div>")); { - VisibleSelection selection = Select(0, 1); - SurroundingText surrounding_text(FirstEphemeralRangeOf(selection), 1); + EphemeralRange selection = Select(0, 1); + SurroundingText surrounding_text(selection, 1); EXPECT_EQ("fo", surrounding_text.Content().SimplifyWhiteSpace()); EXPECT_EQ(0u, surrounding_text.StartOffsetInContent()); @@ -238,8 +234,8 @@ } { - VisibleSelection selection = Select(0, 3); - SurroundingText surrounding_text(FirstEphemeralRangeOf(selection), 12); + EphemeralRange selection = Select(0, 3); + SurroundingText surrounding_text(selection, 12); EXPECT_EQ("e of foo bar", surrounding_text.Content().SimplifyWhiteSpace()); EXPECT_EQ(5u, surrounding_text.StartOffsetInContent()); @@ -247,8 +243,8 @@ } { - VisibleSelection selection = Select(0, 3); - SurroundingText surrounding_text(FirstEphemeralRangeOf(selection), 1337); + EphemeralRange selection = Select(0, 3); + SurroundingText surrounding_text(selection, 1337); EXPECT_EQ("This is outside of foo bar the selected node", surrounding_text.Content().SimplifyWhiteSpace()); @@ -257,8 +253,8 @@ } { - VisibleSelection selection = Select(4, 7); - SurroundingText surrounding_text(FirstEphemeralRangeOf(selection), 12); + EphemeralRange selection = Select(4, 7); + SurroundingText surrounding_text(selection, 12); EXPECT_EQ("foo bar the se", surrounding_text.Content().SimplifyWhiteSpace()); @@ -267,8 +263,8 @@ } { - VisibleSelection selection = Select(0, 7); - SurroundingText surrounding_text(FirstEphemeralRangeOf(selection), 1337); + EphemeralRange selection = Select(0, 7); + SurroundingText surrounding_text(selection, 1337); EXPECT_EQ("This is outside of foo bar the selected node", surrounding_text.Content().SimplifyWhiteSpace()); @@ -287,9 +283,9 @@ (TextControlElement*)GetDocument().getElementById("selection"); text_ctrl->SetSelectionRange(4, 7); - VisibleSelection selection = CreateVisibleSelection(text_ctrl->Selection()); + EphemeralRange selection = text_ctrl->Selection().ComputeRange(); - SurroundingText surrounding_text(FirstEphemeralRangeOf(selection), 20); + SurroundingText surrounding_text(selection, 20); EXPECT_EQ("abc def ghi", surrounding_text.Content().SimplifyWhiteSpace()); EXPECT_EQ(4u, surrounding_text.StartOffsetInContent());
diff --git a/tools/gn/config.cc b/tools/gn/config.cc index 953e677..e021fe4 100644 --- a/tools/gn/config.cc +++ b/tools/gn/config.cc
@@ -8,8 +8,10 @@ #include "tools/gn/input_file_manager.h" #include "tools/gn/scheduler.h" -Config::Config(const Settings* settings, const Label& label) - : Item(settings, label), resolved_(false) {} +Config::Config(const Settings* settings, + const Label& label, + const std::set<SourceFile>& build_dependency_files) + : Item(settings, label, build_dependency_files), resolved_(false) {} Config::~Config() = default;
diff --git a/tools/gn/config.h b/tools/gn/config.h index 20cfe7e4..ad049737 100644 --- a/tools/gn/config.h +++ b/tools/gn/config.h
@@ -5,6 +5,8 @@ #ifndef TOOLS_GN_CONFIG_H_ #define TOOLS_GN_CONFIG_H_ +#include <set> + #include "base/logging.h" #include "base/macros.h" #include "tools/gn/config_values.h" @@ -21,7 +23,11 @@ // flags. class Config : public Item { public: - Config(const Settings* settings, const Label& label); + // We track the set of build files that may affect this config, please refer + // to Scope for how this is determined. + Config(const Settings* settings, + const Label& label, + const std::set<SourceFile>& build_dependency_files = {}); ~Config() override; // Item implementation.
diff --git a/tools/gn/function_toolchain.cc b/tools/gn/function_toolchain.cc index 9fcf1f6..230f77f 100644 --- a/tools/gn/function_toolchain.cc +++ b/tools/gn/function_toolchain.cc
@@ -454,8 +454,8 @@ // This object will actually be copied into the one owned by the toolchain // manager, but that has to be done in the lock. - std::unique_ptr<Toolchain> toolchain = - std::make_unique<Toolchain>(scope->settings(), label); + std::unique_ptr<Toolchain> toolchain = std::make_unique<Toolchain>( + scope->settings(), label, scope->build_dependency_files()); toolchain->set_defined_from(function); toolchain->visibility().SetPublic();
diff --git a/tools/gn/functions.cc b/tools/gn/functions.cc index 60a6eb7..38b3020 100644 --- a/tools/gn/functions.cc +++ b/tools/gn/functions.cc
@@ -338,8 +338,8 @@ g_scheduler->Log("Defining config", label.GetUserVisibleName(true)); // Create the new config. - std::unique_ptr<Config> config = - std::make_unique<Config>(scope->settings(), label); + std::unique_ptr<Config> config = std::make_unique<Config>( + scope->settings(), label, scope->build_dependency_files()); config->set_defined_from(function); if (!Visibility::FillItemVisibility(config.get(), scope, err)) return Value(); @@ -633,6 +633,7 @@ SourceFile import_file = input_dir.ResolveRelativeFile(args[0], err, scope->settings()->build_settings()->root_path_utf8()); + scope->AddBuildDependencyFile(import_file); if (!err->has_error()) { scope->settings()->import_manager().DoImport(import_file, function, scope, err); @@ -910,7 +911,8 @@ } // Create the new pool. - std::unique_ptr<Pool> pool = std::make_unique<Pool>(scope->settings(), label); + std::unique_ptr<Pool> pool = std::make_unique<Pool>( + scope->settings(), label, scope->build_dependency_files()); pool->set_depth(depth->int_value()); // Save the generated item.
diff --git a/tools/gn/item.cc b/tools/gn/item.cc index 31abcdb..f36ff02 100644 --- a/tools/gn/item.cc +++ b/tools/gn/item.cc
@@ -7,8 +7,13 @@ #include "base/logging.h" #include "tools/gn/settings.h" -Item::Item(const Settings* settings, const Label& label) - : settings_(settings), label_(label), defined_from_(nullptr) {} +Item::Item(const Settings* settings, + const Label& label, + const std::set<SourceFile>& build_dependency_files) + : settings_(settings), + label_(label), + build_dependency_files_(build_dependency_files), + defined_from_(nullptr) {} Item::~Item() = default;
diff --git a/tools/gn/item.h b/tools/gn/item.h index 3ec482a..9195b5e 100644 --- a/tools/gn/item.h +++ b/tools/gn/item.h
@@ -5,15 +5,18 @@ #ifndef TOOLS_GN_ITEM_H_ #define TOOLS_GN_ITEM_H_ +#include <set> #include <string> #include "tools/gn/label.h" +#include "tools/gn/source_file.h" #include "tools/gn/visibility.h" class Config; class ParseNode; class Pool; class Settings; +class SourceFile; class Target; class Toolchain; @@ -21,7 +24,9 @@ // graph. class Item { public: - Item(const Settings* settings, const Label& label); + Item(const Settings* settings, + const Label& label, + const std::set<SourceFile>& build_dependency_files = {}); virtual ~Item(); const Settings* settings() const { return settings_; } @@ -50,6 +55,12 @@ // be used in logging and error messages. std::string GetItemTypeName() const; + // Returns the set of build files that may affect this item, please refer to + // Scope for how this is determined. + const std::set<SourceFile>& build_dependency_files() const { + return build_dependency_files_; + } + // Called when this item is resolved, meaning it and all of its dependents // have no unresolved deps. Returns true on success. Sets the error and // returns false on failure. @@ -58,6 +69,7 @@ private: const Settings* settings_; Label label_; + const std::set<SourceFile> build_dependency_files_; const ParseNode* defined_from_; Visibility visibility_;
diff --git a/tools/gn/loader.cc b/tools/gn/loader.cc index 616a224..2e10c9a 100644 --- a/tools/gn/loader.cc +++ b/tools/gn/loader.cc
@@ -24,9 +24,7 @@ struct SourceFileAndOrigin { SourceFileAndOrigin(const SourceFile& f, const LocationRange& o) - : file(f), - origin(o) { - } + : file(f), origin(o) {} SourceFile file; LocationRange origin; @@ -39,9 +37,7 @@ struct LoaderImpl::LoadID { LoadID() = default; LoadID(const SourceFile& f, const Label& tc_name) - : file(f), - toolchain_name(tc_name) { - } + : file(f), toolchain_name(tc_name) {} bool operator<(const LoadID& other) const { if (file.value() == other.file.value()) @@ -61,9 +57,10 @@ ToolchainRecord(const BuildSettings* build_settings, const Label& toolchain_label, const Label& default_toolchain_label) - : settings(build_settings, - GetOutputSubdirName(toolchain_label, - toolchain_label == default_toolchain_label)), + : settings( + build_settings, + GetOutputSubdirName(toolchain_label, + toolchain_label == default_toolchain_label)), is_toolchain_loaded(false), is_config_loaded(false) { settings.set_default_toolchain_label(default_toolchain_label); @@ -111,7 +108,8 @@ const LocationRange& origin, const Label& in_toolchain_name) { const Label& toolchain_name = in_toolchain_name.is_null() - ? default_toolchain_label_ : in_toolchain_name; + ? default_toolchain_label_ + : in_toolchain_name; LoadID load_id(file, toolchain_name); if (!invocations_.insert(load_id).second) return; // Already in set, so this file was already loaded or schedulerd. @@ -253,6 +251,7 @@ Scope our_scope(settings->base_config()); ScopePerFileProvider per_file_provider(&our_scope, true); our_scope.set_source_dir(file_name.GetDir()); + our_scope.AddBuildDependencyFile(file_name); // Targets, etc. generated as part of running this file will end up here. Scope::ItemVector collected_items; @@ -294,9 +293,11 @@ Scope* base_config = settings->base_config(); base_config->set_source_dir(SourceDir("//")); + base_config->AddBuildDependencyFile( + settings->build_settings()->build_config_file()); - settings->build_settings()->build_args().SetupRootScope( - base_config, toolchain_overrides); + settings->build_settings()->build_args().SetupRootScope(base_config, + toolchain_overrides); base_config->SetProcessingBuildConfig(); @@ -306,7 +307,7 @@ base_config->SetProperty(kDefaultToolchainKey, &default_toolchain_label); ScopedTrace trace(TraceItem::TRACE_FILE_EXECUTE, - settings->build_settings()->build_config_file().value()); + settings->build_settings()->build_config_file().value()); trace.SetToolchain(settings->toolchain_label()); Err err; @@ -327,7 +328,8 @@ // The default toolchain must have been set in the default build config // file. if (default_toolchain_label.is_null()) { - g_scheduler->FailWithError(Err(Location(), + g_scheduler->FailWithError(Err( + Location(), "The default build config file did not call set_default_toolchain()", "If you don't call this, I can't figure out what toolchain to use\n" "for all of this code.")); @@ -423,6 +425,5 @@ return g_scheduler->input_file_manager()->AsyncLoadFile( origin, build_settings, file_name, callback, err); } - return async_load_file_.Run( - origin, build_settings, file_name, callback, err); + return async_load_file_.Run(origin, build_settings, file_name, callback, err); }
diff --git a/tools/gn/loader_unittest.cc b/tools/gn/loader_unittest.cc index 8f51a42..4b240c32 100644 --- a/tools/gn/loader_unittest.cc +++ b/tools/gn/loader_unittest.cc
@@ -20,6 +20,35 @@ namespace { +bool ItemContainsBuildDependencyFile(const Item* item, + const SourceFile& source_file) { + const auto& build_dependency_files = item->build_dependency_files(); + return build_dependency_files.end() != + build_dependency_files.find(source_file); +} + +class MockBuilder { + public: + void OnItemDefined(std::unique_ptr<Item> item); + std::vector<const Item*> GetAllItems() const; + + private: + std::vector<std::unique_ptr<Item>> items_; +}; + +void MockBuilder::OnItemDefined(std::unique_ptr<Item> item) { + items_.push_back(std::move(item)); +} + +std::vector<const Item*> MockBuilder::GetAllItems() const { + std::vector<const Item*> result; + for (const auto& item : items_) { + result.push_back(item.get()); + } + + return result; +} + class MockInputFileManager { public: typedef base::Callback<void(const ParseNode*)> Callback; @@ -119,6 +148,7 @@ protected: Scheduler scheduler_; BuildSettings build_settings_; + MockBuilder mock_builder_; MockInputFileManager mock_ifm_; }; @@ -184,3 +214,51 @@ EXPECT_FALSE(scheduler_.is_failed()); } + +TEST_F(LoaderTest, BuildDependencyFilesAreCollected) { + SourceFile build_config("//build/config/BUILDCONFIG.gn"); + SourceFile root_build("//BUILD.gn"); + build_settings_.set_build_config_file(build_config); + build_settings_.set_item_defined_callback(base::Bind( + &MockBuilder::OnItemDefined, base::Unretained(&mock_builder_))); + + scoped_refptr<LoaderImpl> loader(new LoaderImpl(&build_settings_)); + mock_ifm_.AddCannedResponse(build_config, + "set_default_toolchain(\"//tc:tc\")"); + mock_ifm_.AddCannedResponse(SourceFile("//test.gni"), "concurrent_jobs = 1"); + std::string root_build_content = + "executable(\"a\") { sources = [ \"a.cc\" ] }\n" + "config(\"b\") { configs = [\"//t:t\"] }\n" + "toolchain(\"c\") {}\n" + "pool(\"d\") { depth = 1 }"; + mock_ifm_.AddCannedResponse(root_build, root_build_content); + + loader->set_async_load_file(mock_ifm_.GetCallback()); + + // Request the root build file be loaded. This should kick off the default + // build config loading. + loader->Load(root_build, LocationRange(), Label()); + EXPECT_TRUE(mock_ifm_.HasOnePending(build_config)); + + // Completing the build config load should kick off the root build file load. + mock_ifm_.IssueAllPending(); + base::RunLoop().RunUntilIdle(); + EXPECT_TRUE(mock_ifm_.HasOnePending(root_build)); + + // Completing the root build file should define a target which must have + // set of source files hashes. + mock_ifm_.IssueAllPending(); + base::RunLoop().RunUntilIdle(); + + std::vector<const Item*> items = mock_builder_.GetAllItems(); + EXPECT_TRUE(items[0]->AsTarget()); + EXPECT_TRUE(ItemContainsBuildDependencyFile(items[0], root_build)); + EXPECT_TRUE(items[1]->AsConfig()); + EXPECT_TRUE(ItemContainsBuildDependencyFile(items[1], root_build)); + EXPECT_TRUE(items[2]->AsToolchain()); + EXPECT_TRUE(ItemContainsBuildDependencyFile(items[2], root_build)); + EXPECT_TRUE(items[3]->AsPool()); + EXPECT_TRUE(ItemContainsBuildDependencyFile(items[3], root_build)); + + EXPECT_FALSE(scheduler_.is_failed()); +}
diff --git a/tools/gn/scope.cc b/tools/gn/scope.cc index 444ce53..145d6ad7 100644 --- a/tools/gn/scope.cc +++ b/tools/gn/scope.cc
@@ -8,6 +8,7 @@ #include "base/logging.h" #include "tools/gn/parse_tree.h" +#include "tools/gn/source_file.h" #include "tools/gn/template.h" namespace { @@ -30,8 +31,7 @@ Scope::MergeOptions::MergeOptions() : clobber_existing(false), skip_private_vars(false), - mark_dest_used(false) { -} + mark_dest_used(false) {} Scope::MergeOptions::~MergeOptions() = default; @@ -51,14 +51,16 @@ mutable_containing_(parent), settings_(parent->settings()), mode_flags_(0), - item_collector_(nullptr) {} + item_collector_(nullptr), + build_dependency_files_(parent->build_dependency_files_) {} Scope::Scope(const Scope* parent) : const_containing_(parent), mutable_containing_(nullptr), settings_(parent->settings()), mode_flags_(0), - item_collector_(nullptr) {} + item_collector_(nullptr), + build_dependency_files_(parent->build_dependency_files_) {} Scope::~Scope() = default; @@ -121,8 +123,8 @@ // Search in the parent mutable scope if requested, but not const one. if (search_mode == SEARCH_NESTED && mutable_containing_) { - return mutable_containing_->GetMutableValue( - ident, Scope::SEARCH_NESTED, counts_as_used); + return mutable_containing_->GetMutableValue(ident, Scope::SEARCH_NESTED, + counts_as_used); } return nullptr; } @@ -247,7 +249,8 @@ bool Scope::CheckForUnusedVars(Err* err) const { for (const auto& pair : values_) { if (!pair.second.used) { - std::string help = "You set the variable \"" + pair.first.as_string() + + std::string help = + "You set the variable \"" + pair.first.as_string() + "\" here and it was unused before it went\nout of scope."; const BinaryOpNode* binary = pair.second.value.origin()->AsBinaryOp(); @@ -294,13 +297,16 @@ // Value present in both the source and the dest. std::string desc_string(desc_for_err); *err = Err(node_for_err, "Value collision.", - "This " + desc_string + " contains \"" + current_name.as_string() + - "\""); - err->AppendSubErr(Err(pair.second.value, "defined here.", - "Which would clobber the one in your current scope")); - err->AppendSubErr(Err(*existing_value, "defined here.", - "Executing " + desc_string + " should not conflict with anything " - "in the current\nscope unless the values are identical.")); + "This " + desc_string + " contains \"" + + current_name.as_string() + "\""); + err->AppendSubErr( + Err(pair.second.value, "defined here.", + "Which would clobber the one in your current scope")); + err->AppendSubErr( + Err(*existing_value, "defined here.", + "Executing " + desc_string + + " should not conflict with anything " + "in the current\nscope unless the values are identical.")); return false; } } @@ -333,12 +339,18 @@ // target defaults. std::string desc_string(desc_for_err); *err = Err(node_for_err, "Target defaults collision.", - "This " + desc_string + " contains target defaults for\n" - "\"" + current_name + "\" which would clobber one for the\n" - "same target type in your current scope. It's unfortunate that " - "I'm too stupid\nto tell you the location of where the target " - "defaults were set. Usually\nthis happens in the BUILDCONFIG.gn " - "file or in a related .gni file.\n"); + "This " + desc_string + + " contains target defaults for\n" + "\"" + + current_name + + "\" which would clobber one for the\n" + "same target type in your current scope. It's " + "unfortunate that " + "I'm too stupid\nto tell you the location of where " + "the target " + "defaults were set. Usually\nthis happens in the " + "BUILDCONFIG.gn " + "file or in a related .gni file.\n"); return false; } } @@ -357,8 +369,9 @@ // Sources assignment filter present in both the source and the dest. std::string desc_string(desc_for_err); *err = Err(node_for_err, "Assignment filter collision.", - "The " + desc_string + " contains a sources_assignment_filter " - "which\nwould clobber the one in your current scope."); + "The " + desc_string + + " contains a sources_assignment_filter " + "which\nwould clobber the one in your current scope."); return false; } } @@ -386,15 +399,16 @@ // same one. std::string desc_string(desc_for_err); *err = Err(node_for_err, "Template collision.", - "This " + desc_string + " contains a template \"" + - current_name + "\""); - err->AppendSubErr(Err(pair.second->GetDefinitionRange(), - "defined here.", - "Which would clobber the one in your current scope")); + "This " + desc_string + " contains a template \"" + + current_name + "\""); + err->AppendSubErr( + Err(pair.second->GetDefinitionRange(), "defined here.", + "Which would clobber the one in your current scope")); err->AppendSubErr(Err(existing_template->GetDefinitionRange(), - "defined here.", - "Executing " + desc_string + " should not conflict with anything " - "in the current\nscope.")); + "defined here.", + "Executing " + desc_string + + " should not conflict with anything " + "in the current\nscope.")); return false; } } @@ -403,6 +417,10 @@ dest->templates_[current_name] = pair.second; } + // Propogate build dependency files, + dest->build_dependency_files_.insert(build_dependency_files_.begin(), + build_dependency_files_.end()); + return true; } @@ -501,6 +519,10 @@ return source_dir_; } +void Scope::AddBuildDependencyFile(const SourceFile& build_dependency_file) { + build_dependency_files_.insert(build_dependency_file); +} + Scope::ItemVector* Scope::GetItemCollector() { if (item_collector_) return item_collector_;
diff --git a/tools/gn/scope.h b/tools/gn/scope.h index 8ad14ed..9e683d2 100644 --- a/tools/gn/scope.h +++ b/tools/gn/scope.h
@@ -22,6 +22,7 @@ class Item; class ParseNode; class Settings; +class SourceFile; class Template; // Scope for the script execution. @@ -284,6 +285,15 @@ const SourceDir& GetSourceDir() const; void set_source_dir(const SourceDir& d) { source_dir_ = d; } + // Set of files that may affect the execution of this scope. Note that this + // set is constructed conservatively, meanining that every file that can + // potentially affect this scope is included, but not necessarily every change + // to these files will affect this scope. + const std::set<SourceFile>& build_dependency_files() const { + return build_dependency_files_; + } + void AddBuildDependencyFile(const SourceFile& build_dependency_file); + // The item collector is where Items (Targets, Configs, etc.) go that have // been defined. If a scope can generate items, this non-owning pointer will // point to the storage for such items. The creator of this scope will be @@ -379,6 +389,8 @@ SourceDir source_dir_; + std::set<SourceFile> build_dependency_files_; + DISALLOW_COPY_AND_ASSIGN(Scope); };
diff --git a/tools/gn/scope_unittest.cc b/tools/gn/scope_unittest.cc index a90d725..ce3fe0b1 100644 --- a/tools/gn/scope_unittest.cc +++ b/tools/gn/scope_unittest.cc
@@ -2,10 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "tools/gn/scope.h" + #include "testing/gtest/include/gtest/gtest.h" #include "tools/gn/input_file.h" #include "tools/gn/parse_tree.h" -#include "tools/gn/scope.h" +#include "tools/gn/source_file.h" #include "tools/gn/template.h" #include "tools/gn/test_with_scope.h" @@ -22,8 +24,25 @@ return value->string_value() == expected_value; } +bool ContainsBuildDependencyFile(const Scope* scope, + const SourceFile& source_file) { + const auto& build_dependency_files = scope->build_dependency_files(); + return build_dependency_files.end() != + build_dependency_files.find(source_file); +} + } // namespace +TEST(Scope, InheritBuildDependencyFilesFromParent) { + TestWithScope setup; + SourceFile source_file = SourceFile("//a/BUILD.gn"); + setup.scope()->AddBuildDependencyFile(source_file); + + Scope new_scope(setup.scope()); + EXPECT_EQ(1U, new_scope.build_dependency_files().size()); + EXPECT_TRUE(ContainsBuildDependencyFile(&new_scope, source_file)); +} + TEST(Scope, NonRecursiveMergeTo) { TestWithScope setup; @@ -192,6 +211,24 @@ EXPECT_TRUE(new_scope.CheckForUnusedVars(&err)); EXPECT_FALSE(err.has_error()); } + + // Build dependency files are merged. + { + Scope from_scope(setup.settings()); + SourceFile source_file = SourceFile("//a/BUILD.gn"); + from_scope.AddBuildDependencyFile(source_file); + + Scope to_scope(setup.settings()); + EXPECT_FALSE(ContainsBuildDependencyFile(&to_scope, source_file)); + + Scope::MergeOptions options; + Err err; + EXPECT_TRUE(from_scope.NonRecursiveMergeTo(&to_scope, options, &assignment, + "error", &err)); + EXPECT_FALSE(err.has_error()); + EXPECT_EQ(1U, to_scope.build_dependency_files().size()); + EXPECT_TRUE(ContainsBuildDependencyFile(&to_scope, source_file)); + } } TEST(Scope, MakeClosure) {
diff --git a/tools/gn/setup.cc b/tools/gn/setup.cc index dea3eae..9bb0b71 100644 --- a/tools/gn/setup.cc +++ b/tools/gn/setup.cc
@@ -690,6 +690,7 @@ return false; } + dotfile_scope_.AddBuildDependencyFile(SourceFile("//.gn")); dotfile_root_->Execute(&dotfile_scope_, &err); if (err.has_error()) { err.PrintToStdout();
diff --git a/tools/gn/target.cc b/tools/gn/target.cc index d65e2658..5c5ff5c9 100644 --- a/tools/gn/target.cc +++ b/tools/gn/target.cc
@@ -273,8 +273,10 @@ future, do not rely on this behavior. )"; -Target::Target(const Settings* settings, const Label& label) - : Item(settings, label), +Target::Target(const Settings* settings, + const Label& label, + const std::set<SourceFile>& build_dependency_files) + : Item(settings, label, build_dependency_files), output_type_(UNKNOWN), output_prefix_override_(false), output_extension_set_(false),
diff --git a/tools/gn/target.h b/tools/gn/target.h index 1890a535..2c9dc35 100644 --- a/tools/gn/target.h +++ b/tools/gn/target.h
@@ -55,7 +55,11 @@ typedef std::vector<SourceFile> FileList; typedef std::vector<std::string> StringVector; - Target(const Settings* settings, const Label& label); + // We track the set of build files that may affect this target, please refer + // to Scope for how this is determined. + Target(const Settings* settings, + const Label& label, + const std::set<SourceFile>& build_dependency_files = {}); ~Target() override; // Returns a string naming the output type.
diff --git a/tools/gn/target_generator.cc b/tools/gn/target_generator.cc index 114bca7..c441f04f 100644 --- a/tools/gn/target_generator.cc +++ b/tools/gn/target_generator.cc
@@ -90,8 +90,8 @@ if (g_scheduler->verbose_logging()) g_scheduler->Log("Defining target", label.GetUserVisibleName(true)); - std::unique_ptr<Target> target = - std::make_unique<Target>(scope->settings(), label); + std::unique_ptr<Target> target = std::make_unique<Target>( + scope->settings(), label, scope->build_dependency_files()); target->set_defined_from(function_call); // Create and call out to the proper generator.
diff --git a/tools/gn/toolchain.cc b/tools/gn/toolchain.cc index ec02b3e..879acd94 100644 --- a/tools/gn/toolchain.cc +++ b/tools/gn/toolchain.cc
@@ -28,8 +28,10 @@ const char* Toolchain::kToolCompileXCAssets = "compile_xcassets"; const char* Toolchain::kToolAction = "action"; -Toolchain::Toolchain(const Settings* settings, const Label& label) - : Item(settings, label), setup_complete_(false) {} +Toolchain::Toolchain(const Settings* settings, + const Label& label, + const std::set<SourceFile>& build_dependency_files) + : Item(settings, label, build_dependency_files), setup_complete_(false) {} Toolchain::~Toolchain() = default;
diff --git a/tools/gn/toolchain.h b/tools/gn/toolchain.h index 368c2db..1e9bc2e 100644 --- a/tools/gn/toolchain.h +++ b/tools/gn/toolchain.h
@@ -77,7 +77,12 @@ // Loader::GetToolchainSettings(). Many toolchain objects may be created in a // given build, but only a few might be used, and the Loader is in charge of // this process. - Toolchain(const Settings* settings, const Label& label); + // + // We also track the set of build files that may affect this target, please + // refer to Scope for how this is determined. + Toolchain(const Settings* settings, + const Label& label, + const std::set<SourceFile>& build_dependency_files = {}); ~Toolchain() override; // Item overrides.
diff --git a/ui/display/display_layout.cc b/ui/display/display_layout.cc index 89b9719..814e252 100644 --- a/ui/display/display_layout.cc +++ b/ui/display/display_layout.cc
@@ -474,7 +474,7 @@ // DisplayLayout DisplayLayout::DisplayLayout() - : mirrored(false), default_unified(true), primary_id(kInvalidDisplayId) {} + : default_unified(true), primary_id(kInvalidDisplayId) {} DisplayLayout::~DisplayLayout() {} @@ -578,7 +578,6 @@ std::unique_ptr<DisplayLayout> copy(new DisplayLayout); for (const auto& placement : placement_list) copy->placement_list.push_back(placement); - copy->mirrored = mirrored; copy->default_unified = default_unified; copy->primary_id = primary_id; return copy; @@ -612,8 +611,6 @@ std::string DisplayLayout::ToString() const { std::stringstream s; s << "primary=" << primary_id; - if (mirrored) - s << ", mirrored"; if (default_unified) s << ", default_unified"; bool added = false;
diff --git a/ui/display/display_layout.h b/ui/display/display_layout.h index 9a59d32f..e269d589 100644 --- a/ui/display/display_layout.h +++ b/ui/display/display_layout.h
@@ -100,10 +100,6 @@ std::vector<DisplayPlacement> placement_list; - // TODO(crbug.com/791881) Remove this variable and related code. - // True if displays are mirrored. - bool mirrored; - // True if multi displays should default to unified mode. bool default_unified;
diff --git a/ui/display/display_layout_builder.cc b/ui/display/display_layout_builder.cc index add0d386..fc77eb40 100644 --- a/ui/display/display_layout_builder.cc +++ b/ui/display/display_layout_builder.cc
@@ -26,11 +26,6 @@ return *this; } -DisplayLayoutBuilder& DisplayLayoutBuilder::SetMirrored(bool mirrored) { - layout_->mirrored = mirrored; - return *this; -} - DisplayLayoutBuilder& DisplayLayoutBuilder::ClearPlacements() { layout_->placement_list.clear(); return *this;
diff --git a/ui/display/manager/display_layout_store.cc b/ui/display/manager/display_layout_store.cc index 5a69e56..d9913a1 100644 --- a/ui/display/manager/display_layout_store.cc +++ b/ui/display/manager/display_layout_store.cc
@@ -86,12 +86,6 @@ layouts_[list] = std::move(layout); } -bool DisplayLayoutStore::GetMirrorMode(const DisplayIdList& list) { - if (forced_mirror_mode_) - return true; - return GetRegisteredDisplayLayout(list).mirrored; -} - const DisplayLayout& DisplayLayoutStore::GetRegisteredDisplayLayout( const DisplayIdList& list) { DCHECK_GT(list.size(), 1u); @@ -104,19 +98,12 @@ return *layout; } -void DisplayLayoutStore::UpdateMultiDisplayState(const DisplayIdList& list, - bool mirrored, - bool default_unified) { +void DisplayLayoutStore::UpdateDefaultUnified(const DisplayIdList& list, + bool default_unified) { DCHECK(layouts_.find(list) != layouts_.end()); if (layouts_.find(list) == layouts_.end()) CreateDefaultDisplayLayout(list); - if (!forced_mirror_mode_) { - // Don't remember the mirrored status if it's forced by the - // force_mirror_mode_ flag because it'll always be mirrored - // regardless of the user setting. - layouts_[list]->mirrored = mirrored; - } layouts_[list]->default_unified = default_unified; }
diff --git a/ui/display/manager/display_layout_store.h b/ui/display/manager/display_layout_store.h index d8243b3..878e4cd 100644 --- a/ui/display/manager/display_layout_store.h +++ b/ui/display/manager/display_layout_store.h
@@ -33,19 +33,15 @@ void RegisterLayoutForDisplayIdList(const DisplayIdList& list, std::unique_ptr<DisplayLayout> layout); - // Returns true if it should enter mirror mode for given display |list|. - bool GetMirrorMode(const DisplayIdList& list); - // If no layout is registered, it creatas new layout using // |default_display_layout_|. const DisplayLayout& GetRegisteredDisplayLayout(const DisplayIdList& list); - // Update the multi display state in the display layout for + // Update the default unified desktop mode in the display layout for // |display_list|. This creates new display layout if no layout is // registered for |display_list|. - void UpdateMultiDisplayState(const DisplayIdList& display_list, - bool mirrored, - bool default_unified); + void UpdateDefaultUnified(const DisplayIdList& display_list, + bool default_unified); private: // Creates new layout for display list from |default_display_layout_|.
diff --git a/ui/display/manager/display_manager.cc b/ui/display/manager/display_manager.cc index db76846..412c49d 100644 --- a/ui/display/manager/display_manager.cc +++ b/ui/display/manager/display_manager.cc
@@ -1413,8 +1413,7 @@ MultiDisplayMode mode) { DCHECK_NE(MIRRORING, mode); DisplayIdList list = GetCurrentDisplayIdList(); - layout_store_->UpdateMultiDisplayState(list, IsInMirrorMode(), - mode == UNIFIED); + layout_store_->UpdateDefaultUnified(list, mode == UNIFIED); ReconfigureDisplays(); }
diff --git a/ui/display/manager/json_converter.cc b/ui/display/manager/json_converter.cc index 2520d1d..1d4c0a4 100644 --- a/ui/display/manager/json_converter.cc +++ b/ui/display/manager/json_converter.cc
@@ -18,7 +18,6 @@ namespace { // Persistent key names -const char kMirroredKey[] = "mirrored"; const char kDefaultUnifiedKey[] = "default_unified"; const char kPrimaryIdKey[] = "primary-id"; const char kDisplayPlacementKey[] = "display_placement"; @@ -151,8 +150,7 @@ if (!value.GetAsDictionary(&dict_value)) return false; - if (!UpdateFromDict(dict_value, kMirroredKey, &layout->mirrored) || - !UpdateFromDict(dict_value, kDefaultUnifiedKey, + if (!UpdateFromDict(dict_value, kDefaultUnifiedKey, &layout->default_unified) || !UpdateFromDict(dict_value, kPrimaryIdKey, &layout->primary_id)) { return false; @@ -172,7 +170,6 @@ if (!value->GetAsDictionary(&dict_value)) return false; - dict_value->SetBoolean(kMirroredKey, layout.mirrored); dict_value->SetBoolean(kDefaultUnifiedKey, layout.default_unified); dict_value->SetString(kPrimaryIdKey, base::Int64ToString(layout.primary_id));
diff --git a/ui/display/manager/json_converter_unittest.cc b/ui/display/manager/json_converter_unittest.cc index ec30d51..071f3cc 100644 --- a/ui/display/manager/json_converter_unittest.cc +++ b/ui/display/manager/json_converter_unittest.cc
@@ -16,7 +16,6 @@ TEST(JsonConverterTest, JsonFromToDisplayLayout) { DisplayLayout layout; layout.primary_id = 1; - layout.mirrored = true; layout.default_unified = false; layout.placement_list.push_back(DisplayPlacement()); layout.placement_list.push_back(DisplayPlacement()); @@ -35,7 +34,6 @@ const char data[] = "{\n" " \"primary-id\": \"1\",\n" - " \"mirrored\": true,\n" " \"default_unified\": false,\n" " \"display_placement\": [{\n" " \"display_id\": \"2\",\n" @@ -59,7 +57,6 @@ DisplayLayout read_layout; EXPECT_TRUE(JsonToDisplayLayout(*read_value, &read_layout)); - EXPECT_EQ(read_layout.mirrored, layout.mirrored); EXPECT_EQ(read_layout.primary_id, layout.primary_id); EXPECT_EQ(read_layout.default_unified, layout.default_unified); EXPECT_TRUE(read_layout.HasSamePlacementList(layout)); @@ -69,7 +66,6 @@ const char data[] = "{\n" " \"primary-id\": \"1\",\n" - " \"mirrored\": true,\n" " \"default_unified\": false,\n" " \"position\": \"bottom\",\n" " \"offset\": 20\n" @@ -83,7 +79,6 @@ DisplayLayout read_layout; EXPECT_TRUE(JsonToDisplayLayout(*read_value, &read_layout)); - EXPECT_EQ(true, read_layout.mirrored); EXPECT_EQ(1, read_layout.primary_id); EXPECT_FALSE(read_layout.default_unified); ASSERT_EQ(1u, read_layout.placement_list.size());
diff --git a/ui/display/mojo/display_layout.mojom b/ui/display/mojo/display_layout.mojom index e2a1e92c..77d3c50 100644 --- a/ui/display/mojo/display_layout.mojom +++ b/ui/display/mojo/display_layout.mojom
@@ -29,7 +29,6 @@ // Corresponds to display::DisplayLayout. struct DisplayLayout { - bool mirrored; bool default_unified; int64 primary_display_id; array<DisplayPlacement> placement_list;
diff --git a/ui/display/mojo/display_layout_struct_traits.cc b/ui/display/mojo/display_layout_struct_traits.cc index bd9086c..24a9d87 100644 --- a/ui/display/mojo/display_layout_struct_traits.cc +++ b/ui/display/mojo/display_layout_struct_traits.cc
@@ -98,7 +98,6 @@ if (!data.ReadPlacementList(&display_layout->placement_list)) return false; - display_layout->mirrored = data.mirrored(); display_layout->default_unified = data.default_unified(); display_layout->primary_id = data.primary_display_id();
diff --git a/ui/display/mojo/display_layout_struct_traits.h b/ui/display/mojo/display_layout_struct_traits.h index 1b9c453..45b109ad 100644 --- a/ui/display/mojo/display_layout_struct_traits.h +++ b/ui/display/mojo/display_layout_struct_traits.h
@@ -63,10 +63,6 @@ template <> struct StructTraits<display::mojom::DisplayLayoutDataView, std::unique_ptr<display::DisplayLayout>> { - static bool mirrored(const std::unique_ptr<display::DisplayLayout>& layout) { - return layout->mirrored; - } - static bool default_unified( const std::unique_ptr<display::DisplayLayout>& layout) { return layout->default_unified;
diff --git a/ui/display/mojo/display_struct_traits_unittest.cc b/ui/display/mojo/display_struct_traits_unittest.cc index 7dce3b3..3dd7d2e38 100644 --- a/ui/display/mojo/display_struct_traits_unittest.cc +++ b/ui/display/mojo/display_struct_traits_unittest.cc
@@ -50,7 +50,6 @@ const DisplayLayout& output) { EXPECT_NE(&input, &output); // Make sure they aren't the same object. EXPECT_EQ(input.placement_list, output.placement_list); - EXPECT_EQ(input.mirrored, output.mirrored); EXPECT_EQ(input.default_unified, output.default_unified); EXPECT_EQ(input.primary_id, output.primary_id); } @@ -193,7 +192,6 @@ auto input = std::make_unique<DisplayLayout>(); input->placement_list.push_back(placement); input->primary_id = kDisplayId2; - input->mirrored = false; input->default_unified = true; std::unique_ptr<DisplayLayout> output; @@ -221,7 +219,6 @@ input->placement_list.push_back(placement1); input->placement_list.push_back(placement2); input->primary_id = kDisplayId1; - input->mirrored = false; input->default_unified = false; std::unique_ptr<DisplayLayout> output; @@ -230,26 +227,6 @@ CheckDisplayLayoutsEqual(*input, *output); } -TEST(DisplayStructTraitsTest, DisplayLayoutTwoMirrored) { - DisplayPlacement placement; - placement.display_id = kDisplayId1; - placement.parent_display_id = kDisplayId2; - placement.position = DisplayPlacement::RIGHT; - placement.offset = 0; - placement.offset_reference = DisplayPlacement::TOP_LEFT; - - auto input = std::make_unique<DisplayLayout>(); - input->placement_list.push_back(placement); - input->primary_id = kDisplayId2; - input->mirrored = true; - input->default_unified = true; - - std::unique_ptr<DisplayLayout> output; - SerializeAndDeserialize<mojom::DisplayLayout>(input->Copy(), &output); - - CheckDisplayLayoutsEqual(*input, *output); -} - TEST(DisplayStructTraitsTest, BasicGammaRampRGBEntry) { const GammaRampRGBEntry input{259, 81, 16};
diff --git a/ui/events/ozone/device/device_manager_manual.cc b/ui/events/ozone/device/device_manager_manual.cc index c4a7099..8010870a 100644 --- a/ui/events/ozone/device/device_manager_manual.cc +++ b/ui/events/ozone/device/device_manager_manual.cc
@@ -46,6 +46,11 @@ void DeviceManagerManual::AddObserver(DeviceEventObserver* observer) { observers_.AddObserver(observer); + // Notify the new observer about existing devices. + for (const auto& path : devices_) { + DeviceEvent event(DeviceEvent::INPUT, DeviceEvent::ADD, path); + observer->OnDeviceEvent(event); + } } void DeviceManagerManual::RemoveObserver(DeviceEventObserver* observer) {
diff --git a/ui/views/BUILD.gn b/ui/views/BUILD.gn index fc4b4fd44..98f3162 100644 --- a/ui/views/BUILD.gn +++ b/ui/views/BUILD.gn
@@ -43,7 +43,7 @@ all_dependent_configs = [ ":flags" ] public = [ - "accessibility/native_view_accessibility.h", + "accessibility/view_accessibility.h", "accessible_pane_view.h", "animation/bounds_animator.h", "animation/bounds_animator_observer.h", @@ -249,6 +249,7 @@ ] sources = [ + "accessibility/view_accessibility.cc", "accessible_pane_view.cc", "animation/bounds_animator.cc", "animation/flood_fill_ink_drop_ripple.cc", @@ -703,8 +704,6 @@ "accessibility/native_view_accessibility_win.cc", "accessibility/native_view_accessibility_win.h", ] - } else { - sources += [ "accessibility/native_view_accessibility_stub.cc" ] } if (is_fuchsia) {
diff --git a/ui/views/accessibility/ax_view_obj_wrapper.cc b/ui/views/accessibility/ax_view_obj_wrapper.cc index f4ff851..f27df73 100644 --- a/ui/views/accessibility/ax_view_obj_wrapper.cc +++ b/ui/views/accessibility/ax_view_obj_wrapper.cc
@@ -9,6 +9,7 @@ #include "ui/accessibility/ax_node_data.h" #include "ui/events/event_utils.h" #include "ui/views/accessibility/ax_aura_obj_cache.h" +#include "ui/views/accessibility/view_accessibility.h" #include "ui/views/view.h" #include "ui/views/widget/widget.h" @@ -46,26 +47,8 @@ } void AXViewObjWrapper::Serialize(ui::AXNodeData* out_node_data) { - view_->GetAccessibleNodeData(out_node_data); - + view_->GetViewAccessibility().GetAccessibleNodeData(out_node_data); out_node_data->id = GetID(); - - if (view_->IsAccessibilityFocusable()) - out_node_data->AddState(ui::AX_STATE_FOCUSABLE); - if (!view_->visible()) - out_node_data->AddState(ui::AX_STATE_INVISIBLE); - - if (!out_node_data->HasStringAttribute(ui::AX_ATTR_DESCRIPTION)) { - base::string16 description; - view_->GetTooltipText(gfx::Point(), &description); - out_node_data->AddStringAttribute(ui::AX_ATTR_DESCRIPTION, - base::UTF16ToUTF8(description)); - } - - out_node_data->AddStringAttribute(ui::AX_ATTR_CLASS_NAME, - view_->GetClassName()); - - out_node_data->location = gfx::RectF(view_->GetBoundsInScreen()); } int32_t AXViewObjWrapper::GetID() {
diff --git a/ui/views/accessibility/native_view_accessibility_auralinux.cc b/ui/views/accessibility/native_view_accessibility_auralinux.cc index 8654dd57..ac7452f 100644 --- a/ui/views/accessibility/native_view_accessibility_auralinux.cc +++ b/ui/views/accessibility/native_view_accessibility_auralinux.cc
@@ -157,8 +157,7 @@ } // namespace // static -std::unique_ptr<NativeViewAccessibility> NativeViewAccessibility::Create( - View* view) { +std::unique_ptr<ViewAccessibility> ViewAccessibility::Create(View* view) { AuraLinuxApplication::GetInstance()->RegisterWidget(view->GetWidget()); return std::make_unique<NativeViewAccessibilityAuraLinux>(view); }
diff --git a/ui/views/accessibility/native_view_accessibility_base.cc b/ui/views/accessibility/native_view_accessibility_base.cc index 7571efc3..0f19b6b2 100644 --- a/ui/views/accessibility/native_view_accessibility_base.cc +++ b/ui/views/accessibility/native_view_accessibility_base.cc
@@ -5,7 +5,6 @@ #include "ui/views/accessibility/native_view_accessibility_base.h" #include "base/memory/ptr_util.h" -#include "base/strings/utf_string_conversions.h" #include "ui/accessibility/platform/ax_platform_node.h" #include "ui/events/event_utils.h" #include "ui/gfx/native_widget_types.h" @@ -57,7 +56,7 @@ } // namespace NativeViewAccessibilityBase::NativeViewAccessibilityBase(View* view) - : view_(view) { + : ViewAccessibility(view) { ax_node_ = ui::AXPlatformNode::Create(this); DCHECK(ax_node_); @@ -85,41 +84,30 @@ // ui::AXPlatformNodeDelegate const ui::AXNodeData& NativeViewAccessibilityBase::GetData() const { + // Clear it, then populate it. data_ = ui::AXNodeData(); + GetAccessibleNodeData(&data_); - // Views may misbehave if their widget is closed; return an unknown role - // rather than possibly crashing. - if (!view_->GetWidget() || view_->GetWidget()->IsClosed()) { - data_.role = ui::AX_ROLE_UNKNOWN; - data_.AddIntAttribute(ui::AX_ATTR_RESTRICTION, ui::AX_RESTRICTION_DISABLED); - return data_; - } - - view_->GetAccessibleNodeData(&data_); - data_.location = GetBoundsInScreen(); - base::string16 description; - view_->GetTooltipText(gfx::Point(), &description); - data_.AddStringAttribute(ui::AX_ATTR_DESCRIPTION, - base::UTF16ToUTF8(description)); - - if (view_->IsAccessibilityFocusable()) - data_.AddState(ui::AX_STATE_FOCUSABLE); - - if (!view_->enabled()) { - data_.AddIntAttribute(ui::AX_ATTR_RESTRICTION, ui::AX_RESTRICTION_DISABLED); - } - - if (!view_->IsDrawn()) + // View::IsDrawn is true if a View is visible and all of its ancestors are + // visible too, since invisibility inherits. + // + // TODO(dmazzoni): Maybe consider moving this to ViewAccessibility? + // This will require ensuring that Chrome OS invalidates the whole + // subtree when a View changes its visibility state. + if (!view()->IsDrawn()) data_.AddState(ui::AX_STATE_INVISIBLE); - if (view_->context_menu_controller()) - data_.AddAction(ui::AX_ACTION_SHOW_CONTEXT_MENU); - // Make sure this element is excluded from the a11y tree if there's a // focusable parent. All keyboard focusable elements should be leaf nodes. // Exceptions to this rule will themselves be accessibility focusable. - if (IsViewUnfocusableChildOfFocusableAncestor(view_)) + // + // TODO(dmazzoni): this code was added to support MacViews acccessibility, + // because we needed a way to mark a View as a leaf node in the + // accessibility tree. We need to replace this with a cross-platform + // solution that works for ChromeVox, too, and move it to ViewAccessibility. + if (IsViewUnfocusableChildOfFocusableAncestor(view())) data_.role = ui::AX_ROLE_IGNORED; + return data_; } @@ -129,7 +117,7 @@ } int NativeViewAccessibilityBase::GetChildCount() { - int child_count = view_->child_count(); + int child_count = view()->child_count(); std::vector<Widget*> child_widgets; PopulateChildWidgetVector(&child_widgets); @@ -144,10 +132,10 @@ PopulateChildWidgetVector(&child_widgets); int child_widget_count = static_cast<int>(child_widgets.size()); - if (index < view_->child_count()) { - return view_->child_at(index)->GetNativeViewAccessible(); - } else if (index < view_->child_count() + child_widget_count) { - Widget* child_widget = child_widgets[index - view_->child_count()]; + if (index < view()->child_count()) { + return view()->child_at(index)->GetNativeViewAccessible(); + } else if (index < view()->child_count() + child_widget_count) { + Widget* child_widget = child_widgets[index - view()->child_count()]; return child_widget->GetRootView()->GetNativeViewAccessible(); } @@ -155,16 +143,16 @@ } gfx::NativeWindow NativeViewAccessibilityBase::GetTopLevelWidget() { - if (view_->GetWidget()) - return view_->GetWidget()->GetTopLevelWidget()->GetNativeWindow(); + if (view()->GetWidget()) + return view()->GetWidget()->GetTopLevelWidget()->GetNativeWindow(); return nullptr; } gfx::NativeViewAccessible NativeViewAccessibilityBase::GetParent() { - if (view_->parent()) - return view_->parent()->GetNativeViewAccessible(); + if (view()->parent()) + return view()->parent()->GetNativeViewAccessible(); - if (Widget* widget = view_->GetWidget()) { + if (Widget* widget = view()->GetWidget()) { Widget* top_widget = widget->GetTopLevelWidget(); if (top_widget && widget != top_widget && top_widget->GetRootView()) return top_widget->GetRootView()->GetNativeViewAccessible(); @@ -174,12 +162,12 @@ } gfx::Rect NativeViewAccessibilityBase::GetScreenBoundsRect() const { - return view_->GetBoundsInScreen(); + return view()->GetBoundsInScreen(); } gfx::NativeViewAccessible NativeViewAccessibilityBase::HitTestSync(int x, int y) { - if (!view_ || !view_->GetWidget()) + if (!view() || !view()->GetWidget()) return nullptr; // Search child widgets first, since they're on top in the z-order. @@ -194,20 +182,20 @@ } gfx::Point point(x, y); - View::ConvertPointFromScreen(view_, &point); - if (!view_->HitTestPoint(point)) + View::ConvertPointFromScreen(view(), &point); + if (!view()->HitTestPoint(point)) return nullptr; // Check if the point is within any of the immediate children of this // view. We don't have to search further because AXPlatformNode will // do a recursive hit test if we return anything other than |this| or NULL. - for (int i = view_->child_count() - 1; i >= 0; --i) { - View* child_view = view_->child_at(i); + for (int i = view()->child_count() - 1; i >= 0; --i) { + View* child_view = view()->child_at(i); if (!child_view->visible()) continue; gfx::Point point_in_child_coords(point); - view_->ConvertPointToTarget(view_, child_view, &point_in_child_coords); + view()->ConvertPointToTarget(view(), child_view, &point_in_child_coords); if (child_view->HitTestPoint(point_in_child_coords)) return child_view->GetNativeViewAccessible(); } @@ -217,7 +205,7 @@ } gfx::NativeViewAccessible NativeViewAccessibilityBase::GetFocus() { - FocusManager* focus_manager = view_->GetFocusManager(); + FocusManager* focus_manager = view()->GetFocusManager(); View* focused_view = focus_manager ? focus_manager->GetFocusedView() : nullptr; return focused_view ? focused_view->GetNativeViewAccessible() : nullptr; @@ -238,7 +226,7 @@ bool NativeViewAccessibilityBase::AccessibilityPerformAction( const ui::AXActionData& data) { - return view_->HandleAccessibleAction(data); + return view()->HandleAccessibleAction(data); } bool NativeViewAccessibilityBase::ShouldIgnoreHoveredStateForTesting() { @@ -251,16 +239,16 @@ } gfx::RectF NativeViewAccessibilityBase::GetBoundsInScreen() const { - return gfx::RectF(view_->GetBoundsInScreen()); + return gfx::RectF(view()->GetBoundsInScreen()); } void NativeViewAccessibilityBase::PopulateChildWidgetVector( std::vector<Widget*>* result_child_widgets) { // Only attach child widgets to the root view. - Widget* widget = view_->GetWidget(); + Widget* widget = view()->GetWidget(); // Note that during window close, a Widget may exist in a state where it has // no NativeView, but hasn't yet torn down its view hierarchy. - if (!widget || !widget->GetNativeView() || widget->GetRootView() != view_) + if (!widget || !widget->GetNativeView() || widget->GetRootView() != view()) return; std::set<Widget*> child_widgets;
diff --git a/ui/views/accessibility/native_view_accessibility_base.h b/ui/views/accessibility/native_view_accessibility_base.h index e3debc0..a471a78cc 100644 --- a/ui/views/accessibility/native_view_accessibility_base.h +++ b/ui/views/accessibility/native_view_accessibility_base.h
@@ -15,7 +15,7 @@ #include "ui/accessibility/platform/ax_platform_node.h" #include "ui/accessibility/platform/ax_platform_node_delegate.h" #include "ui/gfx/native_widget_types.h" -#include "ui/views/accessibility/native_view_accessibility.h" +#include "ui/views/accessibility/view_accessibility.h" #include "ui/views/views_export.h" #include "ui/views/widget/widget_observer.h" @@ -26,8 +26,9 @@ // Shared base class for platforms that require an implementation of // NativeViewAccessibility to interface with the native accessibility toolkit. +// This class owns the AXPlatformNode, which implements those native APIs. class VIEWS_EXPORT NativeViewAccessibilityBase - : public NativeViewAccessibility, + : public ViewAccessibility, public ui::AXPlatformNodeDelegate { public: ~NativeViewAccessibilityBase() override; @@ -56,9 +57,6 @@ protected: explicit NativeViewAccessibilityBase(View* view); - // Weak. Owns this. - View* view_; - protected: virtual gfx::RectF GetBoundsInScreen() const;
diff --git a/ui/views/accessibility/native_view_accessibility_mac.mm b/ui/views/accessibility/native_view_accessibility_mac.mm index 14235921..c6374ce 100644 --- a/ui/views/accessibility/native_view_accessibility_mac.mm +++ b/ui/views/accessibility/native_view_accessibility_mac.mm
@@ -13,8 +13,7 @@ namespace views { // static -std::unique_ptr<NativeViewAccessibility> NativeViewAccessibility::Create( - View* view) { +std::unique_ptr<ViewAccessibility> ViewAccessibility::Create(View* view) { return std::make_unique<NativeViewAccessibilityMac>(view); } @@ -22,11 +21,11 @@ : NativeViewAccessibilityBase(view) {} gfx::NativeViewAccessible NativeViewAccessibilityMac::GetParent() { - if (view_->parent()) - return view_->parent()->GetNativeViewAccessible(); + if (view()->parent()) + return view()->parent()->GetNativeViewAccessible(); - if (view_->GetWidget()) - return view_->GetWidget()->GetNativeView(); + if (view()->GetWidget()) + return view()->GetWidget()->GetNativeView(); return nullptr; }
diff --git a/ui/views/accessibility/native_view_accessibility_stub.cc b/ui/views/accessibility/native_view_accessibility_stub.cc deleted file mode 100644 index 3c4cda2..0000000 --- a/ui/views/accessibility/native_view_accessibility_stub.cc +++ /dev/null
@@ -1,15 +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 "ui/views/accessibility/native_view_accessibility.h" - -namespace views { - -// static -std::unique_ptr<NativeViewAccessibility> NativeViewAccessibility::Create( - View* view) { - return nullptr; -} - -} // namespace views
diff --git a/ui/views/accessibility/native_view_accessibility_unittest.cc b/ui/views/accessibility/native_view_accessibility_unittest.cc index b088174..5bf1eaaf 100644 --- a/ui/views/accessibility/native_view_accessibility_unittest.cc +++ b/ui/views/accessibility/native_view_accessibility_unittest.cc
@@ -44,11 +44,9 @@ button_ = new TestButton(); button_->SetSize(gfx::Size(20, 20)); - button_accessibility_ = NativeViewAccessibility::Create(button_); label_ = new Label(); button_->AddChildView(label_); - label_accessibility_ = NativeViewAccessibility::Create(label_); widget_->GetContentsView()->AddChildView(button_); widget_->Show(); @@ -62,12 +60,12 @@ NativeViewAccessibilityBase* button_accessibility() { return static_cast<NativeViewAccessibilityBase*>( - button_accessibility_.get()); + &button_->GetViewAccessibility()); } NativeViewAccessibilityBase* label_accessibility() { return static_cast<NativeViewAccessibilityBase*>( - label_accessibility_.get()); + &label_->GetViewAccessibility()); } bool SetFocused(NativeViewAccessibilityBase* view_accessibility, @@ -80,9 +78,7 @@ protected: Widget* widget_; TestButton* button_; - std::unique_ptr<NativeViewAccessibility> button_accessibility_; Label* label_; - std::unique_ptr<NativeViewAccessibility> label_accessibility_; DISALLOW_COPY_AND_ASSIGN(NativeViewAccessibilityTest); };
diff --git a/ui/views/accessibility/native_view_accessibility_win.cc b/ui/views/accessibility/native_view_accessibility_win.cc index 34e7f12..9fe2082 100644 --- a/ui/views/accessibility/native_view_accessibility_win.cc +++ b/ui/views/accessibility/native_view_accessibility_win.cc
@@ -48,8 +48,7 @@ } // namespace // static -std::unique_ptr<NativeViewAccessibility> NativeViewAccessibility::Create( - View* view) { +std::unique_ptr<ViewAccessibility> ViewAccessibility::Create(View* view) { return std::make_unique<NativeViewAccessibilityWin>(view); } @@ -60,12 +59,12 @@ gfx::NativeViewAccessible NativeViewAccessibilityWin::GetParent() { // If the View has a parent View, return that View's IAccessible. - if (view_->parent()) - return view_->parent()->GetNativeViewAccessible(); + if (view()->parent()) + return view()->parent()->GetNativeViewAccessible(); // Otherwise we must be the RootView, get the corresponding Widget // and Window. - Widget* widget = view_->GetWidget(); + Widget* widget = view()->GetWidget(); if (!widget) return nullptr; @@ -84,7 +83,7 @@ } // If that fails, return the NativeViewAccessible for our owning HWND. - HWND hwnd = HWNDForView(view_); + HWND hwnd = HWNDForView(view()); if (!hwnd) return nullptr; @@ -99,12 +98,12 @@ gfx::AcceleratedWidget NativeViewAccessibilityWin::GetTargetForNativeAccessibilityEvent() { - return HWNDForView(view_); + return HWNDForView(view()); } gfx::RectF NativeViewAccessibilityWin::GetBoundsInScreen() const { - gfx::RectF bounds = gfx::RectF(view_->GetBoundsInScreen()); - gfx::NativeView native_view = view_->GetWidget()->GetNativeView(); + gfx::RectF bounds = gfx::RectF(view()->GetBoundsInScreen()); + gfx::NativeView native_view = view()->GetWidget()->GetNativeView(); float device_scale = ui::GetScaleFactorForNativeView(native_view); bounds.Scale(device_scale); return bounds;
diff --git a/ui/views/accessibility/view_accessibility.cc b/ui/views/accessibility/view_accessibility.cc new file mode 100644 index 0000000..b8bd1c975 --- /dev/null +++ b/ui/views/accessibility/view_accessibility.cc
@@ -0,0 +1,98 @@ +// 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 "ui/views/accessibility/view_accessibility.h" + +#include "base/strings/utf_string_conversions.h" +#include "ui/base/ui_features.h" +#include "ui/views/view.h" +#include "ui/views/widget/widget.h" + +namespace views { + +namespace { + +bool IsValidRoleForViews(ui::AXRole role) { + switch (role) { + // These roles all have special meaning and shouldn't ever be + // set on a View. + case ui::AX_ROLE_DESKTOP: + case ui::AX_ROLE_NONE: + case ui::AX_ROLE_ROOT_WEB_AREA: + case ui::AX_ROLE_SVG_ROOT: + case ui::AX_ROLE_UNKNOWN: + case ui::AX_ROLE_WEB_AREA: + return false; + + default: + return true; + } +} + +} // namespace + +#if !BUILDFLAG_INTERNAL_HAS_NATIVE_ACCESSIBILITY() +// static +std::unique_ptr<ViewAccessibility> ViewAccessibility::Create(View* view) { + return base::WrapUnique(new ViewAccessibility(view)); +} +#endif + +ViewAccessibility::ViewAccessibility(View* view) : owner_view_(view) {} + +ViewAccessibility::~ViewAccessibility() {} + +void ViewAccessibility::GetAccessibleNodeData(ui::AXNodeData* data) const { + // Views may misbehave if their widget is closed; return an unknown role + // rather than possibly crashing. + if (!owner_view_->GetWidget() || owner_view_->GetWidget()->IsClosed()) { + data->role = ui::AX_ROLE_UNKNOWN; + data->AddIntAttribute(ui::AX_ATTR_RESTRICTION, ui::AX_RESTRICTION_DISABLED); + return; + } + + owner_view_->GetAccessibleNodeData(data); + if (custom_data_.role != ui::AX_ROLE_UNKNOWN) + data->role = custom_data_.role; + if (custom_data_.HasStringAttribute(ui::AX_ATTR_NAME)) + data->SetName(custom_data_.GetStringAttribute(ui::AX_ATTR_NAME)); + + data->location = gfx::RectF(owner_view_->GetBoundsInScreen()); + if (!data->HasStringAttribute(ui::AX_ATTR_DESCRIPTION)) { + base::string16 description; + owner_view_->GetTooltipText(gfx::Point(), &description); + data->AddStringAttribute(ui::AX_ATTR_DESCRIPTION, + base::UTF16ToUTF8(description)); + } + + data->AddStringAttribute(ui::AX_ATTR_CLASS_NAME, owner_view_->GetClassName()); + + if (owner_view_->IsAccessibilityFocusable()) + data->AddState(ui::AX_STATE_FOCUSABLE); + + if (!owner_view_->enabled()) + data->AddIntAttribute(ui::AX_ATTR_RESTRICTION, ui::AX_RESTRICTION_DISABLED); + + if (!owner_view_->visible()) + data->AddState(ui::AX_STATE_INVISIBLE); + + if (owner_view_->context_menu_controller()) + data->AddAction(ui::AX_ACTION_SHOW_CONTEXT_MENU); +} + +void ViewAccessibility::OverrideRole(ui::AXRole role) { + DCHECK(IsValidRoleForViews(role)); + + custom_data_.role = role; +} + +void ViewAccessibility::OverrideName(const std::string& name) { + custom_data_.SetName(name); +} + +gfx::NativeViewAccessible ViewAccessibility::GetNativeObject() { + return nullptr; +} + +} // namespace views
diff --git a/ui/views/accessibility/view_accessibility.h b/ui/views/accessibility/view_accessibility.h new file mode 100644 index 0000000..e26b34f --- /dev/null +++ b/ui/views/accessibility/view_accessibility.h
@@ -0,0 +1,70 @@ +// 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 UI_VIEWS_ACCESSIBILITY_VIEW_ACCESSIBILITY_H_ +#define UI_VIEWS_ACCESSIBILITY_VIEW_ACCESSIBILITY_H_ + +#include <memory> + +#include "base/macros.h" +#include "ui/accessibility/ax_enums.h" +#include "ui/accessibility/ax_node_data.h" +#include "ui/gfx/native_widget_types.h" +#include "ui/views/views_export.h" + +namespace views { + +class View; + +// An object that manages the accessibility interface for a View. +// +// The default accessibility properties of a View is determined by +// calling View::GetAccessibleNodeData(), which is overridden by many +// View subclasses. ViewAccessibility lets you override these for a +// particular view. +// +// On some platforms, subclasses of ViewAccessibility own the +// AXPlatformNode that implements the native accessibility APIs on that +// platform. +class VIEWS_EXPORT ViewAccessibility { + public: + static std::unique_ptr<ViewAccessibility> Create(View* view); + + virtual ~ViewAccessibility(); + + // Modifies |node_data| to reflect the current accessible state of the + // associated View, taking any custom overrides into account + // (see OverrideRole, etc. below). + virtual void GetAccessibleNodeData(ui::AXNodeData* node_data) const; + + // + // These override anything returned from View::GetAccessibleNodeData(). + // Note that string attributes are only used if non-empty, so you can't + // override a string with the empty string. + // + void OverrideRole(ui::AXRole role); + void OverrideName(const std::string& name); + + virtual gfx::NativeViewAccessible GetNativeObject(); + virtual void NotifyAccessibilityEvent(ui::AXEvent event_type) {} + + protected: + explicit ViewAccessibility(View* view); + + View* view() const { return owner_view_; } + + private: + // Weak. Owns this. + View* const owner_view_; + + // Contains data set explicitly via SetRole, SetName, etc. that overrides + // anything provided by GetAccessibleNodeData(). + ui::AXNodeData custom_data_; + + DISALLOW_COPY_AND_ASSIGN(ViewAccessibility); +}; + +} // namespace views + +#endif // UI_VIEWS_ACCESSIBILITY_VIEW_ACCESSIBILITY_H_
diff --git a/ui/views/controls/native/native_view_host.cc b/ui/views/controls/native/native_view_host.cc index fd7de908..2c5016d 100644 --- a/ui/views/controls/native/native_view_host.cc +++ b/ui/views/controls/native/native_view_host.cc
@@ -7,7 +7,6 @@ #include "base/logging.h" #include "ui/base/cursor/cursor.h" #include "ui/gfx/canvas.h" -#include "ui/views/accessibility/native_view_accessibility.h" #include "ui/views/controls/native/native_view_host_wrapper.h" #include "ui/views/widget/widget.h"
diff --git a/ui/views/view.cc b/ui/views/view.cc index 56734ae8..61c4d68 100644 --- a/ui/views/view.cc +++ b/ui/views/view.cc
@@ -46,7 +46,7 @@ #include "ui/gfx/skia_util.h" #include "ui/gfx/transform.h" #include "ui/native_theme/native_theme.h" -#include "ui/views/accessibility/native_view_accessibility.h" +#include "ui/views/accessibility/view_accessibility.h" #include "ui/views/background.h" #include "ui/views/border.h" #include "ui/views/context_menu_controller.h" @@ -1408,6 +1408,12 @@ // Accessibility---------------------------------------------------------------- +ViewAccessibility& View::GetViewAccessibility() { + if (!view_accessibility_) + view_accessibility_ = ViewAccessibility::Create(this); + return *view_accessibility_; +} + bool View::HandleAccessibleAction(const ui::AXActionData& action_data) { switch (action_data.action) { case ui::AX_ACTION_BLUR: @@ -1448,11 +1454,7 @@ } gfx::NativeViewAccessible View::GetNativeViewAccessible() { - if (!native_view_accessibility_) - native_view_accessibility_ = NativeViewAccessibility::Create(this); - if (native_view_accessibility_) - return native_view_accessibility_->GetNativeObject(); - return nullptr; + return GetViewAccessibility().GetNativeObject(); } void View::NotifyAccessibilityEvent( @@ -1461,12 +1463,8 @@ if (ViewsDelegate::GetInstance()) ViewsDelegate::GetInstance()->NotifyAccessibilityEvent(this, event_type); - if (send_native_event && GetWidget()) { - if (!native_view_accessibility_) - native_view_accessibility_ = NativeViewAccessibility::Create(this); - if (native_view_accessibility_) - native_view_accessibility_->NotifyAccessibilityEvent(event_type); - } + if (send_native_event && GetWidget()) + GetViewAccessibility().NotifyAccessibilityEvent(event_type); OnAccessibilityEvent(event_type); }
diff --git a/ui/views/view.h b/ui/views/view.h index a582753..4a4f120 100644 --- a/ui/views/view.h +++ b/ui/views/view.h
@@ -75,7 +75,7 @@ class FocusManager; class FocusTraversable; class LayoutManager; -class NativeViewAccessibility; +class ViewAccessibility; class ScrollView; class ViewObserver; class Widget; @@ -1095,6 +1095,9 @@ // Accessibility ------------------------------------------------------------- + // Get the object managing the accessibility interface for this View. + ViewAccessibility& GetViewAccessibility(); + // Modifies |node_data| to reflect the current accessible state of this view. virtual void GetAccessibleNodeData(ui::AXNodeData* node_data) {} @@ -1830,8 +1833,8 @@ // Accessibility ------------------------------------------------------------- - // The accessibility element used to represent this View. - std::unique_ptr<NativeViewAccessibility> native_view_accessibility_; + // Manages the accessibility interface for this View. + std::unique_ptr<ViewAccessibility> view_accessibility_; // Observers -------------------------------------------------------------