diff --git a/DEPS b/DEPS index 22e321bb..9fce461a 100644 --- a/DEPS +++ b/DEPS
@@ -40,11 +40,11 @@ # 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': '6e1e27b7fccd74d91d9bbc2a22bf55f2725f2a1b', + 'skia_revision': '8da9e940721168143d6296f578b6d7423de55d69', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. - 'v8_revision': 'fbffc377e396bd5c6d735f612c0dbcb784e7cd5d', + 'v8_revision': '5362e552a9186bfec815cacfb469bce66b4655fd', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling swarming_client # and whatever else without interference from each other. @@ -96,7 +96,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': '2ae07fc28bb3b248baa71647d5cfcefd67e57a84', + 'catapult_revision': 'faa1c3e0aeca393036f21a3722b75b245bb432c7', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other. @@ -303,7 +303,7 @@ Var('chromium_git') + '/external/github.com/cisco/openh264' + '@' + '0fd88df93c5dcaf858c57eb7892bd27763f0f0ac', 'src/third_party/re2/src': - Var('chromium_git') + '/external/github.com/google/re2.git' + '@' + 'db20d46c05900a12539225fe800dd860b14e0061', + Var('chromium_git') + '/external/github.com/google/re2.git' + '@' + 'ae9cb49a2e2ba95de4f0c6ec5a8afd039996d2c7', # Used for building libFuzzers (only supports Linux). 'src/third_party/libFuzzer/src':
diff --git a/android_webview/apk/java/proguard.flags b/android_webview/apk/java/proguard.flags index c4cf0a4..495d4861 100644 --- a/android_webview/apk/java/proguard.flags +++ b/android_webview/apk/java/proguard.flags
@@ -70,5 +70,11 @@ } -dontnote com.android.webview.chromium.AwSafeBrowsingApiHandler +#TODO(hush): remove after N release. crbug.com/546762 +-keep class com.android.webview.chromium.ContentSettingsAdapter { + public void setDisabledActionModeMenuItems(int); + public int getDisabledActionModeMenuItems(); +} + # We strip some unused resources when preprocessing the GMS client libs. -dontwarn com.google.android.gms.R**
diff --git a/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromium.java b/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromium.java index 99dd3fa..0ea0849 100644 --- a/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromium.java +++ b/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromium.java
@@ -63,6 +63,7 @@ import java.io.BufferedWriter; import java.io.File; import java.lang.reflect.Field; +import java.lang.reflect.Method; import java.util.Map; import java.util.concurrent.Callable; @@ -1729,7 +1730,8 @@ mAwContents.onConfigurationChanged(newConfig); } - @Override + //TODO(hush): add override after release. + //@Override public boolean onDragEvent(final DragEvent event) { mFactory.startYourEngines(false); if (checkNeedsPost()) { @@ -2211,7 +2213,15 @@ @Override public void super_startActivityForResult(Intent intent, int requestCode) { - mWebViewPrivate.super_startActivityForResult(intent, requestCode); + // TODO(hush): Use mWebViewPrivate.super_startActivityForResult + // after N release. crbug.com/543272. + try { + Method startActivityForResultMethod = + View.class.getMethod("startActivityForResult", Intent.class, int.class); + startActivityForResultMethod.invoke(mWebView, intent, requestCode); + } catch (Exception e) { + throw new RuntimeException("Invalid reflection", e); + } } @Override
diff --git a/android_webview/java/src/org/chromium/android_webview/AwContents.java b/android_webview/java/src/org/chromium/android_webview/AwContents.java index f4e1cfe..896e9b6 100644 --- a/android_webview/java/src/org/chromium/android_webview/AwContents.java +++ b/android_webview/java/src/org/chromium/android_webview/AwContents.java
@@ -2356,7 +2356,9 @@ void startProcessTextIntent(Intent intent) { // on Android M, WebView is not able to replace the text with the processed text. // So set the readonly flag for M. - if (Build.VERSION.SDK_INT == Build.VERSION_CODES.M) { + // TODO(hush): remove the part about VERSION.CODENAME equality with N, after N release. + // crbug.com/543272 + if (Build.VERSION.SDK_INT == Build.VERSION_CODES.M && !Build.VERSION.CODENAME.equals("N")) { intent.putExtra(Intent.EXTRA_PROCESS_TEXT_READONLY, true); }
diff --git a/android_webview/java/src/org/chromium/android_webview/AwSettings.java b/android_webview/java/src/org/chromium/android_webview/AwSettings.java index a49d01c..231091e2 100644 --- a/android_webview/java/src/org/chromium/android_webview/AwSettings.java +++ b/android_webview/java/src/org/chromium/android_webview/AwSettings.java
@@ -34,6 +34,9 @@ private static final String LOGTAG = AwSettings.class.getSimpleName(); private static final boolean TRACE = false; + // TODO(hush): Use android.webkit.WebSettings.MENU_ITEM_*. crbug.com/546762. + private static final int MENU_ITEM_NONE = 0; + private static final String TAG = "AwSettings"; // This class must be created on the UI thread. Afterwards, it can be @@ -86,7 +89,7 @@ private int mMixedContentMode = WebSettings.MIXED_CONTENT_NEVER_ALLOW; private boolean mOffscreenPreRaster; - private int mDisabledMenuItems = WebSettings.MENU_ITEM_NONE; + private int mDisabledMenuItems = MENU_ITEM_NONE; // Although this bit is stored on AwSettings it is actually controlled via the CookieManager. private boolean mAcceptThirdPartyCookies;
diff --git a/ash/common/system/status_area_widget.cc b/ash/common/system/status_area_widget.cc index 3c66000c..25b886e4 100644 --- a/ash/common/system/status_area_widget.cc +++ b/ash/common/system/status_area_widget.cc
@@ -82,6 +82,10 @@ // Destroy the trays early, causing them to be removed from the view // hierarchy. Do not used scoped pointers since we don't want to destroy them // in the destructor if Shutdown() is not called (e.g. in tests). + // Failure to remove the tray views causes layout crashes during shutdown, + // for example http://crbug.com/700122. + // TODO(jamescook): Find a better way to avoid the layout problems, fix the + // tests and switch to std::unique_ptr. http://crbug.com/700255 delete web_notification_tray_; web_notification_tray_ = nullptr; // Must be destroyed after |web_notification_tray_|. @@ -91,10 +95,14 @@ ime_menu_tray_ = nullptr; delete virtual_keyboard_tray_; virtual_keyboard_tray_ = nullptr; + delete palette_tray_; + palette_tray_ = nullptr; delete logout_button_tray_; logout_button_tray_ = nullptr; delete overview_button_tray_; overview_button_tray_ = nullptr; + // All child tray views have been removed. + DCHECK_EQ(0, GetContentsView()->child_count()); } void StatusAreaWidget::SetShelfAlignment(ShelfAlignment alignment) {
diff --git a/ash/common/wm/default_state.cc b/ash/common/wm/default_state.cc index 8149d7f..dbaf92d 100644 --- a/ash/common/wm/default_state.cc +++ b/ash/common/wm/default_state.cc
@@ -701,8 +701,9 @@ WmWindow* docked_container = window->GetRootWindow()->GetChildByShellWindowId( kShellWindowId_DockedContainer); - ReparentChildWithTransientChildren(window, window->GetParent(), - docked_container); + ReparentChildWithTransientChildren(window->aura_window(), + window->aura_window()->parent(), + docked_container->aura_window()); } // Return early because we don't want to update the bounds of the // window below; as the bounds are managed by the dock layout.
diff --git a/ash/common/wm/dock/docked_window_layout_manager.cc b/ash/common/wm/dock/docked_window_layout_manager.cc index c8920b40..d004da9 100644 --- a/ash/common/wm/dock/docked_window_layout_manager.cc +++ b/ash/common/wm/dock/docked_window_layout_manager.cc
@@ -25,6 +25,7 @@ #include "base/auto_reset.h" #include "base/metrics/histogram_macros.h" #include "third_party/skia/include/core/SkColor.h" +#include "ui/aura/window.h" #include "ui/base/resource/resource_bundle.h" #include "ui/compositor/scoped_layer_animation_settings.h" #include "ui/display/display.h" @@ -181,11 +182,11 @@ void UndockWindow(WmWindow* window) { gfx::Rect previous_bounds = window->GetBounds(); - WmWindow* old_parent = window->GetParent(); + aura::Window* old_parent = window->aura_window()->parent(); window->SetParentUsingContext(window, gfx::Rect()); - if (window->GetParent() != old_parent) { - wm::ReparentTransientChildrenOfChild(window, old_parent, - window->GetParent()); + if (window->aura_window()->parent() != old_parent) { + wm::ReparentTransientChildrenOfChild(window->aura_window(), old_parent, + window->aura_window()->parent()); } // Start maximize or fullscreen (affecting packaged apps) animation from // previous window bounds.
diff --git a/ash/common/wm/dock/docked_window_resizer.cc b/ash/common/wm/dock/docked_window_resizer.cc index f2ea238..e50ecd0 100644 --- a/ash/common/wm/dock/docked_window_resizer.cc +++ b/ash/common/wm/dock/docked_window_resizer.cc
@@ -188,8 +188,9 @@ WmWindow* docked_container = GetTarget()->GetRootWindow()->GetChildByShellWindowId( kShellWindowId_DockedContainer); - wm::ReparentChildWithTransientChildren( - GetTarget(), GetTarget()->GetParent(), docked_container); + wm::ReparentChildWithTransientChildren(GetTarget()->aura_window(), + GetTarget()->aura_window()->parent(), + docked_container->aura_window()); if (!resizer) return; } @@ -266,8 +267,9 @@ if ((is_resized || !is_attached_panel) && is_docked_ != (window->GetParent() == dock_container)) { if (is_docked_) { - wm::ReparentChildWithTransientChildren(window, window->GetParent(), - dock_container); + wm::ReparentChildWithTransientChildren(window->aura_window(), + window->aura_window()->parent(), + dock_container->aura_window()); action = DOCKED_ACTION_DOCK; } else if (window->GetParent()->GetShellWindowId() == kShellWindowId_DockedContainer) { @@ -279,11 +281,12 @@ // mouse is). gfx::Rect near_last_location(last_location_, gfx::Size()); // Reparenting will cause Relayout and possible dock shrinking. - WmWindow* previous_parent = window->GetParent(); + aura::Window* previous_parent = window->aura_window()->parent(); window->SetParentUsingContext(window, near_last_location); - if (window->GetParent() != previous_parent) { - wm::ReparentTransientChildrenOfChild(window, previous_parent, - window->GetParent()); + if (window->aura_window()->parent() != previous_parent) { + wm::ReparentTransientChildrenOfChild(window->aura_window(), + previous_parent, + window->aura_window()->parent()); } action = was_docked_ ? DOCKED_ACTION_UNDOCK : DOCKED_ACTION_NONE; }
diff --git a/ash/common/wm/panels/panel_layout_manager.cc b/ash/common/wm/panels/panel_layout_manager.cc index 66ddd3ce..ba2b0f8 100644 --- a/ash/common/wm/panels/panel_layout_manager.cc +++ b/ash/common/wm/panels/panel_layout_manager.cc
@@ -348,10 +348,11 @@ // back to appropriate container and ignore it. // TODO(varkha): Updating bounds during a drag can cause problems and a more // general solution is needed. See http://crbug.com/251813 . - WmWindow* old_parent = child->GetParent(); + aura::Window* old_parent = child->aura_window()->parent(); child->SetParentUsingContext(child, child->GetRootWindow()->GetBoundsInScreen()); - wm::ReparentTransientChildrenOfChild(child, old_parent, child->GetParent()); + wm::ReparentTransientChildrenOfChild(child->aura_window(), old_parent, + child->aura_window()->parent()); DCHECK(child->GetParent()->GetShellWindowId() != kShellWindowId_PanelContainer); return;
diff --git a/ash/common/wm/panels/panel_window_resizer.cc b/ash/common/wm/panels/panel_window_resizer.cc index e4047eb8..db2ad880 100644 --- a/ash/common/wm/panels/panel_window_resizer.cc +++ b/ash/common/wm/panels/panel_window_resizer.cc
@@ -161,11 +161,11 @@ // We use root window coordinates to ensure that during the drag the panel // is reparented to a container in the root window that has that window. WmWindow* target_root = target->GetRootWindow(); - WmWindow* old_parent = target->GetParent(); + aura::Window* old_parent = target->aura_window()->parent(); target->SetParentUsingContext(target_root, target_root->GetBoundsInScreen()); - wm::ReparentTransientChildrenOfChild(target, old_parent, - target->GetParent()); + wm::ReparentTransientChildrenOfChild(target->aura_window(), old_parent, + target->aura_window()->parent()); } } @@ -180,11 +180,11 @@ // is reparented to a container in the root window that has that location. WmWindow* target = GetTarget(); WmWindow* target_root = target->GetRootWindow(); - WmWindow* old_parent = target->GetParent(); + aura::Window* old_parent = target->aura_window()->parent(); target->SetParentUsingContext(target_root, - gfx::Rect(last_location_, gfx::Size())); - wm::ReparentTransientChildrenOfChild(target, old_parent, - target->GetParent()); + target_root->GetBoundsInScreen()); + wm::ReparentTransientChildrenOfChild(target->aura_window(), old_parent, + target->aura_window()->parent()); } // If we started the drag in one root window and moved into another root
diff --git a/ash/common/wm/window_parenting_utils.cc b/ash/common/wm/window_parenting_utils.cc index 8a868a22..7f035b8 100644 --- a/ash/common/wm/window_parenting_utils.cc +++ b/ash/common/wm/window_parenting_utils.cc
@@ -4,23 +4,26 @@ #include "ash/common/wm/window_parenting_utils.h" -#include "ash/common/wm_window.h" +#include "ui/aura/window.h" +#include "ui/wm/core/window_util.h" + +using aura::Window; namespace ash { namespace wm { -void ReparentChildWithTransientChildren(WmWindow* child, - WmWindow* old_parent, - WmWindow* new_parent) { - if (child->GetParent() == old_parent) +void ReparentChildWithTransientChildren(Window* child, + Window* old_parent, + Window* new_parent) { + if (child->parent() == old_parent) new_parent->AddChild(child); ReparentTransientChildrenOfChild(child, old_parent, new_parent); } -void ReparentTransientChildrenOfChild(WmWindow* child, - WmWindow* old_parent, - WmWindow* new_parent) { - for (WmWindow* transient_child : child->GetTransientChildren()) +void ReparentTransientChildrenOfChild(Window* child, + Window* old_parent, + Window* new_parent) { + for (Window* transient_child : ::wm::GetTransientChildren(child)) ReparentChildWithTransientChildren(transient_child, old_parent, new_parent); }
diff --git a/ash/common/wm/window_parenting_utils.h b/ash/common/wm/window_parenting_utils.h index 864e0aa1..0162d39 100644 --- a/ash/common/wm/window_parenting_utils.h +++ b/ash/common/wm/window_parenting_utils.h
@@ -5,24 +5,26 @@ #ifndef ASH_COMMON_WM_WINDOW_PARENTING_UTILS_H_ #define ASH_COMMON_WM_WINDOW_PARENTING_UTILS_H_ -namespace ash { +namespace aura { +class Window; +} -class WmWindow; +namespace ash { namespace wm { // Changes the parent of a |child| and all its transient children that are // themselves children of |old_parent| to |new_parent|. -void ReparentChildWithTransientChildren(WmWindow* child, - WmWindow* old_parent, - WmWindow* new_parent); +void ReparentChildWithTransientChildren(aura::Window* child, + aura::Window* old_parent, + aura::Window* new_parent); // Changes the parent of all transient children of a |child| to |new_parent|. // Does not change parent of the transient children that are not themselves // children of |old_parent|. -void ReparentTransientChildrenOfChild(WmWindow* child, - WmWindow* old_parent, - WmWindow* new_parent); +void ReparentTransientChildrenOfChild(aura::Window* child, + aura::Window* old_parent, + aura::Window* new_parent); } // namespace wm } // namespace ash
diff --git a/ash/focus_cycler_unittest.cc b/ash/focus_cycler_unittest.cc index 0780939..1c42b81 100644 --- a/ash/focus_cycler_unittest.cc +++ b/ash/focus_cycler_unittest.cc
@@ -13,7 +13,6 @@ #include "ash/common/system/tray/system_tray.h" #include "ash/common/wm_shell.h" #include "ash/test/ash_test_base.h" -#include "ash/test/status_area_widget_test_helper.h" #include "ash/wm/window_util.h" #include "ui/aura/test/test_windows.h" #include "ui/aura/window.h" @@ -79,12 +78,8 @@ } protected: - // Setup the system tray using StatusAreaWidgetTestHelper and focus_cycler. + // Setup the system tray focus cycler. void SetUpTrayFocusCycle() { - StatusAreaWidget* widget = - StatusAreaWidgetTestHelper::GetStatusAreaWidget(); - widget->CreateTrayViews(); - widget->Show(); views::Widget* system_tray_widget = GetPrimarySystemTray()->GetWidget(); ASSERT_TRUE(system_tray_widget); focus_cycler_->AddWidget(system_tray_widget);
diff --git a/ash/sticky_keys/sticky_keys_controller.cc b/ash/sticky_keys/sticky_keys_controller.cc index abbcaf4..d3257a8a 100644 --- a/ash/sticky_keys/sticky_keys_controller.cc +++ b/ash/sticky_keys/sticky_keys_controller.cc
@@ -25,18 +25,20 @@ } // Handle the common tail of event rewriting. -ui::EventRewriteStatus RewriteUpdate(bool consumed, - bool released, - int mod_down_flags, - int* flags) { - int changed_down_flags = mod_down_flags & ~*flags; - *flags |= mod_down_flags; +ui::EventRewriteStatus RewriteUpdate( + bool consumed, + bool released, + int mod_down_flags, + const ui::Event& event, + std::unique_ptr<ui::Event>* rewritten_event) { if (consumed) return ui::EVENT_REWRITE_DISCARD; - if (released) - return ui::EVENT_REWRITE_DISPATCH_ANOTHER; - if (changed_down_flags) - return ui::EVENT_REWRITE_REWRITTEN; + if (mod_down_flags & ~event.flags()) { + *rewritten_event = ui::Event::Clone(event); + (*rewritten_event)->set_flags(event.flags() | mod_down_flags); + return released ? ui::EVENT_REWRITE_DISPATCH_ANOTHER + : ui::EVENT_REWRITE_REWRITTEN; + } return ui::EVENT_REWRITE_CONTINUE; } @@ -82,84 +84,32 @@ } } -bool StickyKeysController::HandleKeyEvent(const ui::KeyEvent& event, - ui::KeyboardCode key_code, - int* mod_down_flags, - bool* released) { - return shift_sticky_key_->HandleKeyEvent(event, key_code, mod_down_flags, - released) || - alt_sticky_key_->HandleKeyEvent(event, key_code, mod_down_flags, - released) || - altgr_sticky_key_->HandleKeyEvent(event, key_code, mod_down_flags, - released) || - ctrl_sticky_key_->HandleKeyEvent(event, key_code, mod_down_flags, - released) || - mod3_sticky_key_->HandleKeyEvent(event, key_code, mod_down_flags, - released) || - search_sticky_key_->HandleKeyEvent(event, key_code, mod_down_flags, - released); +StickyKeysOverlay* StickyKeysController::GetOverlayForTest() { + return overlay_.get(); } -bool StickyKeysController::HandleMouseEvent(const ui::MouseEvent& event, - int* mod_down_flags, - bool* released) { - return shift_sticky_key_->HandleMouseEvent(event, mod_down_flags, released) || - alt_sticky_key_->HandleMouseEvent(event, mod_down_flags, released) || - altgr_sticky_key_->HandleMouseEvent(event, mod_down_flags, released) || - ctrl_sticky_key_->HandleMouseEvent(event, mod_down_flags, released) || - mod3_sticky_key_->HandleMouseEvent(event, mod_down_flags, released); -} - -bool StickyKeysController::HandleScrollEvent(const ui::ScrollEvent& event, - int* mod_down_flags, - bool* released) { - return shift_sticky_key_->HandleScrollEvent(event, mod_down_flags, - released) || - alt_sticky_key_->HandleScrollEvent(event, mod_down_flags, released) || - altgr_sticky_key_->HandleScrollEvent(event, mod_down_flags, - released) || - ctrl_sticky_key_->HandleScrollEvent(event, mod_down_flags, released) || - mod3_sticky_key_->HandleScrollEvent(event, mod_down_flags, released); -} - -ui::EventRewriteStatus StickyKeysController::RewriteKeyEvent( - const ui::KeyEvent& event, - ui::KeyboardCode key_code, - int* flags) { +ui::EventRewriteStatus StickyKeysController::RewriteEvent( + const ui::Event& event, + std::unique_ptr<ui::Event>* rewritten_event) { + DCHECK(rewritten_event); if (!enabled_) return ui::EVENT_REWRITE_CONTINUE; - int mod_down_flags = 0; - bool released = false; - bool consumed = HandleKeyEvent(event, key_code, &mod_down_flags, &released); - UpdateOverlay(); - return RewriteUpdate(consumed, released, mod_down_flags, flags); -} -ui::EventRewriteStatus StickyKeysController::RewriteMouseEvent( - const ui::MouseEvent& event, - int* flags) { - if (!enabled_) - return ui::EVENT_REWRITE_CONTINUE; - int mod_down_flags = 0; - bool released = false; - bool consumed = HandleMouseEvent(event, &mod_down_flags, &released); - UpdateOverlay(); - return RewriteUpdate(consumed, released, mod_down_flags, flags); -} + if (event.IsKeyEvent()) + return RewriteKeyEvent(*event.AsKeyEvent(), rewritten_event); -ui::EventRewriteStatus StickyKeysController::RewriteScrollEvent( - const ui::ScrollEvent& event, - int* flags) { - if (!enabled_) - return ui::EVENT_REWRITE_CONTINUE; - int mod_down_flags = 0; - bool released = false; - bool consumed = HandleScrollEvent(event, &mod_down_flags, &released); - UpdateOverlay(); - return RewriteUpdate(consumed, released, mod_down_flags, flags); + if (event.IsMouseEvent()) + return RewriteMouseEvent(*event.AsMouseEvent(), rewritten_event); + + if (event.IsScrollEvent()) + return RewriteScrollEvent(*event.AsScrollEvent(), rewritten_event); + + NOTREACHED(); + return ui::EVENT_REWRITE_CONTINUE; } ui::EventRewriteStatus StickyKeysController::NextDispatchEvent( + const ui::Event& last_event, std::unique_ptr<ui::Event>* new_event) { DCHECK(new_event); new_event->reset(); @@ -176,6 +126,56 @@ return ui::EVENT_REWRITE_REWRITTEN; } +ui::EventRewriteStatus StickyKeysController::RewriteKeyEvent( + const ui::KeyEvent& event, + std::unique_ptr<ui::Event>* rewritten_event) { + DCHECK(enabled_); + int mod_down_flags = 0; + bool released = false; + bool consumed = + shift_sticky_key_->HandleKeyEvent(event, &mod_down_flags, &released) || + alt_sticky_key_->HandleKeyEvent(event, &mod_down_flags, &released) || + altgr_sticky_key_->HandleKeyEvent(event, &mod_down_flags, &released) || + ctrl_sticky_key_->HandleKeyEvent(event, &mod_down_flags, &released) || + mod3_sticky_key_->HandleKeyEvent(event, &mod_down_flags, &released) || + search_sticky_key_->HandleKeyEvent(event, &mod_down_flags, &released); + UpdateOverlay(); + return RewriteUpdate(consumed, released, mod_down_flags, event, + rewritten_event); +} + +ui::EventRewriteStatus StickyKeysController::RewriteMouseEvent( + const ui::MouseEvent& event, + std::unique_ptr<ui::Event>* rewritten_event) { + DCHECK(enabled_); + int mod_down_flags = 0; + bool released = false; + bool consumed = + shift_sticky_key_->HandleMouseEvent(event, &mod_down_flags, &released) || + alt_sticky_key_->HandleMouseEvent(event, &mod_down_flags, &released) || + altgr_sticky_key_->HandleMouseEvent(event, &mod_down_flags, &released) || + ctrl_sticky_key_->HandleMouseEvent(event, &mod_down_flags, &released) || + mod3_sticky_key_->HandleMouseEvent(event, &mod_down_flags, &released); + return RewriteUpdate(consumed, released, mod_down_flags, event, + rewritten_event); +} + +ui::EventRewriteStatus StickyKeysController::RewriteScrollEvent( + const ui::ScrollEvent& event, + std::unique_ptr<ui::Event>* rewritten_event) { + DCHECK(enabled_); + int mod_down_flags = 0; + bool released = false; + bool consumed = + shift_sticky_key_->HandleScrollEvent(event, &mod_down_flags, &released) || + alt_sticky_key_->HandleScrollEvent(event, &mod_down_flags, &released) || + altgr_sticky_key_->HandleScrollEvent(event, &mod_down_flags, &released) || + ctrl_sticky_key_->HandleScrollEvent(event, &mod_down_flags, &released) || + mod3_sticky_key_->HandleScrollEvent(event, &mod_down_flags, &released); + return RewriteUpdate(consumed, released, mod_down_flags, event, + rewritten_event); +} + void StickyKeysController::UpdateOverlay() { overlay_->SetModifierKeyState(ui::EF_SHIFT_DOWN, shift_sticky_key_->current_state()); @@ -201,10 +201,6 @@ overlay_->Show(enabled_ && key_in_use); } -StickyKeysOverlay* StickyKeysController::GetOverlayForTest() { - return overlay_.get(); -} - /////////////////////////////////////////////////////////////////////////////// // StickyKeysHandler StickyKeysHandler::StickyKeysHandler(ui::EventFlags modifier_flag) @@ -216,16 +212,15 @@ StickyKeysHandler::~StickyKeysHandler() {} bool StickyKeysHandler::HandleKeyEvent(const ui::KeyEvent& event, - ui::KeyboardCode key_code, int* mod_down_flags, bool* released) { switch (current_state_) { case STICKY_KEY_STATE_DISABLED: - return HandleDisabledState(event, key_code); + return HandleDisabledState(event); case STICKY_KEY_STATE_ENABLED: - return HandleEnabledState(event, key_code, mod_down_flags, released); + return HandleEnabledState(event, mod_down_flags, released); case STICKY_KEY_STATE_LOCKED: - return HandleLockedState(event, key_code, mod_down_flags, released); + return HandleLockedState(event, mod_down_flags, released); } NOTREACHED(); return false; @@ -334,9 +329,8 @@ return type == ui::ET_KEY_PRESSED ? OTHER_MODIFIER_DOWN : OTHER_MODIFIER_UP; } -bool StickyKeysHandler::HandleDisabledState(const ui::KeyEvent& event, - ui::KeyboardCode key_code) { - switch (TranslateKeyEvent(event.type(), key_code)) { +bool StickyKeysHandler::HandleDisabledState(const ui::KeyEvent& event) { + switch (TranslateKeyEvent(event.type(), event.key_code())) { case TARGET_MODIFIER_UP: if (preparing_to_enable_) { preparing_to_enable_ = false; @@ -362,10 +356,9 @@ } bool StickyKeysHandler::HandleEnabledState(const ui::KeyEvent& event, - ui::KeyboardCode key_code, int* mod_down_flags, bool* released) { - switch (TranslateKeyEvent(event.type(), key_code)) { + switch (TranslateKeyEvent(event.type(), event.key_code())) { case NORMAL_KEY_UP: case TARGET_MODIFIER_DOWN: return false; @@ -388,10 +381,9 @@ } bool StickyKeysHandler::HandleLockedState(const ui::KeyEvent& event, - ui::KeyboardCode key_code, int* mod_down_flags, bool* released) { - switch (TranslateKeyEvent(event.type(), key_code)) { + switch (TranslateKeyEvent(event.type(), event.key_code())) { case TARGET_MODIFIER_DOWN: return true; case TARGET_MODIFIER_UP:
diff --git a/ash/sticky_keys/sticky_keys_controller.h b/ash/sticky_keys/sticky_keys_controller.h index 327d7ec..cdfc2de 100644 --- a/ash/sticky_keys/sticky_keys_controller.h +++ b/ash/sticky_keys/sticky_keys_controller.h
@@ -59,10 +59,10 @@ // modifiers. Each handling or state is performed independently. // // StickyKeysController is disabled by default. -class ASH_EXPORT StickyKeysController { +class ASH_EXPORT StickyKeysController : public ui::EventRewriter { public: StickyKeysController(); - virtual ~StickyKeysController(); + ~StickyKeysController() override; // Activate sticky keys to intercept and modify incoming events. void Enable(bool enabled); @@ -73,61 +73,29 @@ // passed. StickyKeysOverlay* GetOverlayForTest(); - // Handles keyboard event. Returns an |EventRewriteStatus|, and may - // modify |flags|: - // - Returns ui::EVENT_REWRITE_DISCARD, and leaves |flags| untouched, - // if the event is consumed (i.e. a sticky modifier press or release); - // - Returns ui::EVENT_REWRITE_REWRITTEN if the event needs to be modified - // according to the returned |flags| (i.e. a sticky-modified key); - // - Returns ui::EVENT_REWRITE_DISPATCH_ANOTHER if the event needs to be - // modified according to the returned |flags|, and there are delayed - // modifier-up events now to be retrieved using |NextDispatchEvent()| - // (i.e. a sticky-modified key that ends a sticky state); - // - Otherwise returns ui::EVENT_REWRITE_CONTINUE and leaves |flags| - // unchanged. - ui::EventRewriteStatus RewriteKeyEvent(const ui::KeyEvent& event, - ui::KeyboardCode key_code, - int* flags); - - // Handles mouse event. - ui::EventRewriteStatus RewriteMouseEvent(const ui::MouseEvent& event, - int* flags); - - // Handles scroll event. - ui::EventRewriteStatus RewriteScrollEvent(const ui::ScrollEvent& event, - int* flags); - - // Obtains a pending modifier-up event. If the immediately previous - // call to |Rewrite...Event()| or |NextDispatchEvent()| returned - // ui::EVENT_REWRITE_DISPATCH_ANOTHER, this sets |new_event| and returns: - // - ui::EVENT_REWRITE_DISPATCH_ANOTHER if there is at least one more - // pending modifier-up event; - // - ui::EVENT_REWRITE_REWRITE if this is the last or only modifier-up event; - // Otherwise, there is no pending modifier-up event, and this function - // returns ui::EVENT_REWRITE_CONTINUE and sets |new_event| to NULL. + // ui::EventRewriter: + ui::EventRewriteStatus RewriteEvent( + const ui::Event& event, + std::unique_ptr<ui::Event>* rewritten_event) override; ui::EventRewriteStatus NextDispatchEvent( - std::unique_ptr<ui::Event>* new_event); + const ui::Event& last_event, + std::unique_ptr<ui::Event>* new_event) override; private: - // Handles keyboard event. Returns true if Sticky key consumes keyboard event. - // Adds to |mod_down_flags| any flag to be added to the key event. - // Sets |released| if any modifier is to be released after the key event. - bool HandleKeyEvent(const ui::KeyEvent& event, - ui::KeyboardCode key_code, - int* mod_down_flags, - bool* released); + // Rewrite keyboard event. + ui::EventRewriteStatus RewriteKeyEvent( + const ui::KeyEvent& event, + std::unique_ptr<ui::Event>* rewritten_event); - // Handles mouse event. Returns true if Sticky key consumes keyboard event. - // Sets |released| if any modifier is to be released after the key event. - bool HandleMouseEvent(const ui::MouseEvent& event, - int* mod_down_flags, - bool* released); + // Rewrite mouse event. + ui::EventRewriteStatus RewriteMouseEvent( + const ui::MouseEvent& event, + std::unique_ptr<ui::Event>* rewritten_event); - // Handles scroll event. Returns true if Sticky key consumes keyboard event. - // Sets |released| if any modifier is to be released after the key event. - bool HandleScrollEvent(const ui::ScrollEvent& event, - int* mod_down_flags, - bool* released); + // Rewrite scroll event. + ui::EventRewriteStatus RewriteScrollEvent( + const ui::ScrollEvent& event, + std::unique_ptr<ui::Event>* rewritten_event); // Updates the overlay UI with the current state of the sticky keys. void UpdateOverlay(); @@ -192,7 +160,6 @@ // Sets its own modifier flag in |mod_down_flags| if it is active and needs // to be added to the event, and sets |released| if releasing it. bool HandleKeyEvent(const ui::KeyEvent& event, - ui::KeyboardCode key_code, int* mod_down_flags, bool* released); @@ -234,20 +201,17 @@ // Handles key event in DISABLED state. Returns true if sticky keys // consumes the keyboard event. - bool HandleDisabledState(const ui::KeyEvent& event, - ui::KeyboardCode key_code); + bool HandleDisabledState(const ui::KeyEvent& event); // Handles key event in ENABLED state. Returns true if sticky keys // consumes the keyboard event. bool HandleEnabledState(const ui::KeyEvent& event, - ui::KeyboardCode key_code, int* mod_down_flags, bool* released); // Handles key event in LOCKED state. Returns true if sticky keys // consumes the keyboard event. bool HandleLockedState(const ui::KeyEvent& event, - ui::KeyboardCode key_code, int* mod_down_flags, bool* released);
diff --git a/ash/sticky_keys/sticky_keys_unittest.cc b/ash/sticky_keys/sticky_keys_unittest.cc index 457e3633..c1f32a9 100644 --- a/ash/sticky_keys/sticky_keys_unittest.cc +++ b/ash/sticky_keys/sticky_keys_unittest.cc
@@ -205,23 +205,23 @@ int down_flags = 0; std::unique_ptr<ui::KeyEvent> ev; ev.reset(GenerateKey(ui::ET_KEY_PRESSED, key_code)); - handler->HandleKeyEvent(*ev.get(), key_code, &down_flags, &released); + handler->HandleKeyEvent(*ev.get(), &down_flags, &released); ev.reset(GenerateKey(ui::ET_KEY_RELEASED, key_code)); - handler->HandleKeyEvent(*ev.get(), key_code, &down_flags, &released); + handler->HandleKeyEvent(*ev.get(), &down_flags, &released); } bool HandleKeyEvent(const ui::KeyEvent& key_event, StickyKeysHandler* handler, int* down, bool* up) { - return handler->HandleKeyEvent(key_event, key_event.key_code(), down, up); + return handler->HandleKeyEvent(key_event, down, up); } int HandleKeyEventForDownFlags(const ui::KeyEvent& key_event, StickyKeysHandler* handler) { bool released = false; int down = 0; - handler->HandleKeyEvent(key_event, key_event.key_code(), &down, &released); + handler->HandleKeyEvent(key_event, &down, &released); return down; }
diff --git a/base/process/process_linux.cc b/base/process/process_linux.cc index bcba9b5..f98bb4c0 100644 --- a/base/process/process_linux.cc +++ b/base/process/process_linux.cc
@@ -60,10 +60,12 @@ foreground_type == FILE_SYSTEM_CGROUP && background_type == FILE_SYSTEM_CGROUP; } -}; -base::LazyInstance<CGroups>::DestructorAtExit g_cgroups = - LAZY_INSTANCE_INITIALIZER; + static CGroups& Get() { + static auto& groups = *new CGroups; + return groups; + } +}; #else const int kBackgroundPriority = 5; #endif // defined(OS_CHROMEOS) @@ -87,7 +89,7 @@ // static bool Process::CanBackgroundProcesses() { #if defined(OS_CHROMEOS) - if (g_cgroups.Get().enabled) + if (CGroups::Get().enabled) return true; #endif // defined(OS_CHROMEOS) @@ -100,7 +102,7 @@ DCHECK(IsValid()); #if defined(OS_CHROMEOS) - if (g_cgroups.Get().enabled) { + if (CGroups::Get().enabled) { // Used to allow reading the process priority from proc on thread launch. base::ThreadRestrictions::ScopedAllowIO allow_io; std::string proc; @@ -119,11 +121,10 @@ DCHECK(IsValid()); #if defined(OS_CHROMEOS) - if (g_cgroups.Get().enabled) { + if (CGroups::Get().enabled) { std::string pid = IntToString(process_); - const base::FilePath file = - background ? - g_cgroups.Get().background_file : g_cgroups.Get().foreground_file; + const base::FilePath file = background ? CGroups::Get().background_file + : CGroups::Get().foreground_file; return base::WriteFile(file, pid.c_str(), pid.size()) > 0; } #endif // defined(OS_CHROMEOS)
diff --git a/base/test/launcher/test_launcher.cc b/base/test/launcher/test_launcher.cc index b2340ca..1c4a663 100644 --- a/base/test/launcher/test_launcher.cc +++ b/base/test/launcher/test_launcher.cc
@@ -97,14 +97,21 @@ // Set of live launch test processes with corresponding lock (it is allowed // for callers to launch processes on different threads). -LazyInstance<std::map<ProcessHandle, CommandLine>>::DestructorAtExit - g_live_processes = LAZY_INSTANCE_INITIALIZER; -LazyInstance<Lock>::DestructorAtExit g_live_processes_lock = - LAZY_INSTANCE_INITIALIZER; +Lock* GetLiveProcessesLock() { + static auto* lock = new Lock; + return lock; +} + +std::map<ProcessHandle, CommandLine>* GetLiveProcesses() { + static auto* map = new std::map<ProcessHandle, CommandLine>; + return map; +} // Performance trace generator. -LazyInstance<TestLauncherTracer>::DestructorAtExit g_tracer = - LAZY_INSTANCE_INITIALIZER; +TestLauncherTracer* GetTestLauncherTracer() { + static auto* tracer = new TestLauncherTracer; + return tracer; +} #if defined(OS_POSIX) // Self-pipe that makes it possible to do complex shutdown handling @@ -118,19 +125,15 @@ void KillSpawnedTestProcesses() { // Keep the lock until exiting the process to prevent further processes // from being spawned. - AutoLock lock(g_live_processes_lock.Get()); + AutoLock lock(*GetLiveProcessesLock()); - fprintf(stdout, - "Sending SIGTERM to %" PRIuS " child processes... ", - g_live_processes.Get().size()); + fprintf(stdout, "Sending SIGTERM to %" PRIuS " child processes... ", + GetLiveProcesses()->size()); fflush(stdout); - for (std::map<ProcessHandle, CommandLine>::iterator i = - g_live_processes.Get().begin(); - i != g_live_processes.Get().end(); - ++i) { + for (const auto& pair : *GetLiveProcesses()) { // Send the signal to entire process group. - kill((-1) * (i->first), SIGTERM); + kill((-1) * (pair.first), SIGTERM); } fprintf(stdout, @@ -142,17 +145,13 @@ fprintf(stdout, "done.\n"); fflush(stdout); - fprintf(stdout, - "Sending SIGKILL to %" PRIuS " child processes... ", - g_live_processes.Get().size()); + fprintf(stdout, "Sending SIGKILL to %" PRIuS " child processes... ", + GetLiveProcesses()->size()); fflush(stdout); - for (std::map<ProcessHandle, CommandLine>::iterator i = - g_live_processes.Get().begin(); - i != g_live_processes.Get().end(); - ++i) { + for (const auto& pair : *GetLiveProcesses()) { // Send the signal to entire process group. - kill((-1) * (i->first), SIGKILL); + kill((-1) * (pair.first), SIGKILL); } fprintf(stdout, "done.\n"); @@ -309,11 +308,11 @@ // Note how we grab the lock before the process possibly gets created. // This ensures that when the lock is held, ALL the processes are registered // in the set. - AutoLock lock(g_live_processes_lock.Get()); + AutoLock lock(*GetLiveProcessesLock()); #if defined(OS_WIN) // Allow the handle used to capture stdio and stdout to be inherited by the - // child. Note that this is done under g_live_processes_lock to ensure that + // child. Note that this is done under GetLiveProcessesLock() to ensure that // only the desired child receives the handle. if (new_options.stdout_handle) { ::SetHandleInformation(new_options.stdout_handle, HANDLE_FLAG_INHERIT, @@ -325,7 +324,7 @@ #if defined(OS_WIN) // Revoke inheritance so that the handle isn't leaked into other children. - // Note that this is done under g_live_processes_lock to ensure that only + // Note that this is done under GetLiveProcessesLock() to ensure that only // the desired child receives the handle. if (new_options.stdout_handle) ::SetHandleInformation(new_options.stdout_handle, HANDLE_FLAG_INHERIT, 0); @@ -335,8 +334,7 @@ return -1; // TODO(rvargas) crbug.com/417532: Don't store process handles. - g_live_processes.Get().insert(std::make_pair(process.Handle(), - command_line)); + GetLiveProcesses()->insert(std::make_pair(process.Handle(), command_line)); } if (!launched_callback.is_null()) @@ -355,7 +353,7 @@ // Note how we grab the log before issuing a possibly broad process kill. // Other code parts that grab the log kill processes, so avoid trying // to do that twice and trigger all kinds of log messages. - AutoLock lock(g_live_processes_lock.Get()); + AutoLock lock(*GetLiveProcessesLock()); #if defined(OS_POSIX) if (exit_code != 0) { @@ -367,11 +365,11 @@ } #endif - g_live_processes.Get().erase(process.Handle()); + GetLiveProcesses()->erase(process.Handle()); } - g_tracer.Get().RecordProcessExecution(start_time, - TimeTicks::Now() - start_time); + GetTestLauncherTracer()->RecordProcessExecution( + start_time, TimeTicks::Now() - start_time); return exit_code; } @@ -1114,7 +1112,7 @@ if (command_line->HasSwitch(switches::kTestLauncherTrace)) { FilePath trace_path( command_line->GetSwitchValuePath(switches::kTestLauncherTrace)); - if (!g_tracer.Get().Dump(trace_path)) { + if (!GetTestLauncherTracer()->Dump(trace_path)) { LOG(ERROR) << "Failed to save test launcher trace."; } } @@ -1159,18 +1157,15 @@ void TestLauncher::OnOutputTimeout() { DCHECK(thread_checker_.CalledOnValidThread()); - AutoLock lock(g_live_processes_lock.Get()); + AutoLock lock(*GetLiveProcessesLock()); fprintf(stdout, "Still waiting for the following processes to finish:\n"); - for (std::map<ProcessHandle, CommandLine>::iterator i = - g_live_processes.Get().begin(); - i != g_live_processes.Get().end(); - ++i) { + for (const auto& pair : *GetLiveProcesses()) { #if defined(OS_WIN) - fwprintf(stdout, L"\t%s\n", i->second.GetCommandLineString().c_str()); + fwprintf(stdout, L"\t%s\n", pair.second.GetCommandLineString().c_str()); #else - fprintf(stdout, "\t%s\n", i->second.GetCommandLineString().c_str()); + fprintf(stdout, "\t%s\n", pair.second.GetCommandLineString().c_str()); #endif }
diff --git a/base/trace_event/malloc_dump_provider.cc b/base/trace_event/malloc_dump_provider.cc index 52a432b8..3565b8b 100644 --- a/base/trace_event/malloc_dump_provider.cc +++ b/base/trace_event/malloc_dump_provider.cc
@@ -216,12 +216,18 @@ total_virtual_size = stats.size_allocated; allocated_objects_size = stats.size_in_use; - // The resident size is approximated to the max size in use, which would count - // the total size of all regions other than the free bytes at the end of each - // region. In each allocation region the allocations are rounded off to a - // fixed quantum, so the excess region will not be resident. - // See crrev.com/1531463004 for detailed explanation. - resident_size = stats.max_size_in_use; + // Resident size is approximated pretty well by stats.max_size_in_use. + // However, on macOS, freed blocks are both resident and reusable, which is + // semantically equivalent to deallocated. The implementation of libmalloc + // will also only hold a fixed number of freed regions before actually + // starting to deallocate them, so stats.max_size_in_use is also not + // representative of the peak size. As a result, stats.max_size_in_use is + // typically somewhere between actually resident [non-reusable] pages, and + // peak size. This is not very useful, so we just use stats.size_in_use for + // resident_size, even though it's an underestimate and fails to account for + // fragmentation. See + // https://bugs.chromium.org/p/chromium/issues/detail?id=695263#c1. + resident_size = stats.size_in_use; #elif defined(OS_WIN) WinHeapInfo main_heap_info = {}; WinHeapMemoryDumpImpl(&main_heap_info);
diff --git a/chrome/android/java/AndroidManifest.xml b/chrome/android/java/AndroidManifest.xml index f497d34..cc0e2dd 100644 --- a/chrome/android/java/AndroidManifest.xml +++ b/chrome/android/java/AndroidManifest.xml
@@ -325,7 +325,8 @@ android:exported="false" android:windowSoftInputMode="adjustResize" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|mcc|mnc|screenLayout|smallestScreenSize" - android:hardwareAccelerated="false"> + android:hardwareAccelerated="false" + {{ self.supports_video_persistence() }} > </activity> <activity android:name="org.chromium.chrome.browser.customtabs.SeparateTaskCustomTabActivity" android:theme="@style/MainTheme" @@ -335,7 +336,8 @@ android:persistableMode="persistNever" android:autoRemoveFromRecents="false" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|mcc|mnc|screenLayout|smallestScreenSize" - android:hardwareAccelerated="false"> + android:hardwareAccelerated="false" + {{ self.supports_video_persistence() }} > </activity> {% for i in range(10) %} <activity android:name="org.chromium.chrome.browser.customtabs.SeparateTaskCustomTabActivity{{ i }}" @@ -347,7 +349,8 @@ android:persistableMode="persistNever" android:taskAffinity="" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|mcc|mnc|screenLayout|smallestScreenSize" - android:hardwareAccelerated="false"> + android:hardwareAccelerated="false" + {{ self.supports_video_persistence() }} > </activity> {% endfor %} @@ -359,6 +362,8 @@ android:launchMode="singleTask" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|mcc|mnc|screenLayout|smallestScreenSize" android:hardwareAccelerated="false" + {# We can only use blocks once in Jinja, for future substitutions we use + self.supports_video_persistence(). #} {% block supports_video_persistence %} {% endblock %} > @@ -404,7 +409,9 @@ android:taskAffinity="{{ manifest_package }}.ChromeTabbedActivity2" android:launchMode="singleTask" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|mcc|mnc|screenLayout|smallestScreenSize" - android:hardwareAccelerated="false"> + android:hardwareAccelerated="false" + {{ self.supports_video_persistence() }} + > </activity> <activity android:name="org.chromium.chrome.browser.multiwindow.MultiInstanceChromeTabbedActivity" android:theme="@style/TabbedModeTheme" @@ -525,11 +532,13 @@ android:windowSoftInputMode="adjustResize" android:persistableMode="persistNever" android:hardwareAccelerated="false" - android:configChanges="orientation|keyboardHidden|keyboard|screenSize|mcc|mnc|screenLayout|smallestScreenSize"> + android:configChanges="orientation|keyboardHidden|keyboard|screenSize|mcc|mnc|screenLayout|smallestScreenSize" + {{ self.supports_video_persistence() }} > </activity> <activity-alias android:name="com.google.android.apps.chrome.webapps.WebappActivity" android:targetActivity="org.chromium.chrome.browser.webapps.WebappActivity" - android:label="@string/webapp_activity_title"> + android:label="@string/webapp_activity_title" + {{ self.supports_video_persistence() }} > </activity-alias> {% for i in range(10) %} <activity android:name="org.chromium.chrome.browser.webapps.WebappActivity{{ i }}" @@ -541,7 +550,8 @@ android:persistableMode="persistNever" android:hardwareAccelerated="false" android:taskAffinity="{{ manifest_package }}.webapps.WebappActivity{{ i }}" - android:configChanges="orientation|keyboardHidden|keyboard|screenSize|mcc|mnc|screenLayout|smallestScreenSize"> + android:configChanges="orientation|keyboardHidden|keyboard|screenSize|mcc|mnc|screenLayout|smallestScreenSize" + {{ self.supports_video_persistence() }} > </activity> <activity-alias android:name="com.google.android.apps.chrome.webapps.WebappActivity{{ i }}" android:targetActivity="org.chromium.chrome.browser.webapps.WebappActivity{{ i }}" @@ -558,7 +568,8 @@ android:windowSoftInputMode="adjustResize" android:persistableMode="persistNever" android:hardwareAccelerated="false" - android:configChanges="orientation|keyboardHidden|keyboard|screenSize|mcc|mnc|screenLayout|smallestScreenSize"> + android:configChanges="orientation|keyboardHidden|keyboard|screenSize|mcc|mnc|screenLayout|smallestScreenSize" + {{ self.supports_video_persistence() }} > </activity> {% for i in range(10) %} <activity android:name="org.chromium.chrome.browser.webapps.WebApkActivity{{ i }}" @@ -570,7 +581,8 @@ android:persistableMode="persistNever" android:hardwareAccelerated="false" android:taskAffinity="{{ manifest_package }}.webapps.WebApkActivity{{ i }}" - android:configChanges="orientation|keyboardHidden|keyboard|screenSize|mcc|mnc|screenLayout|smallestScreenSize"> + android:configChanges="orientation|keyboardHidden|keyboard|screenSize|mcc|mnc|screenLayout|smallestScreenSize" + {{ self.supports_video_persistence() }} > </activity> {% endfor %}
diff --git a/chrome/android/java/res/layout/item_chooser_dialog.xml b/chrome/android/java/res/layout/item_chooser_dialog.xml index d1aa10d..3806426 100644 --- a/chrome/android/java/res/layout/item_chooser_dialog.xml +++ b/chrome/android/java/res/layout/item_chooser_dialog.xml
@@ -22,6 +22,17 @@ android:paddingEnd="16dp" android:textSize="16sp" /> + <!-- The "no item found" message. --> + <org.chromium.ui.widget.TextViewWithClickableSpans + android:id="@+id/not_found_message" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginTop="8dp" + android:layout_marginStart="16dp" + android:layout_marginEnd="16dp" + android:textSize="16sp" + android:visibility="gone" /> + <!-- A layout containing a spinning progress bar that gets replaced with a list of items. --> <FrameLayout @@ -29,18 +40,6 @@ android:layout_width="fill_parent" android:layout_height="100dp" > - <!-- The "no item found" message. --> - <org.chromium.ui.widget.TextViewWithClickableSpans - android:id="@+id/not_found_message" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_gravity="center" - android:layout_marginTop="8dp" - android:layout_marginStart="16dp" - android:layout_marginEnd="16dp" - android:textSize="16sp" - android:visibility="gone" /> - <ProgressBar android:id="@+id/progress" android:layout_width="24dp"
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java index cb0b5ba..e1dc768 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java
@@ -85,6 +85,7 @@ import org.chromium.chrome.browser.history.HistoryManagerUtils; import org.chromium.chrome.browser.infobar.InfoBarContainer; import org.chromium.chrome.browser.init.AsyncInitializationActivity; +import org.chromium.chrome.browser.media.VideoPersister; import org.chromium.chrome.browser.metrics.LaunchMetrics; import org.chromium.chrome.browser.metrics.StartupMetrics; import org.chromium.chrome.browser.metrics.UmaSessionStats; @@ -812,6 +813,14 @@ FeatureUtilities.setCustomTabVisible(isCustomTab()); FeatureUtilities.setIsInMultiWindowMode( MultiWindowUtils.getInstance().isInMultiWindowMode(this)); + + VideoPersister.getInstance().stopPersist(this); + } + + @Override + protected void onUserLeaveHint() { + super.onUserLeaveHint(); + VideoPersister.getInstance().attemptPersist(this); } @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java index 8953448..88ddbec 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
@@ -75,7 +75,6 @@ import org.chromium.chrome.browser.incognito.IncognitoNotificationManager; import org.chromium.chrome.browser.infobar.DataReductionPromoInfoBar; import org.chromium.chrome.browser.locale.LocaleManager; -import org.chromium.chrome.browser.media.VideoPersister; import org.chromium.chrome.browser.metrics.ActivityStopMetrics; import org.chromium.chrome.browser.metrics.LaunchMetrics; import org.chromium.chrome.browser.metrics.MainIntentBehaviorMetrics; @@ -512,7 +511,6 @@ mMergeTabsOnResume = false; } - VideoPersister.getInstance().stopPersist(this); // TODO(mthiesse): Move this call into ChromeActivity. crbug.com/697694 VrShellDelegate.maybeResumeVR(this); @@ -527,12 +525,6 @@ } @Override - protected void onUserLeaveHint() { - VideoPersister.getInstance().attemptPersist(this); - super.onUserLeaveHint(); - } - - @Override public void onPauseWithNative() { mTabModelSelectorImpl.commitAllTabClosures(); CookiesFetcher.persistCookies(this);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchBarControl.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchBarControl.java index c332ff3..5946d858 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchBarControl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchBarControl.java
@@ -221,15 +221,15 @@ } /** - * Sets the search context to display in the control. + * Sets the details of the context to display in the control. * @param selection The portion of the context that represents the user's selection. * @param end The portion of the context after the selection. */ - public void setSearchContext(String selection, String end) { + public void setContextDetails(String selection, String end) { cancelSearchTermResolutionAnimation(); hideCaption(); mQuickActionControl.reset(); - mContextControl.setSearchContext(selection, end); + mContextControl.setContextDetails(selection, end); resetSearchBarContextOpacity(); animateDividerLine(false); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchContextControl.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchContextControl.java index 542ad59..cc344760 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchContextControl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchContextControl.java
@@ -43,11 +43,11 @@ } /** - * Sets the search context to display in the control. + * Sets the details of the search context to display in the control. * @param selection The portion of the context that represents the user's selection. * @param end The portion of the context after the selection. */ - public void setSearchContext(String selection, String end) { + public void setContextDetails(String selection, String end) { inflate(); mSelectedText.setText(sanitizeText(selection));
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchPanel.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchPanel.java index f5c07f99..baecee1 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchPanel.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchPanel.java
@@ -546,14 +546,16 @@ } /** - * Sets the search context to display in the SearchBar. + * Sets the search context details to display in the SearchBar. * @param selection The portion of the context that represents the user's selection. * @param end The portion of the context from the selection to its end. */ - public void setSearchContext(String selection, String end) { + public void setContextDetails(String selection, String end) { getImageControl().hideStaticImage(true); - getSearchBarControl().setSearchContext(selection, end); + getSearchBarControl().setContextDetails(selection, end); mPanelMetrics.onSearchRequestStarted(); + // Make sure the new Context draws. + requestUpdate(); } /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchContext.java b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchContext.java new file mode 100644 index 0000000..1ad2a65 --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchContext.java
@@ -0,0 +1,77 @@ +// 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. + +package org.chromium.chrome.browser.contextualsearch; + +import org.chromium.base.annotations.CalledByNative; + +/** + * Provides a context in which to search, and links to the native ContextualSearchContext. + * Includes the selection, selection offsets, surrounding page content, etc. + */ +public class ContextualSearchContext { + // The initial selection that established this context, or null. + private final String mSelection; + + // Pointer to the native instance of this class. + private long mNativePointer; + + /** + * Constructs a context that cannot resolve a search term and has a small amount of + * page content. + */ + ContextualSearchContext() { + mNativePointer = nativeInit(); + mSelection = null; + } + + /** + * Constructs a context that can resolve a search term and has a large amount of + * page content. + * @param selection The current selection. + * @param homeCountry The country where the user usually resides, or an empty string if not + * known. + * @param maySendBasePageUrl Whether policy allows sending the base-page URL to the server. + */ + ContextualSearchContext(String selection, String homeCountry, boolean maySendBasePageUrl) { + mNativePointer = nativeInit(); + mSelection = selection; + nativeSetResolveProperties(getNativePointer(), selection, homeCountry, maySendBasePageUrl); + } + + /** + * This method should be called to clean up storage when an instance of this class is + * no longer in use. The nativeDestroy will call the destructor on the native instance. + */ + void destroy() { + assert mNativePointer != 0; + nativeDestroy(mNativePointer); + mNativePointer = 0; + } + + /** + * @return the original selection. + */ + String getSelection() { + return mSelection; + } + + // ============================================================================================ + // Native callback support. + // ============================================================================================ + + @CalledByNative + private long getNativePointer() { + assert mNativePointer != 0; + return mNativePointer; + } + + // ============================================================================================ + // Native methods. + // ============================================================================================ + private native long nativeInit(); + private native void nativeDestroy(long nativeContextualSearchContext); + private native void nativeSetResolveProperties(long nativeContextualSearchContext, + String selection, String homeCountry, boolean maySendBasePageUrl); +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManager.java b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManager.java index 0861373..5287bd6f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManager.java
@@ -120,6 +120,9 @@ private boolean mWasActivatedByTap; private boolean mIsInitialized; + // The current search context, or null. + private ContextualSearchContext mContext; + /** * This boolean is used for loading content after a long-press when content is not immediately * loaded. @@ -303,8 +306,9 @@ /** * @return The Base Page's {@link ContentViewCore}. */ - @Nullable private ContentViewCore getBaseContentView() { - return mSelectionController.getBaseContentView(); + @Nullable + private WebContents getBaseWebContents() { + return mSelectionController.getBaseWebContents(); } /** @@ -326,6 +330,8 @@ * @param reason The {@link StateChangeReason} for hiding Contextual Search. */ public void hideContextualSearch(StateChangeReason reason) { + if (mContext != null) mContext.destroy(); + mContext = null; if (mSearchPanel == null) return; if (mSearchPanel.isShowing()) { @@ -419,6 +425,7 @@ // TODO(pedrosimonetti): Fix for M47. Replace this with a better delayed load approach. mSearchPanel.destroyContent(); + String selection = mSelectionController.getSelectedText(); boolean isTap = mSelectionController.getSelectionType() == SelectionType.TAP; boolean didRequestSurroundings = false; if (isTap) { @@ -426,42 +433,42 @@ mShouldLoadDelayedSearch = false; } if (isTap && mPolicy.shouldPreviousTapResolve()) { - mNetworkCommunicator.startSearchTermResolutionRequest( - mSelectionController.getSelectedText()); + if (mContext != null) mContext.destroy(); + mContext = new ContextualSearchContext( + selection, mPolicy.getHomeCountry(mActivity), mPolicy.maySendBasePageUrl()); + nativeGatherSurroundingText( + mNativeContextualSearchManagerPtr, mContext, getBaseWebContents()); didRequestSurroundings = true; // Cache the native translate data, so JNI calls won't be made when time-critical. mTranslateController.cacheNativeTranslateData(); } else { boolean shouldPrefetch = mPolicy.shouldPrefetchSearchResult(); - mSearchRequest = createContextualSearchRequest( - mSelectionController.getSelectedText(), null, null, shouldPrefetch); + mSearchRequest = createContextualSearchRequest(selection, null, null, shouldPrefetch); mTranslateController.forceAutoDetectTranslateUnlessDisabled(mSearchRequest); mDidStartLoadingResolvedSearchRequest = false; - mSearchPanel.setSearchTerm(mSelectionController.getSelectedText()); + mSearchPanel.setSearchTerm(selection); if (shouldPrefetch) loadSearchUrl(); // Record metrics for manual refinement of the search term from long-press. // TODO(donnd): remove this section once metrics have been analyzed. - if (mSelectionController.getSelectionType() == SelectionType.LONG_PRESS - && mSearchPanel.isPeeking()) { + if (!isTap && mSearchPanel.isPeeking()) { boolean isSingleWord = - !CONTAINS_WHITESPACE_PATTERN - .matcher(mSelectionController.getSelectedText().trim()) - .find(); + !CONTAINS_WHITESPACE_PATTERN.matcher(selection.trim()).find(); RecordUserAction.record(isSingleWord ? "ContextualSearch.ManualRefineSingleWord" : "ContextualSearch.ManualRefineMultiWord"); } } - if (!didRequestSurroundings) { + if (!didRequestSurroundings && getBaseWebContents() != null) { // Gather surrounding text for Icing integration, which will make the selection and // a shorter version of the surroundings available for Conversational Search. // Although the surroundings are extracted, they will not be sent to the server as // part of search term resolution, just sent to Icing which keeps them local until // the user activates a Voice Search. - nativeGatherSurroundingText(mNativeContextualSearchManagerPtr, - mSelectionController.getSelectedText(), NO_HOME_COUNTRY, - getBaseContentView().getWebContents(), mPolicy.maySendBasePageUrl()); + if (mContext != null) mContext.destroy(); + mContext = new ContextualSearchContext(); + nativeGatherSurroundingText( + mNativeContextualSearchManagerPtr, mContext, getBaseWebContents()); } mWereSearchResultsSeen = false; @@ -492,8 +499,6 @@ mSearchPanel.setDidSearchInvolvePromo(); } - // TODO(donnd): although we are showing the bar here, we have not yet set the text! - // Refactor to show the bar and set the text at the same time! // TODO(donnd): If there was a previously ongoing contextual search, we should ensure // it's registered as closed. mSearchPanel.requestPanelShow(stateChangeReason); @@ -504,21 +509,21 @@ @Override public void startSearchTermResolutionRequest(String selection) { - ContentViewCore baseContentView = getBaseContentView(); - if (baseContentView != null) { - nativeStartSearchTermResolutionRequest(mNativeContextualSearchManagerPtr, selection, - mPolicy.getHomeCountry(mActivity), getBaseContentView().getWebContents(), - mPolicy.maySendBasePageUrl()); + WebContents baseWebContents = getBaseWebContents(); + if (baseWebContents != null) { + assert mContext != null; + nativeStartSearchTermResolutionRequest( + mNativeContextualSearchManagerPtr, mContext, getBaseWebContents()); } } @Override @Nullable public URL getBasePageUrl() { - ContentViewCore baseContentViewCore = getBaseContentView(); - if (baseContentViewCore == null) return null; + WebContents baseWebContents = getBaseWebContents(); + if (baseWebContents == null) return null; try { - return new URL(baseContentViewCore.getWebContents().getUrl()); + return new URL(baseWebContents.getUrl()); } catch (MalformedURLException e) { return null; } @@ -615,10 +620,11 @@ */ @CalledByNative private void onSurroundingTextAvailable(final String afterText) { + String selection = mSelectionController.getSelectedText(); // TODO(donnd): check if panel has been requested to show. // We used to call mSearchPanel.isShowing() here, but that's unreliable (crbug.com/669600). - mSearchPanel.setSearchContext( - mSelectionController.getSelectedText(), afterText); + mSearchPanel.setContextDetails(selection, afterText); + mNetworkCommunicator.startSearchTermResolutionRequest(selection); } /** @@ -747,8 +753,13 @@ mPolicy.logSearchTermResolutionDetails(searchTerm); } + // Adjust the selection unless the user changed it since we initiated the search. if (selectionStartAdjust != 0 || selectionEndAdjust != 0) { - mSelectionController.adjustSelection(selectionStartAdjust, selectionEndAdjust); + String originalSelection = mContext == null ? null : mContext.getSelection(); + if (originalSelection != null + && originalSelection.equals(mSelectionController.getSelectedText())) { + mSelectionController.adjustSelection(selectionStartAdjust, selectionEndAdjust); + } } } @@ -1291,16 +1302,21 @@ if (mIsAccessibilityModeEnabled) return; if (isTapSupported()) { - // Here we are starting a new Contextual Search with a Tap gesture, therefore - // we need to clear to properly reflect that a search just started and we don't - // have the resolved search term yet. + // Here we are probably starting a new Contextual Search with a Tap gesture (or we'll + // ignore the tap), therefore we need to clear to properly reflect that a search just + // started and we don't have the resolved search term yet. mSearchRequest = null; - // Let the policy know that a tap gesture has been received. - mPolicy.registerTap(); + if (mContext != null) mContext.destroy(); + mContext = null; - ContentViewCore baseContentView = getBaseContentView(); - if (baseContentView != null) baseContentView.getWebContents().selectWordAroundCaret(); + WebContents baseWebContents = getBaseWebContents(); + if (baseWebContents != null) { + // Let the policy know that a tap gesture has been received. + mPolicy.registerTap(); + + baseWebContents.selectWordAroundCaret(); + } } } @@ -1313,7 +1329,7 @@ StateChangeReason stateChangeReason = type == SelectionType.TAP ? StateChangeReason.TEXT_SELECT_TAP : StateChangeReason.TEXT_SELECT_LONG_PRESS; ContextualSearchUma.logSelectionIsValid(selectionValid); - if (selectionValid) { + if (selectionValid && mSearchPanel != null) { mSearchPanel.updateBasePageSelectionYPx(y); if (!mSearchPanel.isShowing()) { mSearchPanel.getPanelMetrics().onSelectionEstablished(selection); @@ -1329,7 +1345,7 @@ public void handleSelectionDismissal() { if (mIsAccessibilityModeEnabled) return; - if (mSearchPanel.isShowing() + if (mSearchPanel != null && mSearchPanel.isShowing() && !mIsPromotingToTab // If the selection is dismissed when the Panel is not peeking anymore, // which means the Panel is at least partially expanded, then it means @@ -1346,7 +1362,7 @@ String selection, boolean selectionValid, float x, float y) { if (mIsAccessibilityModeEnabled) return; - if (mSearchPanel.isShowing()) { + if (mSearchPanel != null && mSearchPanel.isShowing()) { if (selectionValid) { mSearchPanel.setSearchTerm(selection); } else { @@ -1359,7 +1375,7 @@ public void handleSelectionSuppression(BlacklistReason reason) { if (mIsAccessibilityModeEnabled) return; - mSearchPanel.getPanelMetrics().setBlacklistReason(reason); + if (mSearchPanel != null) mSearchPanel.getPanelMetrics().setBlacklistReason(reason); } // ============================================================================================ @@ -1431,11 +1447,9 @@ private native long nativeInit(); private native void nativeDestroy(long nativeContextualSearchManager); private native void nativeStartSearchTermResolutionRequest(long nativeContextualSearchManager, - String selection, String homeCountry, WebContents baseWebContents, - boolean maySendBasePageUrl); + ContextualSearchContext contextualSearchContext, WebContents baseWebContents); protected native void nativeGatherSurroundingText(long nativeContextualSearchManager, - String selection, String homeCountry, WebContents baseWebContents, - boolean maySendBasePageUrl); + ContextualSearchContext contextualSearchContext, WebContents baseWebContents); private native void nativeEnableContextualSearchJsApiForOverlay( long nativeContextualSearchManager, WebContents overlayWebContents); // Don't call these directly, instead call the private methods that cache the results.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchSelectionController.java b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchSelectionController.java index 161f317..86b1108 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchSelectionController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchSelectionController.java
@@ -15,6 +15,7 @@ import org.chromium.chrome.browser.tab.Tab; import org.chromium.content.browser.ContentViewCore; import org.chromium.content_public.browser.GestureStateListener; +import org.chromium.content_public.browser.WebContents; import org.chromium.ui.touch_selection.SelectionEventType; import java.util.regex.Matcher; @@ -355,10 +356,11 @@ /** * Handles an unhandled tap gesture. + * @param x The x coordinate in px. + * @param y The y coordinate in px. */ void handleShowUnhandledTapUIIfNeeded(int x, int y) { mWasTapGestureDetected = false; - // TODO(donnd): shouldn't we check == TAP here instead of LONG_PRESS? // TODO(donnd): refactor to avoid needing a new handler API method as suggested by Pedro. if (mSelectionType != SelectionType.LONG_PRESS) { mWasTapGestureDetected = true; @@ -403,14 +405,25 @@ } /** + * Gets the base page ContentViewCore. + * Deprecated, use getBaseWebContents instead. * @return The Base Page's {@link ContentViewCore}, or {@code null} if there is no current tab. */ + @Deprecated ContentViewCore getBaseContentView() { Tab currentTab = mActivity.getActivityTab(); return currentTab != null ? currentTab.getContentViewCore() : null; } /** + * @return The Base Page's {@link WebContents}, or {@code null} if there is no current tab. + */ + WebContents getBaseWebContents() { + Tab currentTab = mActivity.getActivityTab(); + return currentTab != null ? currentTab.getContentViewCore().getWebContents() : null; + } + + /** * Expands the current selection by the specified amounts. * @param selectionStartAdjust The start offset adjustment of the selection to use to highlight * the search term. @@ -422,10 +435,10 @@ // crbug.com/508354 if (selectionStartAdjust == 0 && selectionEndAdjust == 0) return; - ContentViewCore basePageContentView = getBaseContentView(); - if (basePageContentView != null && basePageContentView.getWebContents() != null) { + WebContents basePageWebContents = getBaseWebContents(); + if (basePageWebContents != null) { mDidExpandSelection = true; - basePageContentView.getWebContents().adjustSelectionByCharacterOffset( + basePageWebContents.adjustSelectionByCharacterOffset( selectionStartAdjust, selectionEndAdjust); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SectionList.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SectionList.java index 98e963a..477326f1 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SectionList.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SectionList.java
@@ -164,10 +164,6 @@ removeSection(mSections.get(category)); return; - case CategoryStatus.SIGNED_OUT: - resetSection(category, status, /* alwaysAllowEmptySections = */ false); - return; - default: mSections.get(category).setStatus(status); return;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/snippets/SnippetsBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/snippets/SnippetsBridge.java index 68f0ca8..767af465 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/snippets/SnippetsBridge.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/snippets/SnippetsBridge.java
@@ -42,7 +42,6 @@ case CategoryStatus.INITIALIZING: case CategoryStatus.AVAILABLE: case CategoryStatus.AVAILABLE_LOADING: - case CategoryStatus.SIGNED_OUT: return true; } return false;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/AutocompleteController.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/AutocompleteController.java index a212b08..c23bdaa 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/AutocompleteController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/AutocompleteController.java
@@ -33,6 +33,9 @@ private final VoiceSuggestionProvider mVoiceSuggestionProvider = new VoiceSuggestionProvider(); + private boolean mUseCachedZeroSuggestResults; + private boolean mWaitingForSuggestionsToCache; + /** * Listener for receiving OmniboxSuggestions. */ @@ -73,6 +76,17 @@ } /** + * Use cached zero suggest results if there are any available and start caching them + * for all zero suggest updates. + */ + public void startCachedZeroSuggest() { + mUseCachedZeroSuggestResults = true; + List<OmniboxSuggestion> suggestions = + OmniboxSuggestion.getCachedOmniboxSuggestionsForZeroSuggest(); + if (suggestions != null) mListener.onSuggestionsReceived(suggestions, ""); + } + + /** * Starts querying for omnibox suggestions for a given text. * * @param profile The profile to use for starting the AutocompleteController @@ -103,6 +117,7 @@ if (mNativeAutocompleteControllerAndroid != 0) { nativeStart(mNativeAutocompleteControllerAndroid, text, cursorPosition, null, url, preventInlineAutocomplete, false, false, true); + mWaitingForSuggestionsToCache = false; } } @@ -140,6 +155,7 @@ if (profile == null || TextUtils.isEmpty(url)) return; mNativeAutocompleteControllerAndroid = nativeInit(profile); if (mNativeAutocompleteControllerAndroid != 0) { + if (mUseCachedZeroSuggestResults) mWaitingForSuggestionsToCache = true; nativeOnOmniboxFocused(mNativeAutocompleteControllerAndroid, omniboxText, url, focusedFromFakebox); } @@ -159,6 +175,7 @@ public void stop(boolean clear) { if (clear) mVoiceSuggestionProvider.clearVoiceSearchResults(); mCurrentNativeAutocompleteResult = 0; + mWaitingForSuggestionsToCache = false; if (mNativeAutocompleteControllerAndroid != 0) { nativeStop(mNativeAutocompleteControllerAndroid, clear); } @@ -210,6 +227,9 @@ // Notify callbacks of suggestions. mListener.onSuggestionsReceived(suggestions, inlineAutocompleteText); + if (mWaitingForSuggestionsToCache) { + OmniboxSuggestion.cacheOmniboxSuggestionListForZeroSuggest(suggestions); + } } @CalledByNative @@ -234,6 +254,7 @@ public void onSuggestionSelected(int selectedIndex, int type, String currentPageUrl, boolean focusedFromFakebox, long elapsedTimeSinceModified, int completedLength, WebContents webContents) { + assert mNativeAutocompleteControllerAndroid != 0; // Don't natively log voice suggestion results as we add them in Java. if (type == OmniboxSuggestionType.VOICE_SUGGEST) return; nativeOnSuggestionSelected(mNativeAutocompleteControllerAndroid, selectedIndex,
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBarLayout.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBarLayout.java index 26dcfc4..0ff7e03 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBarLayout.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBarLayout.java
@@ -226,6 +226,36 @@ private Runnable mShowSuggestions; + private boolean mShowCachedZeroSuggestResults; + + private DeferredOnSelectionRunnable mDeferredOnSelection; + + private abstract class DeferredOnSelectionRunnable implements Runnable { + protected final OmniboxSuggestion mSuggestion; + protected final int mPosition; + protected boolean mShouldLog; + + public DeferredOnSelectionRunnable(OmniboxSuggestion suggestion, int position) { + this.mSuggestion = suggestion; + this.mPosition = position; + } + + /** + * Set whether the selection matches with native results for logging to make sense. + * @param log Whether the selection should be logged in native code. + */ + public void setShouldLog(boolean log) { + mShouldLog = log; + } + + /** + * @return Whether the selection should be logged in native code. + */ + public boolean shouldLog() { + return mShouldLog; + } + } + /** * Listener for receiving the messages related with interacting with the omnibox during startup. */ @@ -761,6 +791,29 @@ // If the user focused the omnibox prior to the native libraries being initialized, // autocomplete will not always be enabled, so we force it enabled in that case. mUrlBar.setIgnoreTextChangesForAutocomplete(false); + mAutocomplete = new AutocompleteController(this); + } + + /** + * Sets to show cached zero suggest results. This will start both caching zero suggest results + * in shared preferences and also attempt to show them when appropriate without needing native + * initialization. See {@link LocationBarLayout#showCachedZeroSuggestResultsIfAvailable()} for + * showing the loaded results before native initialization. + * @param showCachedZeroSuggestResults Whether cached zero suggest should be shown. + */ + public void setShowCachedZeroSuggestResults(boolean showCachedZeroSuggestResults) { + mShowCachedZeroSuggestResults = showCachedZeroSuggestResults; + if (mShowCachedZeroSuggestResults) mAutocomplete.startCachedZeroSuggest(); + } + + /** + * Signals the omnibox to shows the cached zero suggest results if they have been loaded from + * cache successfully. + */ + public void showCachedZeroSuggestResultsIfAvailable() { + if (!mShowCachedZeroSuggestResults || mSuggestionList == null) return; + setSuggestionsListVisibility(true); + mSuggestionList.updateLayoutParams(); } /** @@ -794,8 +847,6 @@ mDeleteButton.setOnClickListener(this); mMicButton.setOnClickListener(this); - mAutocomplete = new AutocompleteController(this); - mOmniboxPrerender = new OmniboxPrerender(); for (Runnable deferredRunnable : mDeferredNativeRunnables) { @@ -1548,6 +1599,15 @@ @Override public void onSelection(OmniboxSuggestion suggestion, int position) { mSuggestionSelectionInProgress = true; + if (mShowCachedZeroSuggestResults && !mNativeInitialized) { + mDeferredOnSelection = new DeferredOnSelectionRunnable(suggestion, position) { + @Override + public void run() { + onSelection(this.mSuggestion, this.mPosition); + } + }; + return; + } String suggestionMatchUrl = updateSuggestionUrlIfNeeded( suggestion, position, false); loadUrlFromOmniboxMatch(suggestionMatchUrl, suggestion.getTransition(), position, @@ -1720,7 +1780,7 @@ */ @Override public void hideSuggestions() { - if (mAutocomplete == null) return; + if (mAutocomplete == null || !mNativeInitialized) return; if (mShowSuggestions != null) removeCallbacks(mShowSuggestions); @@ -1861,12 +1921,13 @@ // so can only be called once the native side is set up. assert mNativeInitialized : "Suggestions received before native side intialialized"; - if (getCurrentTab() == null) { - // If the current tab is not available, drop the suggestions and hide the autocomplete. - hideSuggestions(); - return; + if (mDeferredOnSelection != null) { + mDeferredOnSelection.setShouldLog(newSuggestions.size() > mDeferredOnSelection.mPosition + && mDeferredOnSelection.mSuggestion.equals( + newSuggestions.get(mDeferredOnSelection.mPosition))); + mDeferredOnSelection.run(); + mDeferredOnSelection = null; } - String userText = mUrlBar.getTextWithoutAutocomplete(); mUrlTextAfterSuggestionsReceived = userText + inlineAutocompleteText; @@ -1945,7 +2006,8 @@ // Update the navigation button to show the default suggestion's icon. updateNavigationButton(); - if (!CommandLine.getInstance().hasSwitch(ChromeSwitches.DISABLE_INSTANT) + if (mNativeInitialized + && !CommandLine.getInstance().hasSwitch(ChromeSwitches.DISABLE_INSTANT) && PrivacyPreferencesManager.getInstance().shouldPrerender()) { mOmniboxPrerender.prerenderMaybe( userText, @@ -2092,9 +2154,15 @@ WebContents webContents = currentTab != null ? currentTab.getWebContents() : null; long elapsedTimeSinceModified = mNewOmniboxEditSessionTimestamp > 0 ? (SystemClock.elapsedRealtime() - mNewOmniboxEditSessionTimestamp) : -1; - mAutocomplete.onSuggestionSelected(matchPosition, type, currentPageUrl, - mUrlFocusedFromFakebox, elapsedTimeSinceModified, mUrlBar.getAutocompleteLength(), - webContents); + boolean shouldSkipNativeLog = mShowCachedZeroSuggestResults + && (mDeferredOnSelection != null) + && !mDeferredOnSelection.shouldLog(); + if (!shouldSkipNativeLog) { + mAutocomplete.onSuggestionSelected(matchPosition, type, currentPageUrl, + mUrlFocusedFromFakebox, elapsedTimeSinceModified, + mUrlBar.getAutocompleteLength(), + webContents); + } loadUrl(url, transition); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/OmniboxSuggestion.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/OmniboxSuggestion.java index f8c81b2..06a942f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/OmniboxSuggestion.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/OmniboxSuggestion.java
@@ -4,10 +4,14 @@ package org.chromium.chrome.browser.omnibox; +import android.content.SharedPreferences; +import android.content.SharedPreferences.Editor; import android.text.TextUtils; +import org.chromium.base.ContextUtils; import org.chromium.base.VisibleForTesting; +import java.util.ArrayList; import java.util.List; /** @@ -15,6 +19,16 @@ */ @VisibleForTesting public class OmniboxSuggestion { + private static final String KEY_ZERO_SUGGEST_LIST_SIZE = "zero_suggest_list_size"; + private static final String KEY_PREFIX_ZERO_SUGGEST_URL = "zero_suggest_url"; + private static final String KEY_PREFIX_ZERO_SUGGEST_DISPLAY_TEST = "zero_suggest_display_text"; + private static final String KEY_PREFIX_ZERO_SUGGEST_DESCRIPTION = "zero_suggest_description"; + private static final String KEY_PREFIX_ZERO_SUGGEST_NATIVE_TYPE = "zero_suggest_native_type"; + private static final String KEY_PREFIX_ZERO_SUGGEST_IS_SEARCH_TYPE = "zero_suggest_is_search"; + private static final String KEY_PREFIX_ZERO_SUGGEST_ANSWER_TEXT = "zero_suggest_answer_text"; + private static final String KEY_PREFIX_ZERO_SUGGEST_ANSWER_TYPE = "zero_suggest_answer_type"; + private static final String KEY_PREFIX_ZERO_SUGGEST_IS_DELETABLE = "zero_suggest_is_deletable"; + private static final String KEY_PREFIX_ZERO_SUGGEST_IS_STARRED = "zero_suggest_is_starred"; /** * Specifies the style of portions of the suggestion text. @@ -192,4 +206,65 @@ && mIsStarred == suggestion.mIsStarred && mIsDeletable == suggestion.mIsDeletable; } + + /** + * Cache the given suggestion list in shared preferences. + * @param suggestions Suggestions to be cached. + */ + public static void cacheOmniboxSuggestionListForZeroSuggest( + List<OmniboxSuggestion> suggestions) { + Editor editor = ContextUtils.getAppSharedPreferences().edit(); + editor.putInt(KEY_ZERO_SUGGEST_LIST_SIZE, suggestions.size()).apply(); + for (int i = 0; i < suggestions.size(); i++) { + OmniboxSuggestion suggestion = suggestions.get(i); + editor.putString(KEY_PREFIX_ZERO_SUGGEST_URL + i, suggestion.getUrl()) + .putString(KEY_PREFIX_ZERO_SUGGEST_DISPLAY_TEST + i, + suggestion.getDisplayText()) + .putString(KEY_PREFIX_ZERO_SUGGEST_DESCRIPTION + i, + suggestion.getDescription()) + .putString(KEY_PREFIX_ZERO_SUGGEST_ANSWER_TEXT + i, + suggestion.getAnswerContents()) + .putString(KEY_PREFIX_ZERO_SUGGEST_ANSWER_TYPE + i, + suggestion.getAnswerType()) + .putInt(KEY_PREFIX_ZERO_SUGGEST_NATIVE_TYPE + i, suggestion.getType()) + .putBoolean(KEY_PREFIX_ZERO_SUGGEST_IS_SEARCH_TYPE + i, + !suggestion.isUrlSuggestion()) + .putBoolean(KEY_PREFIX_ZERO_SUGGEST_IS_DELETABLE + i, suggestion.mIsDeletable) + .putBoolean(KEY_PREFIX_ZERO_SUGGEST_IS_STARRED + i, suggestion.mIsStarred) + .apply(); + } + } + + /** + * @return The zero suggest result if they have been cached before. + */ + public static List<OmniboxSuggestion> getCachedOmniboxSuggestionsForZeroSuggest() { + SharedPreferences prefs = ContextUtils.getAppSharedPreferences(); + int size = prefs.getInt(KEY_ZERO_SUGGEST_LIST_SIZE, -1); + List<OmniboxSuggestion> suggestions = null; + if (size > 1) { + suggestions = new ArrayList<>(size); + List<MatchClassification> classifications = new ArrayList<>(); + classifications.add(new MatchClassification(0, MatchClassificationStyle.NONE)); + for (int i = 0; i < size; i++) { + String url = prefs.getString(KEY_PREFIX_ZERO_SUGGEST_URL + i, ""); + String displayText = prefs.getString(KEY_PREFIX_ZERO_SUGGEST_DISPLAY_TEST + i, ""); + String description = prefs.getString(KEY_PREFIX_ZERO_SUGGEST_DESCRIPTION + i, ""); + String answerText = prefs.getString(KEY_PREFIX_ZERO_SUGGEST_ANSWER_TEXT + i, ""); + String answerType = prefs.getString(KEY_PREFIX_ZERO_SUGGEST_ANSWER_TYPE + i, ""); + int nativeType = prefs.getInt(KEY_PREFIX_ZERO_SUGGEST_NATIVE_TYPE + i, -1); + boolean isSearchType = + prefs.getBoolean(KEY_PREFIX_ZERO_SUGGEST_IS_SEARCH_TYPE, true); + boolean isStarred = prefs.getBoolean(KEY_PREFIX_ZERO_SUGGEST_IS_STARRED + i, false); + boolean isDeletable = prefs.getBoolean( + KEY_PREFIX_ZERO_SUGGEST_IS_DELETABLE + i, false); + OmniboxSuggestion suggestion = new OmniboxSuggestion( + nativeType, !isSearchType, 0, 0, displayText, + classifications, description, classifications, answerText, + answerType, "", url, isStarred, isDeletable); + suggestions.add(suggestion); + } + } + return suggestions; + } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/SyncCustomizationFragment.java b/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/SyncCustomizationFragment.java index 70e06f5..7373c972 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/SyncCustomizationFragment.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/SyncCustomizationFragment.java
@@ -31,7 +31,6 @@ import org.chromium.base.ApiCompatibilityUtils; import org.chromium.base.BuildInfo; -import org.chromium.base.Callback; import org.chromium.base.VisibleForTesting; import org.chromium.base.metrics.RecordHistogram; import org.chromium.chrome.R; @@ -712,10 +711,7 @@ if (mCurrentSyncError == SYNC_AUTH_ERROR) { AccountManagerHelper.get(getActivity()) .updateCredentials(ChromeSigninController.get(getActivity()).getSignedInUser(), - getActivity(), new Callback<Boolean>() { - @Override - public void onResult(Boolean result) {} - }); + getActivity(), null); return; }
diff --git a/chrome/android/java_sources.gni b/chrome/android/java_sources.gni index fd90721d..d3fae37 100644 --- a/chrome/android/java_sources.gni +++ b/chrome/android/java_sources.gni
@@ -225,6 +225,7 @@ "java/src/org/chromium/chrome/browser/contextmenu/ContextMenuTitleView.java", "java/src/org/chromium/chrome/browser/contextualsearch/BarOverlapTapSuppression.java", "java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchBlacklist.java", + "java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchContext.java", "java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchFieldTrial.java", "java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchHeuristic.java", "java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchHeuristics.java",
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchTapEventTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchTapEventTest.java index 13a271f..8978f83d 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchTapEventTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchTapEventTest.java
@@ -114,8 +114,7 @@ @Override protected void nativeGatherSurroundingText(long nativeContextualSearchManager, - String selection, String homeCountry, WebContents webContents, - boolean maySendBasePageUrl) {} + ContextualSearchContext contextualSearchContext, WebContents baseWebContents) {} /** * @return A stubbed ContentViewCore for mocking text selection. @@ -140,7 +139,7 @@ } @Override - public StubbedContentViewCore getBaseContentView() { + StubbedContentViewCore getBaseContentView() { return mContentViewCore; } }
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/ntp/cards/NewTabPageAdapterTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/ntp/cards/NewTabPageAdapterTest.java index a3f3674..39397ca 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/ntp/cards/NewTabPageAdapterTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/ntp/cards/NewTabPageAdapterTest.java
@@ -277,15 +277,18 @@ mSource.setStatusForCategory(TEST_CATEGORY, CategoryStatus.AVAILABLE); assertItemsFor(section(4)); - // When the category is disabled, the suggestions are cleared and we should go back to - // the situation with the status card. - mSource.setStatusForCategory(TEST_CATEGORY, CategoryStatus.SIGNED_OUT); - assertItemsFor(sectionWithStatusCard()); + // When the category is disabled, the section should go away completely. + mSource.setStatusForCategory(TEST_CATEGORY, CategoryStatus.CATEGORY_EXPLICITLY_DISABLED); + assertItemsFor(); - // The adapter should now be waiting for new suggestions. + // Now we're in the "all dismissed" state. No suggestions should be accepted. suggestions = createDummySuggestions(6, TEST_CATEGORY); mSource.setStatusForCategory(TEST_CATEGORY, CategoryStatus.AVAILABLE); mSource.setSuggestionsForCategory(TEST_CATEGORY, suggestions); + assertItemsFor(); + + // After a full refresh, the adapter should accept suggestions again. + mSource.fireFullRefreshRequired(); assertItemsFor(section(6)); } @@ -306,20 +309,26 @@ suggestions.add(new SnippetArticle(TEST_CATEGORY, "https://site.com/url1", "title1", "pub1", "txt1", "https://site.com/url1", 0, 0, 0)); - // When suggestion are disabled, we should not be able to load them. - mSource.setStatusForCategory(TEST_CATEGORY, CategoryStatus.SIGNED_OUT); + // When the provider is removed, we should not be able to load suggestions. The UI should + // stay the same though. + mSource.setStatusForCategory(TEST_CATEGORY, CategoryStatus.NOT_PROVIDED); mSource.setSuggestionsForCategory(TEST_CATEGORY, suggestions); - assertItemsFor(sectionWithStatusCard()); + assertItemsFor(section(3)); - // INITIALIZING lets us load suggestion still. + // INITIALIZING lets us load suggestions still. mSource.setStatusForCategory(TEST_CATEGORY, CategoryStatus.INITIALIZING); mSource.setSuggestionsForCategory(TEST_CATEGORY, suggestions); assertItemsFor(sectionWithStatusCard().withProgress()); - // The adapter should now be waiting for new suggestion and the fourth one should appear. + // The adapter should now be waiting for new suggestions and the fourth one should appear. mSource.setStatusForCategory(TEST_CATEGORY, CategoryStatus.AVAILABLE); mSource.setSuggestionsForCategory(TEST_CATEGORY, suggestions); assertItemsFor(section(4)); + + // When the category gets disabled, the section should go away and not load any suggestions. + mSource.setStatusForCategory(TEST_CATEGORY, CategoryStatus.CATEGORY_EXPLICITLY_DISABLED); + mSource.setSuggestionsForCategory(TEST_CATEGORY, suggestions); + assertItemsFor(); } /** @@ -341,8 +350,10 @@ mSource.setStatusForCategory(TEST_CATEGORY, CategoryStatus.AVAILABLE_LOADING); assertTrue(progress.isVisible()); - mSource.setStatusForCategory(TEST_CATEGORY, CategoryStatus.SIGNED_OUT); - assertFalse(progress.isVisible()); + // After the section gets disabled, it should gone completely, so checking the progress + // indicator doesn't make sense anymore. + mSource.setStatusForCategory(TEST_CATEGORY, CategoryStatus.CATEGORY_EXPLICITLY_DISABLED); + assertEquals(mAdapter.getSectionListForTesting().getSectionForTesting(TEST_CATEGORY), null); } /** @@ -733,11 +744,12 @@ suggestionsSource.setSuggestionsForCategory( TEST_CATEGORY, createDummySuggestions(0, TEST_CATEGORY)); mAdapter.getSectionListForTesting().onCategoryStatusChanged( - TEST_CATEGORY, CategoryStatus.SIGNED_OUT); - verify(dataObserver).onItemRangeRemoved(2, newSuggestionCount); - verify(dataObserver).onItemRangeChanged(4, 1, null); // Spacer refresh - verify(dataObserver).onItemRangeInserted(2, 1); // Status card added - verify(dataObserver).onItemRangeChanged(5, 1, null); // Spacer refresh + TEST_CATEGORY, CategoryStatus.CATEGORY_EXPLICITLY_DISABLED); + // All suggestions as well as the header and the action should be gone. + verify(dataObserver).onItemRangeRemoved(1, newSuggestionCount + 2); + // The spacer gets refreshed twice: Once when the section is removed, and then again when + // the "all dismissed" item gets added. + verify(dataObserver, times(2)).onItemRangeChanged(2, 1, null); } @Test
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/ntp/cards/SuggestionsSectionTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/ntp/cards/SuggestionsSectionTest.java index ff940e63..044021ff 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/ntp/cards/SuggestionsSectionTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/ntp/cards/SuggestionsSectionTest.java
@@ -183,7 +183,7 @@ verifyNoMoreInteractions(mParent); // We clear existing suggestions when the status is not AVAILABLE, and show the status card. - section.setStatus(CategoryStatus.SIGNED_OUT); + section.setStatus(CategoryStatus.CATEGORY_EXPLICITLY_DISABLED); verify(mParent).onItemRangeRemoved(section, 1, suggestionCount); verify(mParent).onItemRangeInserted(section, 1, 1);
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index a24533f..9cdec6b 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -3985,6 +3985,7 @@ "../android/java/src/org/chromium/chrome/browser/compositor/scene_layer/ToolbarSceneLayer.java", "../android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuHelper.java", "../android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuParams.java", + "../android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchContext.java", "../android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManager.java", "../android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchTabHelper.java", "../android/java/src/org/chromium/chrome/browser/contextualsearch/CtrSuppression.java",
diff --git a/chrome/browser/android/chrome_jni_registrar.cc b/chrome/browser/android/chrome_jni_registrar.cc index d256c67a..bc699aab 100644 --- a/chrome/browser/android/chrome_jni_registrar.cc +++ b/chrome/browser/android/chrome_jni_registrar.cc
@@ -31,6 +31,7 @@ #include "chrome/browser/android/compositor/scene_layer/tab_strip_scene_layer.h" #include "chrome/browser/android/compositor/scene_layer/toolbar_scene_layer.h" #include "chrome/browser/android/compositor/tab_content_manager.h" +#include "chrome/browser/android/contextualsearch/contextual_search_context.h" #include "chrome/browser/android/contextualsearch/contextual_search_manager.h" #include "chrome/browser/android/contextualsearch/contextual_search_tab_helper.h" #include "chrome/browser/android/contextualsearch/ctr_suppression.h" @@ -267,6 +268,7 @@ {"ContentSuggestionsNotificationHelper", ntp_snippets::ContentSuggestionsNotificationHelper::Register}, {"ContextMenuHelper", RegisterContextMenuHelper}, + {"ContextualSearchContext", RegisterContextualSearchContext}, {"ContextualSearchManager", RegisterContextualSearchManager}, {"ContextualSearchSceneLayer", RegisterContextualSearchSceneLayer}, {"ContextualSearchTabHelper", RegisterContextualSearchTabHelper},
diff --git a/chrome/browser/android/contextualsearch/contextual_search_context.cc b/chrome/browser/android/contextualsearch/contextual_search_context.cc index e0db7cc..82900a6 100644 --- a/chrome/browser/android/contextualsearch/contextual_search_context.cc +++ b/chrome/browser/android/contextualsearch/contextual_search_context.cc
@@ -2,7 +2,20 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/android/contextualsearch/contextual_search_context.h" +#include <chrome/browser/android/contextualsearch/contextual_search_context.h> + +#include "base/android/jni_string.h" +#include "content/public/browser/browser_thread.h" + +#include "jni/ContextualSearchContext_jni.h" + +ContextualSearchContext::ContextualSearchContext(JNIEnv* env, jobject obj) + : can_resolve(false), + can_send_base_page_url(false), + start_offset(0), + end_offset(0) { + java_object_.Reset(env, obj); +} ContextualSearchContext::ContextualSearchContext( const std::string& selected_text, @@ -11,8 +24,111 @@ const std::string& encoding) : selected_text(selected_text), home_country(home_country), - page_url(page_url), - encoding(encoding) {} + base_page_url(page_url), + base_page_encoding(encoding) { + java_object_ = nullptr; +} ContextualSearchContext::~ContextualSearchContext() { } + +// static +ContextualSearchContext* +ContextualSearchContext::FromJavaContextualSearchContext( + const base::android::JavaRef<jobject>& j_contextual_search_context) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + if (j_contextual_search_context.is_null()) + return NULL; + + ContextualSearchContext* contextual_search_context = + reinterpret_cast<ContextualSearchContext*>( + Java_ContextualSearchContext_getNativePointer( + base::android::AttachCurrentThread(), + j_contextual_search_context)); + return contextual_search_context; +} + +void ContextualSearchContext::SetResolveProperties( + JNIEnv* env, + jobject obj, + const base::android::JavaParamRef<jstring>& j_selection, + const base::android::JavaParamRef<jstring>& j_home_country, + jboolean j_may_send_base_page_url) { + can_resolve = true; + selected_text = base::android::ConvertJavaStringToUTF8(env, j_selection); + home_country = base::android::ConvertJavaStringToUTF8(env, j_home_country); + can_send_base_page_url = j_may_send_base_page_url; +} + +// Accessors + +bool ContextualSearchContext::CanResolve() const { + return can_resolve; +} + +bool ContextualSearchContext::CanSendBasePageUrl() const { + return can_send_base_page_url; +} + +const GURL ContextualSearchContext::GetBasePageUrl() const { + return base_page_url; +} + +void ContextualSearchContext::SetBasePageUrl(const GURL& base_page_url) { + this->base_page_url = base_page_url; +} + +const std::string ContextualSearchContext::GetBasePageEncoding() const { + return base_page_encoding; +} + +void ContextualSearchContext::SetBasePageEncoding( + const std::string& base_page_encoding) { + this->base_page_encoding = base_page_encoding; +} + +const std::string ContextualSearchContext::GetHomeCountry() const { + return home_country; +} + +void ContextualSearchContext::SetSelectionSurroundings( + int start_offset, + int end_offset, + const base::string16& surrounding_text) { + this->start_offset = start_offset; + this->end_offset = end_offset; + this->surrounding_text = surrounding_text; +} + +const std::string ContextualSearchContext::GetOriginalSelectedText() const { + return selected_text; +} + +const base::string16 ContextualSearchContext::GetSurroundingText() const { + return surrounding_text; +} + +int ContextualSearchContext::GetStartOffset() const { + return start_offset; +} + +int ContextualSearchContext::GetEndOffset() const { + return end_offset; +} + +// Java wrapper boilerplate + +void ContextualSearchContext::Destroy( + JNIEnv* env, + const base::android::JavaParamRef<jobject>& obj) { + delete this; +} + +bool RegisterContextualSearchContext(JNIEnv* env) { + return RegisterNativesImpl(env); +} + +jlong Init(JNIEnv* env, const base::android::JavaParamRef<jobject>& obj) { + ContextualSearchContext* context = new ContextualSearchContext(env, obj); + return reinterpret_cast<intptr_t>(context); +}
diff --git a/chrome/browser/android/contextualsearch/contextual_search_context.h b/chrome/browser/android/contextualsearch/contextual_search_context.h index 436a114..350d962 100644 --- a/chrome/browser/android/contextualsearch/contextual_search_context.h +++ b/chrome/browser/android/contextualsearch/contextual_search_context.h
@@ -7,6 +7,7 @@ #include <string> +#include "base/android/jni_android.h" #include "base/macros.h" #include "url/gurl.h" @@ -14,22 +15,88 @@ // text. struct ContextualSearchContext { public: + ContextualSearchContext(JNIEnv* env, jobject obj); + // Constructor for tests. ContextualSearchContext(const std::string& selected_text, const std::string& home_country, const GURL& page_url, const std::string& encoding); ~ContextualSearchContext(); - const std::string selected_text; - const std::string home_country; - const GURL page_url; - const std::string encoding; + // Calls the destructor. Should be called when this native object is no + // longer needed. + void Destroy(JNIEnv* env, const base::android::JavaParamRef<jobject>& obj); + // Returns the native |ContextualSearchContext| given the Java object. + static ContextualSearchContext* FromJavaContextualSearchContext( + const base::android::JavaRef<jobject>& j_contextual_search_context); + + // Returns whether this context can be resolved. + // The context can be resolved only after calling SetResolveProperites. + bool CanResolve() const; + + // Returns whether the base page URL may be sent (according to the Java + // policy). + bool CanSendBasePageUrl() const; + + // Sets the properties needed to resolve a context. + void SetResolveProperties( + JNIEnv* env, + jobject obj, + const base::android::JavaParamRef<jstring>& j_selection, + const base::android::JavaParamRef<jstring>& j_home_country, + jboolean j_may_send_base_page_url); + + // Gets the URL of the base page. + const GURL GetBasePageUrl() const; + // Sets the URL of the base page. + void SetBasePageUrl(const GURL& base_page_url); + + // Gets the encoding of the base page. This is not very important, since + // the surrounding text stored here in a base::string16 is implicitly encoded + // in UTF-16 (see http://www.chromium.org/developers/chromium-string-usage). + const std::string GetBasePageEncoding() const; + void SetBasePageEncoding(const std::string& base_page_encoding); + + // Gets the country code of the home country of the user, or an empty string. + const std::string GetHomeCountry() const; + + // Sets the selection and surroundings. + void SetSelectionSurroundings(int start_offset, + int end_offset, + const base::string16& surrounding_text); + + // Gets the original selection. + const std::string GetOriginalSelectedText() const; + + // Gets the text surrounding the selection (including the selection). + const base::string16 GetSurroundingText() const; + + // Gets the start offset of the selection within the surrounding text (in + // characters). + int GetStartOffset() const; + // Gets the end offset of the selection within the surrounding text (in + // characters). + int GetEndOffset() const; + + private: + bool can_resolve; + bool can_send_base_page_url; + + std::string selected_text; + std::string home_country; + GURL base_page_url; + std::string base_page_encoding; base::string16 surrounding_text; int start_offset; int end_offset; + // The linked Java object. + base::android::ScopedJavaGlobalRef<jobject> java_object_; + DISALLOW_COPY_AND_ASSIGN(ContextualSearchContext); }; +bool RegisterContextualSearchContext(JNIEnv* env); + #endif // CHROME_BROWSER_ANDROID_CONTEXTUALSEARCH_CONTEXTUAL_SEARCH_CONTEXT_H_
diff --git a/chrome/browser/android/contextualsearch/contextual_search_delegate.cc b/chrome/browser/android/contextualsearch/contextual_search_delegate.cc index bde0a2f5..6ed1466 100644 --- a/chrome/browser/android/contextualsearch/contextual_search_delegate.cc +++ b/chrome/browser/android/contextualsearch/contextual_search_delegate.cc
@@ -98,33 +98,53 @@ ContextualSearchDelegate::~ContextualSearchDelegate() { } -void ContextualSearchDelegate::StartSearchTermResolutionRequest( - const std::string& selection, - const std::string& home_country, - content::WebContents* web_contents, - bool may_send_base_page_url) { - GatherSurroundingTextWithCallback( - selection, home_country, web_contents, may_send_base_page_url, - base::Bind(&ContextualSearchDelegate::StartSearchTermRequestFromSelection, - AsWeakPtr())); -} - void ContextualSearchDelegate::GatherAndSaveSurroundingText( - const std::string& selection, - const std::string& home_country, - content::WebContents* web_contents, - bool may_send_base_page_url) { - GatherSurroundingTextWithCallback( - selection, home_country, web_contents, may_send_base_page_url, - base::Bind(&ContextualSearchDelegate::SaveSurroundingText, AsWeakPtr())); - // TODO(donnd): clear the context here, since we're done with it (but risky). + ContextualSearchContext* contextual_search_context, + content::WebContents* web_contents) { + DCHECK(web_contents); + RenderFrameHost::TextSurroundingSelectionCallback callback = + base::Bind(&ContextualSearchDelegate::OnTextSurroundingSelectionAvailable, + AsWeakPtr()); + context_ = contextual_search_context; + context_->SetBasePageEncoding(web_contents->GetEncoding()); + int surroundingTextSize = context_->CanResolve() + ? field_trial_->GetSurroundingSize() + : field_trial_->GetIcingSurroundingSize(); + RenderFrameHost* focused_frame = web_contents->GetFocusedFrame(); + if (focused_frame) { + focused_frame->RequestTextSurroundingSelection(callback, + surroundingTextSize); + } else { + callback.Run(base::string16(), 0, 0); + } } -void ContextualSearchDelegate::ContinueSearchTermResolutionRequest() { - DCHECK(context_.get()); - if (!context_.get()) +void ContextualSearchDelegate::StartSearchTermResolutionRequest( + ContextualSearchContext* contextual_search_context, + content::WebContents* web_contents) { + DCHECK(web_contents); + DCHECK(context_ == contextual_search_context); + DCHECK(context_->CanResolve()); + + // Immediately cancel any request that's in flight, since we're building a new + // context (and the response disposes of any existing context). + search_term_fetcher_.reset(); + + // Decide if the URL should be sent with the context. + GURL page_url(web_contents->GetURL()); + if (context_->CanSendBasePageUrl() && + CanSendPageURL(page_url, ProfileManager::GetActiveUserProfile(), + template_url_service_)) { + context_->SetBasePageUrl(page_url); + } + ResolveSearchTermFromContext(); +} + +void ContextualSearchDelegate::ResolveSearchTermFromContext() { + DCHECK(context_); + if (!context_) return; - GURL request_url(BuildRequestUrl(context_->home_country)); + GURL request_url(BuildRequestUrl(context_->GetHomeCountry())); DCHECK(request_url.is_valid()); // Reset will delete any previous fetcher, and we won't get any callback. @@ -166,9 +186,6 @@ } } search_term_callback_.Run(*resolved_search_term); - - // The ContextualSearchContext is consumed once the request has completed. - context_.reset(); } std::unique_ptr<ResolvedSearchTerm> @@ -201,13 +218,13 @@ // the new and old selection. if (mention_start >= mention_end || (mention_end - mention_start) > kContextualSearchMaxSelection || - mention_end <= context_->start_offset || - mention_start >= context_->end_offset) { + mention_end <= context_->GetStartOffset() || + mention_start >= context_->GetEndOffset()) { start_adjust = 0; end_adjust = 0; } else { - start_adjust = mention_start - context_->start_offset; - end_adjust = mention_end - context_->end_offset; + start_adjust = mention_start - context_->GetStartOffset(); + end_adjust = mention_end - context_->GetEndOffset(); } } bool is_invalid = response_code == net::URLFetcher::RESPONSE_CODE_INVALID; @@ -270,107 +287,64 @@ return request; } -void ContextualSearchDelegate::GatherSurroundingTextWithCallback( - const std::string& selection, - const std::string& home_country, - content::WebContents* web_contents, - bool may_send_base_page_url, - HandleSurroundingsCallback callback) { - // Immediately cancel any request that's in flight, since we're building a new - // context (and the response disposes of any existing context). - search_term_fetcher_.reset(); - BuildContext(selection, home_country, web_contents, may_send_base_page_url); - DCHECK(web_contents); - RenderFrameHost* focused_frame = web_contents->GetFocusedFrame(); - if (focused_frame) { - focused_frame->RequestTextSurroundingSelection( - callback, field_trial_->GetSurroundingSize()); - } else { - callback.Run(base::string16(), 0, 0); - } -} - -void ContextualSearchDelegate::BuildContext(const std::string& selection, - const std::string& home_country, - content::WebContents* web_contents, - bool may_send_base_page_url) { - // Decide if the URL should be sent with the context. - GURL page_url(web_contents->GetURL()); - GURL url_to_send; - if (may_send_base_page_url && - CanSendPageURL(page_url, ProfileManager::GetActiveUserProfile(), - template_url_service_)) { - url_to_send = page_url; - } - std::string encoding(web_contents->GetEncoding()); - context_.reset(new ContextualSearchContext(selection, home_country, - url_to_send, encoding)); -} - -void ContextualSearchDelegate::StartSearchTermRequestFromSelection( +void ContextualSearchDelegate::OnTextSurroundingSelectionAvailable( const base::string16& surrounding_text, int start_offset, int end_offset) { - // TODO(donnd): figure out how to gather text surrounding the selection - // for other purposes too: e.g. to determine if we should select the - // word where the user tapped. - if (context_.get()) { - SaveSurroundingText(surrounding_text, start_offset, end_offset); + SaveSurroundingText(surrounding_text, start_offset, end_offset); + if (context_->CanResolve()) SendSurroundingText(kSurroundingSizeForUI); - ContinueSearchTermResolutionRequest(); - } else { - DVLOG(1) << "ctxs: Null context, ignored!"; - } } void ContextualSearchDelegate::SaveSurroundingText( const base::string16& surrounding_text, int start_offset, int end_offset) { - DCHECK(context_.get()); + DCHECK(context_); // Sometimes the surroundings are 0, 0, '', so fall back on the selection. // See crbug.com/393100. + bool use_selection = false; if (start_offset == 0 && end_offset == 0 && surrounding_text.length() == 0) { - context_->surrounding_text = base::UTF8ToUTF16(context_->selected_text); - context_->start_offset = 0; - context_->end_offset = context_->selected_text.length(); - } else { - context_->surrounding_text = surrounding_text; - context_->start_offset = start_offset; - context_->end_offset = end_offset; + use_selection = true; + end_offset = context_->GetOriginalSelectedText().length(); } + const base::string16& surrounding_text_or_selection( + use_selection ? base::UTF8ToUTF16(context_->GetOriginalSelectedText()) + : surrounding_text); // Pin the start and end offsets to ensure they point within the string. - int surrounding_length = context_->surrounding_text.length(); - context_->start_offset = - std::min(surrounding_length, std::max(0, context_->start_offset)); - context_->end_offset = - std::min(surrounding_length, std::max(0, context_->end_offset)); + int surrounding_length = surrounding_text_or_selection.length(); + start_offset = std::min(surrounding_length, std::max(0, start_offset)); + end_offset = std::min(surrounding_length, std::max(0, end_offset)); + + context_->SetSelectionSurroundings(start_offset, end_offset, + surrounding_text_or_selection); // Call the Icing callback with a shortened copy of the surroundings. int icing_surrounding_size = field_trial_->GetIcingSurroundingSize(); - size_t selection_start = context_->start_offset; - size_t selection_end = context_->end_offset; - if (icing_surrounding_size >= 0 && selection_start < selection_end) { + size_t selection_start = start_offset; + size_t selection_end = end_offset; + if (icing_surrounding_size >= 0 && selection_start <= selection_end) { int icing_padding_each_side = icing_surrounding_size / 2; base::string16 icing_surrounding_text = SurroundingTextForIcing( - context_->surrounding_text, icing_padding_each_side, &selection_start, - &selection_end); - if (selection_start < selection_end) - icing_callback_.Run(context_->encoding, icing_surrounding_text, - selection_start, selection_end); + surrounding_text_or_selection, icing_padding_each_side, + &selection_start, &selection_end); + if (selection_start <= selection_end) + icing_callback_.Run(context_->GetBasePageEncoding(), + icing_surrounding_text, selection_start, + selection_end); } } void ContextualSearchDelegate::SendSurroundingText(int max_surrounding_chars) { - const base::string16& surrounding = context_->surrounding_text; + const base::string16& surrounding = context_->GetSurroundingText(); // Determine the text after the selection. int surrounding_length = surrounding.length(); // Cast to int. int num_after_characters = std::min( - surrounding_length - context_->end_offset, max_surrounding_chars); - base::string16 after_text = surrounding.substr( - context_->end_offset, num_after_characters); + surrounding_length - context_->GetEndOffset(), max_surrounding_chars); + base::string16 after_text = + surrounding.substr(context_->GetEndOffset(), num_after_characters); base::TrimWhitespace(after_text, base::TRIM_ALL, &after_text); surrounding_callback_.Run(UTF16ToUTF8(after_text)); @@ -385,15 +359,15 @@ const ContextualSearchContext& context) { discourse_context::ClientDiscourseContext proto; discourse_context::Display* display = proto.add_display(); - display->set_uri(context.page_url.spec()); + display->set_uri(context.GetBasePageUrl().spec()); discourse_context::Media* media = display->mutable_media(); - media->set_mime_type(context.encoding); + media->set_mime_type(context.GetBasePageEncoding()); discourse_context::Selection* selection = display->mutable_selection(); - selection->set_content(UTF16ToUTF8(context.surrounding_text)); - selection->set_start(context.start_offset); - selection->set_end(context.end_offset); + selection->set_content(UTF16ToUTF8(context.GetSurroundingText())); + selection->set_start(context.GetStartOffset()); + selection->set_end(context.GetEndOffset()); selection->set_is_uri_encoded(false); std::string serialized;
diff --git a/chrome/browser/android/contextualsearch/contextual_search_delegate.h b/chrome/browser/android/contextualsearch/contextual_search_delegate.h index dde551b3..bdec64a 100644 --- a/chrome/browser/android/contextualsearch/contextual_search_delegate.h +++ b/chrome/browser/android/contextualsearch/contextual_search_delegate.h
@@ -43,11 +43,6 @@ // Provides the Resolved Search Term, called when the Resolve Request returns. typedef base::Callback<void(const ResolvedSearchTerm&)> SearchTermResolutionCallback; - // Provides the surrounding text and selection start/end when Blink gathers - // surrounding text for the Context. - typedef base::Callback< - void(const base::string16&, int, int)> - HandleSurroundingsCallback; // Provides limited surrounding text for icing. typedef base::Callback< void(const std::string&, const base::string16&, size_t, size_t)> @@ -66,24 +61,19 @@ const IcingCallback& icing_callback); ~ContextualSearchDelegate() override; - // Gathers surrounding text and starts an asynchronous search term resolution - // request. The "search term" is the best query to issue for a section of text - // in the context of a web page. When the response is available the callback - // specified in the constructor is run. - void StartSearchTermResolutionRequest(const std::string& selection, - const std::string& home_country, - content::WebContents* web_contents, - bool may_send_base_page_url); + // Gathers surrounding text and saves it locally in the given context. + void GatherAndSaveSurroundingText( + ContextualSearchContext* contextual_search_context, + content::WebContents* web_contents); - // Gathers surrounding text and saves it locally for a future query. - void GatherAndSaveSurroundingText(const std::string& selection, - const std::string& home_country, - content::WebContents* web_contents, - bool may_send_base_page_url); - - // Continues making a Search Term Resolution request, once the surrounding - // text has been gathered. - void ContinueSearchTermResolutionRequest(); + // Starts an asynchronous search term resolution request. + // The given context includes some content from a web page and must be able + // to resolve. + // When the response is available the callback specified in the constructor + // is run. + void StartSearchTermResolutionRequest( + ContextualSearchContext* contextual_search_context, + content::WebContents* web_contents); // Gets the target language for translation purposes for this user. std::string GetTargetLanguage(); @@ -93,10 +83,15 @@ // For testing. void set_context_for_testing(ContextualSearchContext* context) { - context_.reset(context); + context_ = context; } private: + // Friend our test which allows our private methods to be used in helper + // functions. FRIEND_TEST_ALL_PREFIXES just friends individual prefixes. + // Needed for |ResolveSearchTermFromContext|. + friend class ContextualSearchDelegateTest; + // TODO(donnd): consider removing the following since the above covers this. FRIEND_TEST_ALL_PREFIXES(ContextualSearchDelegateTest, SurroundingTextHighMaximum); FRIEND_TEST_ALL_PREFIXES(ContextualSearchDelegateTest, @@ -118,12 +113,9 @@ // net::URLFetcherDelegate: void OnURLFetchComplete(const net::URLFetcher* source) override; - // Builds the ContextualSearchContext in the current context from - // the given parameters. - void BuildContext(const std::string& selection, - const std::string& home_country, - content::WebContents* web_contents, - bool may_send_base_page_url); + // Resolves the search term specified by the current context. + // Only needed for tests. TODO(donnd): make private and friend? + void ResolveSearchTermFromContext(); // Builds and returns the search term resolution request URL. // |selection| is used as the default query. @@ -136,17 +128,9 @@ const std::string& base_page_url, const bool may_send_base_page_url); - // Will gather the surrounding text from the |content_view_core| and call the - // |callback|. - void GatherSurroundingTextWithCallback(const std::string& selection, - const std::string& home_country, - content::WebContents* web_contents, - bool may_send_base_page_url, - HandleSurroundingsCallback callback); - - // Callback for GatherSurroundingTextWithCallback(). Will start the search - // term resolution request. - void StartSearchTermRequestFromSelection( + // Callback for GatherAndSaveSurroundingText, called when surrounding text is + // available. + void OnTextSurroundingSelectionAvailable( const base::string16& surrounding_text, int start_offset, int end_offset); @@ -243,7 +227,8 @@ IcingCallback icing_callback_; // Used to hold the context until an upcoming search term request is started. - std::unique_ptr<ContextualSearchContext> context_; + // Owned by the Java ContextualSearchContext. + ContextualSearchContext* context_; DISALLOW_COPY_AND_ASSIGN(ContextualSearchDelegate); };
diff --git a/chrome/browser/android/contextualsearch/contextual_search_delegate_unittest.cc b/chrome/browser/android/contextualsearch/contextual_search_delegate_unittest.cc index 5646a65a..d28dd01 100644 --- a/chrome/browser/android/contextualsearch/contextual_search_delegate_unittest.cc +++ b/chrome/browser/android/contextualsearch/contextual_search_delegate_unittest.cc
@@ -95,10 +95,9 @@ // ContextualSearchDelegate class takes ownership of the context. delegate_->set_context_for_testing(test_context_); - test_context_->start_offset = start_offset; - test_context_->end_offset = end_offset; - test_context_->surrounding_text = surrounding_text; - delegate_->ContinueSearchTermResolutionRequest(); + test_context_->SetSelectionSurroundings(start_offset, end_offset, + surrounding_text); + delegate_->ResolveSearchTermFromContext(); fetcher_ = test_factory_.GetFetcherByID( ContextualSearchDelegate::kContextualSearchURLFetcherID); ASSERT_TRUE(fetcher_); @@ -147,9 +146,8 @@ int end_offset) { test_context_ = new ContextualSearchContext( "Bogus", std::string(), GURL(kSomeSpecificBasePage), "utf-8"); - test_context_->surrounding_text = surrounding_text; - test_context_->start_offset = start_offset; - test_context_->end_offset = end_offset; + test_context_->SetSelectionSurroundings(start_offset, end_offset, + surrounding_text); // ContextualSearchDelegate class takes ownership of the context. delegate_->set_context_for_testing(test_context_); }
diff --git a/chrome/browser/android/contextualsearch/contextual_search_manager.cc b/chrome/browser/android/contextualsearch/contextual_search_manager.cc index 9c96f5e..6eee9e4 100644 --- a/chrome/browser/android/contextualsearch/contextual_search_manager.cc +++ b/chrome/browser/android/contextualsearch/contextual_search_manager.cc
@@ -65,40 +65,32 @@ void ContextualSearchManager::StartSearchTermResolutionRequest( JNIEnv* env, const JavaParamRef<jobject>& obj, - const JavaParamRef<jstring>& j_selection, - const JavaParamRef<jstring>& j_home_country, - const JavaParamRef<jobject>& j_base_web_contents, - jboolean j_may_send_base_page_url) { + const base::android::JavaParamRef<jobject>& j_contextual_search_context, + const JavaParamRef<jobject>& j_base_web_contents) { WebContents* base_web_contents = WebContents::FromJavaWebContents(j_base_web_contents); DCHECK(base_web_contents); - std::string selection( - base::android::ConvertJavaStringToUTF8(env, j_selection)); - std::string home_country( - base::android::ConvertJavaStringToUTF8(env, j_home_country)); - bool may_send_base_page_url = j_may_send_base_page_url; + ContextualSearchContext* contextual_search_context = + ContextualSearchContext::FromJavaContextualSearchContext( + j_contextual_search_context); // Calls back to OnSearchTermResolutionResponse. - delegate_->StartSearchTermResolutionRequest( - selection, home_country, base_web_contents, may_send_base_page_url); + delegate_->StartSearchTermResolutionRequest(contextual_search_context, + base_web_contents); } void ContextualSearchManager::GatherSurroundingText( JNIEnv* env, const JavaParamRef<jobject>& obj, - const JavaParamRef<jstring>& j_selection, - const JavaParamRef<jstring>& j_home_country, - const JavaParamRef<jobject>& j_base_web_contents, - jboolean j_may_send_base_page_url) { + const base::android::JavaParamRef<jobject>& j_contextual_search_context, + const JavaParamRef<jobject>& j_base_web_contents) { WebContents* base_web_contents = WebContents::FromJavaWebContents(j_base_web_contents); DCHECK(base_web_contents); - std::string selection( - base::android::ConvertJavaStringToUTF8(env, j_selection)); - std::string home_country( - base::android::ConvertJavaStringToUTF8(env, j_home_country)); - bool may_send_base_page_url = j_may_send_base_page_url; - delegate_->GatherAndSaveSurroundingText( - selection, home_country, base_web_contents, may_send_base_page_url); + ContextualSearchContext* contextual_search_context = + ContextualSearchContext::FromJavaContextualSearchContext( + j_contextual_search_context); + delegate_->GatherAndSaveSurroundingText(contextual_search_context, + base_web_contents); } base::android::ScopedJavaLocalRef<jstring>
diff --git a/chrome/browser/android/contextualsearch/contextual_search_manager.h b/chrome/browser/android/contextualsearch/contextual_search_manager.h index f173376..1115509 100644 --- a/chrome/browser/android/contextualsearch/contextual_search_manager.h +++ b/chrome/browser/android/contextualsearch/contextual_search_manager.h
@@ -33,25 +33,20 @@ // content view core object). // Any outstanding server requests are canceled. // When the server responds with the search term, the Java object is notified - // by - // calling OnSearchTermResolutionResponse(). + // by calling OnSearchTermResolutionResponse(). void StartSearchTermResolutionRequest( JNIEnv* env, const base::android::JavaParamRef<jobject>& obj, - const base::android::JavaParamRef<jstring>& j_selection, - const base::android::JavaParamRef<jstring>& j_home_country, - const base::android::JavaParamRef<jobject>& j_base_web_contents, - jboolean j_may_send_base_page_url); + const base::android::JavaParamRef<jobject>& j_contextual_search_context, + const base::android::JavaParamRef<jobject>& j_base_web_contents); // Gathers the surrounding text around the selection and saves it locally. // Does not send a search term resolution request to the server. void GatherSurroundingText( JNIEnv* env, const base::android::JavaParamRef<jobject>& obj, - const base::android::JavaParamRef<jstring>& j_selection, - const base::android::JavaParamRef<jstring>& j_home_country, - const base::android::JavaParamRef<jobject>& j_base_web_contents, - jboolean j_may_send_base_page_url); + const base::android::JavaParamRef<jobject>& j_contextual_search_context, + const base::android::JavaParamRef<jobject>& j_base_web_contents); // Gets the target language for translation purposes. base::android::ScopedJavaLocalRef<jstring> GetTargetLanguage(
diff --git a/chrome/browser/android/ntp/content_suggestions_notifier_service.cc b/chrome/browser/android/ntp/content_suggestions_notifier_service.cc index 446e96a..8e42f09 100644 --- a/chrome/browser/android/ntp/content_suggestions_notifier_service.cc +++ b/chrome/browser/android/ntp/content_suggestions_notifier_service.cc
@@ -152,19 +152,9 @@ if (!category.IsKnownCategory(KnownCategories::ARTICLES)) { return; } - switch (new_status) { - case CategoryStatus::AVAILABLE: - case CategoryStatus::AVAILABLE_LOADING: - break; // nothing to do - case CategoryStatus::INITIALIZING: - case CategoryStatus::ALL_SUGGESTIONS_EXPLICITLY_DISABLED: - case CategoryStatus::CATEGORY_EXPLICITLY_DISABLED: - case CategoryStatus::LOADING_ERROR: - case CategoryStatus::NOT_PROVIDED: - case CategoryStatus::SIGNED_OUT: - ContentSuggestionsNotificationHelper::HideAllNotifications( - CONTENT_SUGGESTIONS_HIDE_DISABLED); - break; + if (!ntp_snippets::IsCategoryStatusAvailable(new_status)) { + ContentSuggestionsNotificationHelper::HideAllNotifications( + CONTENT_SUGGESTIONS_HIDE_DISABLED); } }
diff --git a/chrome/browser/browser_process.h b/chrome/browser/browser_process.h index b11c732a..cf07d9a0 100644 --- a/chrome/browser/browser_process.h +++ b/chrome/browser/browser_process.h
@@ -46,7 +46,7 @@ } namespace subresource_filter { -class RulesetService; +class ContentRulesetService; } namespace variations { @@ -239,7 +239,7 @@ // Returns the service providing versioned storage for rules used by the Safe // Browsing subresource filter. - virtual subresource_filter::RulesetService* + virtual subresource_filter::ContentRulesetService* subresource_filter_ruleset_service() = 0; #if (defined(OS_WIN) || defined(OS_LINUX)) && !defined(OS_CHROMEOS)
diff --git a/chrome/browser/browser_process_impl.cc b/chrome/browser/browser_process_impl.cc index be34208..08f28a14 100644 --- a/chrome/browser/browser_process_impl.cc +++ b/chrome/browser/browser_process_impl.cc
@@ -104,7 +104,7 @@ #include "components/rappor/rappor_service_impl.h" #include "components/safe_json/safe_json_parser.h" #include "components/signin/core/common/profile_management_switches.h" -#include "components/subresource_filter/content/browser/content_ruleset_service_delegate.h" +#include "components/subresource_filter/content/browser/content_ruleset_service.h" #include "components/subresource_filter/core/browser/ruleset_service.h" #include "components/subresource_filter/core/browser/subresource_filter_constants.h" #include "components/subresource_filter/core/browser/subresource_filter_features.h" @@ -903,7 +903,7 @@ return NULL; } -subresource_filter::RulesetService* +subresource_filter::ContentRulesetService* BrowserProcessImpl::subresource_filter_ruleset_service() { DCHECK(CalledOnValidThread()); if (!created_subresource_filter_ruleset_service_) @@ -1224,11 +1224,12 @@ base::FilePath indexed_ruleset_base_dir = user_data_dir.Append(subresource_filter::kTopLevelDirectoryName) .Append(subresource_filter::kIndexedRulesetBaseDirectoryName); - subresource_filter_ruleset_service_.reset( - new subresource_filter::RulesetService( + subresource_filter_ruleset_service_ = + base::MakeUnique<subresource_filter::ContentRulesetService>(); + subresource_filter_ruleset_service_->set_ruleset_service( + base::MakeUnique<subresource_filter::RulesetService>( local_state(), blocking_task_runner, - base::MakeUnique<subresource_filter::ContentRulesetServiceDelegate>(), - indexed_ruleset_base_dir)); + subresource_filter_ruleset_service_.get(), indexed_ruleset_base_dir)); } void BrowserProcessImpl::CreateGCMDriver() {
diff --git a/chrome/browser/browser_process_impl.h b/chrome/browser/browser_process_impl.h index 167ce60e8..701e822 100644 --- a/chrome/browser/browser_process_impl.h +++ b/chrome/browser/browser_process_impl.h
@@ -133,8 +133,8 @@ safe_browsing::SafeBrowsingService* safe_browsing_service() override; safe_browsing::ClientSideDetectionService* safe_browsing_detection_service() override; - subresource_filter::RulesetService* subresource_filter_ruleset_service() - override; + subresource_filter::ContentRulesetService* + subresource_filter_ruleset_service() override; #if (defined(OS_WIN) || defined(OS_LINUX)) && !defined(OS_CHROMEOS) void StartAutoupdateTimer() override; @@ -263,7 +263,7 @@ scoped_refptr<safe_browsing::SafeBrowsingService> safe_browsing_service_; bool created_subresource_filter_ruleset_service_; - std::unique_ptr<subresource_filter::RulesetService> + std::unique_ptr<subresource_filter::ContentRulesetService> subresource_filter_ruleset_service_; bool shutting_down_;
diff --git a/chrome/browser/chromeos/chrome_browser_main_chromeos.cc b/chrome/browser/chromeos/chrome_browser_main_chromeos.cc index 75a7370..1ee08dfe 100644 --- a/chrome/browser/chromeos/chrome_browser_main_chromeos.cc +++ b/chrome/browser/chromeos/chrome_browser_main_chromeos.cc
@@ -11,6 +11,7 @@ #include <vector> #include "ash/shell.h" +#include "ash/sticky_keys/sticky_keys_controller.h" #include "base/bind.h" #include "base/callback.h" #include "base/command_line.h"
diff --git a/chrome/browser/chromeos/events/event_rewriter.cc b/chrome/browser/chromeos/events/event_rewriter.cc index 5a68721..d622d52 100644 --- a/chrome/browser/chromeos/events/event_rewriter.cc +++ b/chrome/browser/chromeos/events/event_rewriter.cc
@@ -8,9 +8,6 @@ #include <vector> -#include "ash/common/wm/window_state.h" -#include "ash/sticky_keys/sticky_keys_controller.h" -#include "ash/wm/window_util.h" #include "base/command_line.h" #include "base/logging.h" #include "base/macros.h" @@ -35,7 +32,6 @@ #include "ui/events/keycodes/dom/dom_key.h" #include "ui/events/keycodes/dom/keycode_converter.h" #include "ui/events/keycodes/keyboard_code_conversion.h" -#include "ui/wm/core/window_util.h" #if defined(USE_X11) #include <X11/extensions/XInput2.h> @@ -306,7 +302,7 @@ } // namespace -EventRewriter::EventRewriter(ash::StickyKeysController* sticky_keys_controller) +EventRewriter::EventRewriter(ui::EventRewriter* sticky_keys_controller) : last_keyboard_device_id_(ui::ED_UNKNOWN_DEVICE), ime_keyboard_for_testing_(NULL), pref_service_for_testing_(NULL), @@ -370,7 +366,7 @@ // know that they don't have to be passed through the post-sticky key // rewriting phases, |RewriteExtendedKeys()| and |RewriteFunctionKeys()|, // because those phases do nothing with modifier key releases. - return sticky_keys_controller_->NextDispatchEvent(new_event); + return sticky_keys_controller_->NextDispatchEvent(last_event, new_event); } NOTREACHED(); return ui::EVENT_REWRITE_CONTINUE; @@ -523,8 +519,14 @@ ui::EventRewriteStatus status = ui::EVENT_REWRITE_CONTINUE; bool is_sticky_key_extension_command = false; if (sticky_keys_controller_) { - status = sticky_keys_controller_->RewriteKeyEvent(key_event, state.key_code, - &state.flags); + auto tmp_event = key_event; + tmp_event.set_key_code(state.key_code); + tmp_event.set_flags(state.flags); + std::unique_ptr<ui::Event> output_event; + status = sticky_keys_controller_->RewriteEvent(tmp_event, &output_event); + if (status == ui::EVENT_REWRITE_REWRITTEN || + status == ui::EVENT_REWRITE_DISPATCH_ANOTHER) + state.flags = output_event->flags(); if (status == ui::EVENT_REWRITE_DISCARD) return ui::EVENT_REWRITE_DISCARD; is_sticky_key_extension_command = @@ -573,8 +575,15 @@ int flags = mouse_event.flags(); RewriteLocatedEvent(mouse_event, &flags); ui::EventRewriteStatus status = ui::EVENT_REWRITE_CONTINUE; - if (sticky_keys_controller_) - status = sticky_keys_controller_->RewriteMouseEvent(mouse_event, &flags); + if (sticky_keys_controller_) { + auto tmp_event = mouse_event; + tmp_event.set_flags(flags); + std::unique_ptr<ui::Event> output_event; + status = sticky_keys_controller_->RewriteEvent(tmp_event, &output_event); + if (status == ui::EVENT_REWRITE_REWRITTEN || + status == ui::EVENT_REWRITE_DISPATCH_ANOTHER) + flags = output_event->flags(); + } int changed_button = ui::EF_NONE; if ((mouse_event.type() == ui::ET_MOUSE_PRESSED) || (mouse_event.type() == ui::ET_MOUSE_RELEASED)) { @@ -608,21 +617,34 @@ return ui::EVENT_REWRITE_CONTINUE; int flags = wheel_event.flags(); RewriteLocatedEvent(wheel_event, &flags); + auto tmp_event = wheel_event; + tmp_event.set_flags(flags); ui::EventRewriteStatus status = - sticky_keys_controller_->RewriteMouseEvent(wheel_event, &flags); - if ((wheel_event.flags() == flags) && - (status == ui::EVENT_REWRITE_CONTINUE)) { - return ui::EVENT_REWRITE_CONTINUE; - } - if (status == ui::EVENT_REWRITE_CONTINUE) - status = ui::EVENT_REWRITE_REWRITTEN; - ui::MouseWheelEvent* rewritten_wheel_event = - new ui::MouseWheelEvent(wheel_event); - rewritten_event->reset(rewritten_wheel_event); - rewritten_wheel_event->set_flags(flags); + sticky_keys_controller_->RewriteEvent(tmp_event, rewritten_event); + + switch (status) { + case ui::EVENT_REWRITE_REWRITTEN: + case ui::EVENT_REWRITE_DISPATCH_ANOTHER: + // whell event has been rewritten and stored in |rewritten_event|. #if defined(USE_X11) - ui::UpdateX11EventForFlags(rewritten_wheel_event); + ui::UpdateX11EventForFlags(rewritten_event->get()); #endif + break; + case ui::EVENT_REWRITE_CONTINUE: + if (flags != wheel_event.flags()) { + *rewritten_event = base::MakeUnique<ui::MouseWheelEvent>(wheel_event); + (*rewritten_event)->set_flags(flags); + status = ui::EVENT_REWRITE_REWRITTEN; +#if defined(USE_X11) + ui::UpdateX11EventForFlags(rewritten_event->get()); +#endif + } + break; + case ui::EVENT_REWRITE_DISCARD: + NOTREACHED(); + break; + } + return status; } @@ -645,17 +667,15 @@ ui::EventRewriteStatus EventRewriter::RewriteScrollEvent( const ui::ScrollEvent& scroll_event, std::unique_ptr<ui::Event>* rewritten_event) { - int flags = scroll_event.flags(); - ui::EventRewriteStatus status = ui::EVENT_REWRITE_CONTINUE; - if (sticky_keys_controller_) - status = sticky_keys_controller_->RewriteScrollEvent(scroll_event, &flags); - if (status == ui::EVENT_REWRITE_CONTINUE) - return status; - ui::ScrollEvent* rewritten_scroll_event = new ui::ScrollEvent(scroll_event); - rewritten_event->reset(rewritten_scroll_event); - rewritten_scroll_event->set_flags(flags); + if (!sticky_keys_controller_) + return ui::EVENT_REWRITE_CONTINUE; + ui::EventRewriteStatus status = + sticky_keys_controller_->RewriteEvent(scroll_event, rewritten_event); + // Scroll event shouldn't be discarded. + DCHECK_NE(status, ui::EVENT_REWRITE_DISCARD); #if defined(USE_X11) - ui::UpdateX11EventForFlags(rewritten_scroll_event); + if (status != ui::EVENT_REWRITE_CONTINUE) + ui::UpdateX11EventForFlags(rewritten_event->get()); #endif return status; }
diff --git a/chrome/browser/chromeos/events/event_rewriter.h b/chrome/browser/chromeos/events/event_rewriter.h index afb4d6f..e887a2c 100644 --- a/chrome/browser/chromeos/events/event_rewriter.h +++ b/chrome/browser/chromeos/events/event_rewriter.h
@@ -19,10 +19,6 @@ class PrefService; -namespace ash { -class StickyKeysController; -} - namespace ui { enum class DomCode; }; @@ -62,7 +58,7 @@ // Does not take ownership of the |sticky_keys_controller|, which may also // be NULL (for testing without ash), in which case sticky key operations // don't happen. - explicit EventRewriter(ash::StickyKeysController* sticky_keys_controller); + explicit EventRewriter(ui::EventRewriter* sticky_keys_controller); ~EventRewriter() override; // Calls KeyboardDeviceAddedInternal. @@ -179,7 +175,7 @@ // The sticky keys controller is not owned here; // at time of writing it is a singleton in ash::Shell. - ash::StickyKeysController* sticky_keys_controller_; + ui::EventRewriter* const sticky_keys_controller_; // Some keyboard layouts have 'latching' keys, which either apply // a modifier while held down (like normal modifiers), or, if no
diff --git a/chrome/browser/component_updater/cros_component_installer.cc b/chrome/browser/component_updater/cros_component_installer.cc index 0aa0886..04fb704 100644 --- a/chrome/browser/component_updater/cros_component_installer.cc +++ b/chrome/browser/component_updater/cros_component_installer.cc
@@ -19,7 +19,30 @@ namespace component_updater { #if defined(OS_CHROMEOS) -void LogRegistrationResult(chromeos::DBusMethodCallStatus call_status, +void LogLoadResult(chromeos::DBusMethodCallStatus call_status, + const std::string& result) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + if (call_status != chromeos::DBUS_METHOD_CALL_SUCCESS) { + DVLOG(1) << "Call to imageloader service failed."; + return; + } + if (result.empty()) { + DVLOG(1) << "Component load failed"; + return; + } +} +void ImageLoaderLoad(const std::string& name) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + chromeos::ImageLoaderClient* loader = + chromeos::DBusThreadManager::Get()->GetImageLoaderClient(); + if (loader) { + loader->LoadComponent(name, base::Bind(&LogLoadResult)); + } else { + DVLOG(1) << "Failed to get ImageLoaderClient object."; + } +} +void LogRegistrationResult(const std::string& name, + chromeos::DBusMethodCallStatus call_status, bool result) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); if (call_status != chromeos::DBUS_METHOD_CALL_SUCCESS) { @@ -30,6 +53,7 @@ DVLOG(1) << "Component registration failed"; return; } + ImageLoaderLoad(name); } void ImageLoaderRegistration(const std::string& version, const base::FilePath& install_dir, @@ -40,7 +64,7 @@ if (loader) { loader->RegisterComponent(name, version, install_dir.value(), - base::Bind(&LogRegistrationResult)); + base::Bind(&LogRegistrationResult, name)); } else { DVLOG(1) << "Failed to get ImageLoaderClient object."; }
diff --git a/chrome/browser/component_updater/subresource_filter_component_installer.cc b/chrome/browser/component_updater/subresource_filter_component_installer.cc index ad4a450..a636e3fa 100644 --- a/chrome/browser/component_updater/subresource_filter_component_installer.cc +++ b/chrome/browser/component_updater/subresource_filter_component_installer.cc
@@ -12,6 +12,7 @@ #include "base/version.h" #include "chrome/browser/browser_process.h" #include "components/component_updater/component_updater_paths.h" +#include "components/subresource_filter/content/browser/content_ruleset_service.h" #include "components/subresource_filter/core/browser/ruleset_service.h" #include "components/subresource_filter/core/browser/subresource_filter_constants.h" #include "components/subresource_filter/core/browser/subresource_filter_features.h" @@ -79,10 +80,12 @@ install_dir.Append(subresource_filter::kUnindexedRulesetDataFileName); ruleset_info.license_path = install_dir.Append(subresource_filter::kUnindexedRulesetLicenseFileName); - subresource_filter::RulesetService* ruleset_service = + subresource_filter::ContentRulesetService* content_ruleset_service = g_browser_process->subresource_filter_ruleset_service(); - if (ruleset_service) - ruleset_service->IndexAndStoreAndPublishRulesetIfNeeded(ruleset_info); + if (content_ruleset_service) { + content_ruleset_service->IndexAndStoreAndPublishRulesetIfNeeded( + ruleset_info); + } } // Called during startup and installation before ComponentReady().
diff --git a/chrome/browser/component_updater/subresource_filter_component_installer_unittest.cc b/chrome/browser/component_updater/subresource_filter_component_installer_unittest.cc index 2599c8c..810c57f 100644 --- a/chrome/browser/component_updater/subresource_filter_component_installer_unittest.cc +++ b/chrome/browser/component_updater/subresource_filter_component_installer_unittest.cc
@@ -22,7 +22,7 @@ #include "chrome/test/base/testing_browser_process.h" #include "components/component_updater/mock_component_updater_service.h" #include "components/prefs/testing_pref_service.h" -#include "components/subresource_filter/content/browser/content_ruleset_service_delegate.h" +#include "components/subresource_filter/content/browser/content_ruleset_service.h" #include "components/subresource_filter/core/browser/ruleset_service.h" #include "components/subresource_filter/core/browser/subresource_filter_constants.h" #include "components/subresource_filter/core/browser/subresource_filter_features.h" @@ -39,13 +39,12 @@ public: TestRulesetService(PrefService* local_state, scoped_refptr<base::SequencedTaskRunner> task_runner, + subresource_filter::ContentRulesetService* content_service, const base::FilePath& base_dir) - : subresource_filter::RulesetService( - local_state, - task_runner, - base::MakeUnique< - subresource_filter::ContentRulesetServiceDelegate>(), - base_dir) {} + : subresource_filter::RulesetService(local_state, + task_runner, + content_service, + base_dir) {} ~TestRulesetService() override {} @@ -103,19 +102,20 @@ subresource_filter::IndexedRulesetVersion::RegisterPrefs( pref_service_.registry()); - std::unique_ptr<subresource_filter::RulesetService> service( - new TestRulesetService(&pref_service_, task_runner_, - ruleset_service_dir_.GetPath())); + auto content_service = + base::MakeUnique<subresource_filter::ContentRulesetService>(); + auto test_ruleset_service = base::MakeUnique<TestRulesetService>( + &pref_service_, task_runner_, content_service.get(), + ruleset_service_dir_.GetPath()); + test_ruleset_service_ = test_ruleset_service.get(); + content_service->set_ruleset_service(std::move(test_ruleset_service)); - TestingBrowserProcess::GetGlobal()->SetRulesetService(std::move(service)); + TestingBrowserProcess::GetGlobal()->SetRulesetService( + std::move(content_service)); traits_.reset(new SubresourceFilterComponentInstallerTraits()); } - TestRulesetService* service() { - return static_cast<TestRulesetService*>( - TestingBrowserProcess::GetGlobal() - ->subresource_filter_ruleset_service()); - } + TestRulesetService* service() { return test_ruleset_service_; } void WriteStringToFile(const std::string data, const base::FilePath& path) { ASSERT_EQ(static_cast<int32_t>(data.length()), @@ -179,6 +179,8 @@ scoped_refptr<base::TestSimpleTaskRunner> task_runner_; TestingPrefServiceSimple pref_service_; + TestRulesetService* test_ruleset_service_ = nullptr; + DISALLOW_COPY_AND_ASSIGN(SubresourceFilterComponentInstallerTest); };
diff --git a/chrome/browser/extensions/api/downloads/downloads_api_browsertest.cc b/chrome/browser/extensions/api/downloads/downloads_api_browsertest.cc index 912e0ac..cbd6e335 100644 --- a/chrome/browser/extensions/api/downloads/downloads_api_browsertest.cc +++ b/chrome/browser/extensions/api/downloads/downloads_api_browsertest.cc
@@ -3999,8 +3999,9 @@ result_id))); } -#if defined(OS_WIN) || defined(OS_CHROMEOS) +#if defined(OS_WIN) || defined(OS_CHROMEOS) || defined(OS_LINUX) // This test is very flaky on Win XP and Aura. http://crbug.com/248438 +// Also flaky on Linux. http://crbug.com/700382 #define MAYBE_DownloadExtensionTest_OnDeterminingFilename_InterruptedResume \ DISABLED_DownloadExtensionTest_OnDeterminingFilename_InterruptedResume #else
diff --git a/chrome/browser/extensions/extension_commands_global_registry_apitest.cc b/chrome/browser/extensions/extension_commands_global_registry_apitest.cc index f4e17f1..52d46aae 100644 --- a/chrome/browser/extensions/extension_commands_global_registry_apitest.cc +++ b/chrome/browser/extensions/extension_commands_global_registry_apitest.cc
@@ -17,9 +17,11 @@ #include <X11/Xlib.h> #include <X11/extensions/XTest.h> #include <X11/keysym.h> - +#include "ui/aura/window.h" #include "ui/events/keycodes/keyboard_code_conversion_x.h" #include "ui/gfx/x/x11_types.h" +#include "ui/views/widget/desktop_aura/desktop_window_tree_host_observer_x11.h" +#include "ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h" #endif #if defined(OS_MACOSX) @@ -155,16 +157,33 @@ incognito_browser, ui::VKEY_8, true, true, false, false)); #elif defined(OS_LINUX) && defined(USE_X11) // Create an incognito browser to capture the focus. - CreateIncognitoBrowser(); + Browser* incognito_browser = CreateIncognitoBrowser(); - // On Linux, our infrastructure for sending keys just synthesize keyboard - // event and send them directly to the specified window, without notifying the - // X root window. It didn't work while testing global shortcut because the - // stuff of global shortcut on Linux need to be notified when KeyPress event - // is happening on X root window. So we simulate the keyboard input here. - SendNativeKeyEventToXDisplay(ui::VKEY_1, true, true, false); - SendNativeKeyEventToXDisplay(ui::VKEY_A, true, true, false); - SendNativeKeyEventToXDisplay(ui::VKEY_8, true, true, false); + views::DesktopWindowTreeHostX11* host = + static_cast<views::DesktopWindowTreeHostX11*>( + incognito_browser->window()->GetNativeWindow()->GetHost()); + + class GlobalCommandTreeHostObserver + : public views::DesktopWindowTreeHostObserverX11 { + public: + void OnWindowMapped(unsigned long xid) override { + // On Linux, our infrastructure for sending keys just synthesize keyboard + // event and send them directly to the specified window, without notifying + // the X root window. It didn't work while testing global shortcut because + // the stuff of global shortcut on Linux need to be notified when KeyPress + // event is happening on X root window. So we simulate the keyboard input + // here. + SendNativeKeyEventToXDisplay(ui::VKEY_1, true, true, false); + SendNativeKeyEventToXDisplay(ui::VKEY_A, true, true, false); + SendNativeKeyEventToXDisplay(ui::VKEY_8, true, true, false); + } + + void OnWindowUnmapped(unsigned long xid) override {} + } observer; + + // The observer sends the commands after window mapping + host->AddObserver(&observer); + #elif defined(OS_MACOSX) // Create an incognito browser to capture the focus. CreateIncognitoBrowser(); @@ -179,6 +198,9 @@ // but it might also be because the non-global shortcuts unexpectedly // worked. ASSERT_TRUE(catcher.GetNextResult()) << catcher.message(); +#if defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(USE_X11) + host->RemoveObserver(&observer); +#endif } #if defined(OS_WIN)
diff --git a/chrome/browser/first_run/try_chrome_dialog_view.cc b/chrome/browser/first_run/try_chrome_dialog_view.cc index 16482e6e..7927b28a 100644 --- a/chrome/browser/first_run/try_chrome_dialog_view.cc +++ b/chrome/browser/first_run/try_chrome_dialog_view.cc
@@ -34,6 +34,7 @@ #include "ui/views/controls/separator.h" #include "ui/views/layout/grid_layout.h" #include "ui/views/layout/layout_constants.h" +#include "ui/views/views_delegate.h" #include "ui/views/widget/widget.h" namespace { @@ -134,7 +135,9 @@ columns->AddPaddingColumn(0, icon_size.width()); columns->AddColumn(views::GridLayout::LEADING, views::GridLayout::FILL, 0, views::GridLayout::USE_PREF, 0, 0); - columns->AddPaddingColumn(0, views::kRelatedButtonHSpacing); + columns->AddPaddingColumn( + 0, views::ViewsDelegate::GetInstance()->GetDistanceMetric( + views::DistanceMetric::RELATED_BUTTON_HORIZONTAL)); columns->AddColumn(views::GridLayout::LEADING, views::GridLayout::FILL, 0, views::GridLayout::USE_PREF, 0, 0);
diff --git a/chrome/browser/notifications/notification_permission_context.cc b/chrome/browser/notifications/notification_permission_context.cc index 36c6d91..3d3f0830 100644 --- a/chrome/browser/notifications/notification_permission_context.cc +++ b/chrome/browser/notifications/notification_permission_context.cc
@@ -4,13 +4,13 @@ #include "chrome/browser/notifications/notification_permission_context.h" -#include <algorithm> #include <deque> #include "base/callback.h" #include "base/location.h" #include "base/rand_util.h" #include "base/single_thread_task_runner.h" +#include "base/stl_util.h" #include "base/threading/thread_task_runner_handle.h" #include "base/timer/timer.h" #include "chrome/browser/notifications/desktop_notification_profile_util.h" @@ -122,10 +122,7 @@ void VisibilityTimerTabHelper::CancelTask(const PermissionRequestID& id) { bool deleting_front = task_queue_.front().id == id; - task_queue_.erase( - std::remove_if(task_queue_.begin(), task_queue_.end(), - [id](const Task& task) { return task.id == id; }), - task_queue_.end()); + base::EraseIf(task_queue_, [id](const Task& task) { return task.id == id; }); if (!task_queue_.empty() && is_visible_ && deleting_front) task_queue_.front().timer->Reset();
diff --git a/chrome/browser/ntp_snippets/download_suggestions_provider_unittest.cc b/chrome/browser/ntp_snippets/download_suggestions_provider_unittest.cc index 932098d..0b0b51e 100644 --- a/chrome/browser/ntp_snippets/download_suggestions_provider_unittest.cc +++ b/chrome/browser/ntp_snippets/download_suggestions_provider_unittest.cc
@@ -76,9 +76,6 @@ case CategoryStatus::CATEGORY_EXPLICITLY_DISABLED: os << "CATEGORY_EXPLICITLY_DISABLED"; break; - case CategoryStatus::SIGNED_OUT: - os << "SIGNED_OUT"; - break; case CategoryStatus::LOADING_ERROR: os << "LOADING_ERROR"; break;
diff --git a/chrome/browser/profiles/profile.cc b/chrome/browser/profiles/profile.cc index 5dc721b6..16fea3c 100644 --- a/chrome/browser/profiles/profile.cc +++ b/chrome/browser/profiles/profile.cc
@@ -100,6 +100,10 @@ registry->RegisterBooleanPref(prefs::kSafeBrowsingScoutReportingEnabled, false); registry->RegisterBooleanPref(prefs::kSafeBrowsingScoutGroupSelected, false); + registry->RegisterBooleanPref( + prefs::kSafeBrowsingSawInterstitialExtendedReporting, false); + registry->RegisterBooleanPref( + prefs::kSafeBrowsingSawInterstitialScoutReporting, false); registry->RegisterBooleanPref(prefs::kSafeBrowsingProceedAnywayDisabled, false); registry->RegisterBooleanPref(prefs::kSSLErrorOverrideAllowed, true);
diff --git a/chrome/browser/resources/vr_shell/vr_shell_ui.css b/chrome/browser/resources/vr_shell/vr_shell_ui.css index d0242ae..c066e2b6 100644 --- a/chrome/browser/resources/vr_shell/vr_shell_ui.css +++ b/chrome/browser/resources/vr_shell/vr_shell_ui.css
@@ -145,6 +145,12 @@ background-color: pink; } +#content-interceptor { + height: 1px; + opacity: 0; + width: 1px; +} + .tab { background-color: #eee; border-radius: 6px;
diff --git a/chrome/browser/resources/vr_shell/vr_shell_ui.html b/chrome/browser/resources/vr_shell/vr_shell_ui.html index c2839d1..d522e96 100644 --- a/chrome/browser/resources/vr_shell/vr_shell_ui.html +++ b/chrome/browser/resources/vr_shell/vr_shell_ui.html
@@ -73,6 +73,7 @@ $i18n{forward} </div> <div id="reload-ui-button" class="ui-element">Reload UI</div> + <div id="content-interceptor" class="ui-element"></div> <div id="tab-template" class="tab"></div> <!--The tab container element behaves like a scroll view (in conjunction with the clip view). -->
diff --git a/chrome/browser/resources/vr_shell/vr_shell_ui.js b/chrome/browser/resources/vr_shell/vr_shell_ui.js index aa5dde6..098f5b8 100644 --- a/chrome/browser/resources/vr_shell/vr_shell_ui.js +++ b/chrome/browser/resources/vr_shell/vr_shell_ui.js
@@ -39,6 +39,8 @@ /** @const */ this.MENU_MODE_SCREEN_HEIGHT = 0.8; /** @const */ this.MENU_MODE_SCREEN_ELEVATION = 0.2; /** @const */ this.BACKGROUND_DISTANCE_MULTIPLIER = 1.414; + /** @const */ this.DOM_INTERCEPTOR_SELECTOR = '#content-interceptor'; + /** @const */ this.DOM_INTERCEPTOR_ELEVATION = 0.01; this.menuMode = false; this.fullscreen = false; @@ -61,6 +63,24 @@ backPlane.setFill(new api.NoFill()); ui.addElement(backPlane); + // Place invisible plane on top of content quad, to intercept the clicks + // while on menu mode. + this.interceptor = new DomUiElement(this.DOM_INTERCEPTOR_SELECTOR); + let update = new api.UiElementUpdate(); + update.setTranslation(0, 0, this.DOM_INTERCEPTOR_ELEVATION); + update.setVisible(false); + update.setParentId(this.elementId); + update.setSize( + this.MENU_MODE_SCREEN_HEIGHT * this.SCREEN_RATIO, + this.MENU_MODE_SCREEN_HEIGHT); + ui.updateElement(this.interceptor.id, update); + let interceptorButton = + document.querySelector(this.DOM_INTERCEPTOR_SELECTOR); + interceptorButton.addEventListener('click', function() { + uiManager.exitMenuMode(); + ui.flush(); + }); + this.updateState(); } @@ -106,6 +126,10 @@ distance = this.FULLSCREEN_DISTANCE; } + let update = new api.UiElementUpdate(); + update.setVisible(this.menuMode); + ui.updateElement(this.interceptor.id, update); + let anim; anim = new api.Animation(this.elementId, ANIM_DURATION); anim.setTranslation(0, y, -distance); @@ -999,6 +1023,13 @@ this.controls.setForwardButtonEnabled(this.canGoForward); } + exitMenuMode() { + if (this.menuMode) { + this.menuMode = false; + this.updateState(); + } + } + updateState() { /** @const */ var URL_INDICATOR_VISIBILITY_TIMEOUT_MS = 5000;
diff --git a/chrome/browser/subresource_filter/test_ruleset_publisher.cc b/chrome/browser/subresource_filter/test_ruleset_publisher.cc index ea9c817..c5d3cfd 100644 --- a/chrome/browser/subresource_filter/test_ruleset_publisher.cc +++ b/chrome/browser/subresource_filter/test_ruleset_publisher.cc
@@ -8,7 +8,7 @@ #include "base/run_loop.h" #include "base/strings/string_number_conversions.h" #include "chrome/browser/browser_process.h" -#include "components/subresource_filter/content/browser/content_ruleset_service_delegate.h" +#include "components/subresource_filter/content/browser/content_ruleset_service.h" #include "components/subresource_filter/core/browser/ruleset_service.h" #include "testing/gtest/include/gtest/gtest.h" @@ -20,20 +20,20 @@ class RulesetDistributionListener { public: RulesetDistributionListener() - : delegate_(static_cast<ContentRulesetServiceDelegate*>( - g_browser_process->subresource_filter_ruleset_service() - ->delegate())) { - delegate_->SetRulesetPublishedCallbackForTesting(run_loop_.QuitClosure()); + : content_service_( + g_browser_process->subresource_filter_ruleset_service()) { + content_service_->SetRulesetPublishedCallbackForTesting( + run_loop_.QuitClosure()); } ~RulesetDistributionListener() { - delegate_->SetRulesetPublishedCallbackForTesting(base::Closure()); + content_service_->SetRulesetPublishedCallbackForTesting(base::Closure()); } void AwaitDistribution() { run_loop_.Run(); } private: - ContentRulesetServiceDelegate* delegate_; + ContentRulesetService* content_service_; base::RunLoop run_loop_; DISALLOW_COPY_AND_ASSIGN(RulesetDistributionListener);
diff --git a/chrome/browser/supervised_user/supervised_user_interstitial.cc b/chrome/browser/supervised_user/supervised_user_interstitial.cc index 5958869c..d150be1 100644 --- a/chrome/browser/supervised_user/supervised_user_interstitial.cc +++ b/chrome/browser/supervised_user/supervised_user_interstitial.cc
@@ -267,6 +267,7 @@ std::string message = l10n_util::GetStringFUTF8( IDS_BLOCK_INTERSTITIAL_DEFAULT_FEEDBACK_TEXT, reason); #if defined(OS_ANDROID) + DCHECK(profile_->IsChild()); ReportChildAccountFeedback(web_contents_, message, url_); #else chrome::ShowFeedbackPage(chrome::FindBrowserWithWebContents(web_contents_),
diff --git a/chrome/browser/ui/libgtkui/select_file_dialog_interactive_uitest.cc b/chrome/browser/ui/libgtkui/select_file_dialog_interactive_uitest.cc index be18ef84d2..669974c2e 100644 --- a/chrome/browser/ui/libgtkui/select_file_dialog_interactive_uitest.cc +++ b/chrome/browser/ui/libgtkui/select_file_dialog_interactive_uitest.cc
@@ -68,7 +68,8 @@ } // namespace libgtkui // Leaks in GtkFileChooserDialog. http://crbug.com/537468 -#if defined(ADDRESS_SANITIZER) +// Flaky on Linux. http://crbug.com/700134 +#if defined(ADDRESS_SANITIZER) || defined(OS_LINUX) #define MAYBE_ModalTest DISABLED_ModalTest #else #define MAYBE_ModalTest ModalTest
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_editor_view_unittest.cc b/chrome/browser/ui/views/bookmarks/bookmark_editor_view_unittest.cc index 2abe3d7..ef959af 100644 --- a/chrome/browser/ui/views/bookmarks/bookmark_editor_view_unittest.cc +++ b/chrome/browser/ui/views/bookmarks/bookmark_editor_view_unittest.cc
@@ -17,6 +17,7 @@ #include "testing/gtest/include/gtest/gtest.h" #include "ui/views/controls/textfield/textfield.h" #include "ui/views/controls/tree/tree_view.h" +#include "ui/views/test/test_views_delegate.h" using base::ASCIIToUTF16; using base::UTF8ToUTF16; @@ -112,6 +113,7 @@ content::TestBrowserThreadBundle thread_bundle_; BookmarkModel* model_; + views::TestViewsDelegate views_delegate_; std::unique_ptr<TestingProfile> profile_; private:
diff --git a/chrome/browser/ui/views/chrome_views_delegate.cc b/chrome/browser/ui/views/chrome_views_delegate.cc index fef73a45..20793d9 100644 --- a/chrome/browser/ui/views/chrome_views_delegate.cc +++ b/chrome/browser/ui/views/chrome_views_delegate.cc
@@ -57,17 +57,32 @@ return profile->GetPrefs(); } +ChromeViewsDelegate* views_delegate = nullptr; + } // namespace // ChromeViewsDelegate -------------------------------------------------------- -#if !defined(OS_WIN) -ChromeViewsDelegate::ChromeViewsDelegate() {} +#if defined(OS_WIN) +ChromeViewsDelegate::ChromeViewsDelegate() + : in_autohide_edges_callback_(false), weak_factory_(this) { +#else +ChromeViewsDelegate::ChromeViewsDelegate() { #endif + DCHECK(!views_delegate); + views_delegate = this; +} ChromeViewsDelegate::~ChromeViewsDelegate() { DCHECK_EQ(0u, ref_count_); + + DCHECK_EQ(this, views_delegate); + views_delegate = nullptr; +} + +ChromeViewsDelegate* ChromeViewsDelegate::GetInstance() { + return views_delegate; } void ChromeViewsDelegate::SaveWindowPlacement(const views::Widget* window, @@ -196,58 +211,61 @@ return content::BrowserThread::GetBlockingPool(); } -gfx::Insets ChromeViewsDelegate::GetDialogButtonInsets() const { +gfx::Insets ChromeViewsDelegate::GetInsetsMetric( + views::InsetsMetric metric) const { const LayoutDelegate* layout_delegate = LayoutDelegate::Get(); - const int top = layout_delegate->GetMetric( - LayoutDelegate::Metric::DIALOG_BUTTON_TOP_SPACING); - const int margin = layout_delegate->GetMetric( - LayoutDelegate::Metric::DIALOG_BUTTON_MARGIN); - return gfx::Insets(top, margin, margin, margin); + switch (metric) { + case views::InsetsMetric::DIALOG_BUTTON: { + const int top = layout_delegate->GetMetric( + LayoutDelegate::Metric::DIALOG_BUTTON_TOP_SPACING); + const int margin = layout_delegate->GetMetric( + LayoutDelegate::Metric::DIALOG_BUTTON_MARGIN); + return gfx::Insets(top, margin, margin, margin); + } + case views::InsetsMetric::DIALOG_FRAME_VIEW: { + const int top = layout_delegate->GetMetric( + LayoutDelegate::Metric::PANEL_CONTENT_MARGIN); + const int side = layout_delegate->GetMetric( + LayoutDelegate::Metric::DIALOG_BUTTON_MARGIN); + // Titles are inset at the top and sides, but not at the bottom. + return gfx::Insets(top, side, 0, side); + } + case views::InsetsMetric::BUBBLE_DIALOG: + return gfx::Insets(layout_delegate->GetMetric( + LayoutDelegate::Metric::PANEL_CONTENT_MARGIN)); + } + NOTREACHED(); + return gfx::Insets(); } -int ChromeViewsDelegate::GetDialogCloseButtonMargin() const { - return LayoutDelegate::Get()->GetMetric( - LayoutDelegate::Metric::DIALOG_CLOSE_BUTTON_MARGIN); +int ChromeViewsDelegate::GetDistanceMetric(views::DistanceMetric metric) const { + switch (metric) { + case views::DistanceMetric::CLOSE_BUTTON_MARGIN: + return LayoutDelegate::Get()->GetMetric( + LayoutDelegate::Metric::DIALOG_CLOSE_BUTTON_MARGIN); + case views::DistanceMetric::RELATED_BUTTON_HORIZONTAL: + return LayoutDelegate::Get()->GetMetric( + LayoutDelegate::Metric::RELATED_BUTTON_HORIZONTAL_SPACING); + case views::DistanceMetric::RELATED_CONTROL_HORIZONTAL: + return LayoutDelegate::Get()->GetMetric( + LayoutDelegate::Metric::RELATED_CONTROL_HORIZONTAL_SPACING); + case views::DistanceMetric::RELATED_CONTROL_VERTICAL: + return LayoutDelegate::Get()->GetMetric( + LayoutDelegate::Metric::RELATED_CONTROL_VERTICAL_SPACING); + case views::DistanceMetric::DIALOG_BUTTON_MINIMUM_WIDTH: + return LayoutDelegate::Get()->GetMetric( + LayoutDelegate::Metric::DIALOG_BUTTON_MINIMUM_WIDTH); + case views::DistanceMetric::BUTTON_HORIZONTAL_PADDING: + return LayoutDelegate::Get()->GetMetric( + LayoutDelegate::Metric::BUTTON_HORIZONTAL_PADDING); + } + NOTREACHED(); + return 0; } -int ChromeViewsDelegate::GetDialogRelatedButtonHorizontalSpacing() const { - return LayoutDelegate::Get()->GetMetric( - LayoutDelegate::Metric::RELATED_BUTTON_HORIZONTAL_SPACING); -} - -int ChromeViewsDelegate::GetDialogRelatedControlVerticalSpacing() const { - return LayoutDelegate::Get()->GetMetric( - LayoutDelegate::Metric::RELATED_CONTROL_VERTICAL_SPACING); -} - -gfx::Insets ChromeViewsDelegate::GetDialogFrameViewInsets() const { - const LayoutDelegate* layout_delegate = LayoutDelegate::Get(); - const int top = layout_delegate->GetMetric( - LayoutDelegate::Metric::PANEL_CONTENT_MARGIN); - const int side = layout_delegate->GetMetric( - LayoutDelegate::Metric::DIALOG_BUTTON_MARGIN); - // Titles are inset at the top and sides, but not at the bottom. - return gfx::Insets(top, side, 0, side); -} - -gfx::Insets ChromeViewsDelegate::GetBubbleDialogMargins() const { - return gfx::Insets(LayoutDelegate::Get()->GetMetric( - LayoutDelegate::Metric::PANEL_CONTENT_MARGIN)); -} - -int ChromeViewsDelegate::GetButtonMinimumWidth() const { - return LayoutDelegate::Get()->GetMetric( - LayoutDelegate::Metric::BUTTON_MINIMUM_WIDTH); -} - -int ChromeViewsDelegate::GetDialogButtonMinimumWidth() const { - return LayoutDelegate::Get()->GetMetric( - LayoutDelegate::Metric::DIALOG_BUTTON_MINIMUM_WIDTH); -} - -int ChromeViewsDelegate::GetButtonHorizontalPadding() const { - return LayoutDelegate::Get()->GetMetric( - LayoutDelegate::Metric::BUTTON_HORIZONTAL_PADDING); +int ChromeViewsDelegate::GetDefaultDistanceMetric( + views::DistanceMetric metric) const { + return views::ViewsDelegate::GetDistanceMetric(metric); } #if !defined(OS_CHROMEOS)
diff --git a/chrome/browser/ui/views/chrome_views_delegate.h b/chrome/browser/ui/views/chrome_views_delegate.h index 5e0bc98..4b9c34e2 100644 --- a/chrome/browser/ui/views/chrome_views_delegate.h +++ b/chrome/browser/ui/views/chrome_views_delegate.h
@@ -20,6 +20,8 @@ ChromeViewsDelegate(); ~ChromeViewsDelegate() override; + static ChromeViewsDelegate* GetInstance(); + // views::ViewsDelegate: void SaveWindowPlacement(const views::Widget* window, const std::string& window_name, @@ -58,15 +60,10 @@ std::string GetApplicationName() override; scoped_refptr<base::TaskRunner> GetBlockingPoolTaskRunner() override; - gfx::Insets GetDialogButtonInsets() const override; - int GetDialogCloseButtonMargin() const override; - int GetDialogRelatedButtonHorizontalSpacing() const override; - int GetDialogRelatedControlVerticalSpacing() const override; - gfx::Insets GetDialogFrameViewInsets() const override; - gfx::Insets GetBubbleDialogMargins() const override; - int GetButtonMinimumWidth() const override; - int GetDialogButtonMinimumWidth() const override; - int GetButtonHorizontalPadding() const override; + gfx::Insets GetInsetsMetric(views::InsetsMetric metric) const override; + int GetDistanceMetric(views::DistanceMetric metric) const override; + + int GetDefaultDistanceMetric(views::DistanceMetric metric) const; private: #if defined(OS_WIN)
diff --git a/chrome/browser/ui/views/chrome_views_delegate_win.cc b/chrome/browser/ui/views/chrome_views_delegate_win.cc index 342e139..3f87f6f 100644 --- a/chrome/browser/ui/views/chrome_views_delegate_win.cc +++ b/chrome/browser/ui/views/chrome_views_delegate_win.cc
@@ -106,9 +106,6 @@ } // namespace -ChromeViewsDelegate::ChromeViewsDelegate() - : in_autohide_edges_callback_(false), weak_factory_(this) {} - HICON ChromeViewsDelegate::GetDefaultWindowIcon() const { return GetAppIcon(); }
diff --git a/chrome/browser/ui/views/extensions/media_galleries_dialog_views_unittest.cc b/chrome/browser/ui/views/extensions/media_galleries_dialog_views_unittest.cc index d14182f9..4853d07 100644 --- a/chrome/browser/ui/views/extensions/media_galleries_dialog_views_unittest.cc +++ b/chrome/browser/ui/views/extensions/media_galleries_dialog_views_unittest.cc
@@ -13,6 +13,7 @@ #include "components/storage_monitor/storage_info.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/views/controls/button/checkbox.h" +#include "ui/views/test/test_views_delegate.h" using ::testing::_; using ::testing::AnyNumber; @@ -60,6 +61,7 @@ private: // TODO(gbillock): Get rid of this mock; make something specialized. NiceMock<MediaGalleriesDialogControllerMock> controller_; + views::TestViewsDelegate views_delegate_; DISALLOW_COPY_AND_ASSIGN(MediaGalleriesDialogTest); };
diff --git a/chrome/browser/ui/views/global_error_bubble_view_unittest.cc b/chrome/browser/ui/views/global_error_bubble_view_unittest.cc index 1ea3979..4c2c545 100644 --- a/chrome/browser/ui/views/global_error_bubble_view_unittest.cc +++ b/chrome/browser/ui/views/global_error_bubble_view_unittest.cc
@@ -16,6 +16,7 @@ #include "ui/gfx/image/image_unittest_util.h" #include "ui/views/controls/button/button.h" #include "ui/views/controls/button/label_button.h" +#include "ui/views/test/test_views_delegate.h" using ::testing::_; using ::testing::Return; @@ -87,6 +88,7 @@ mock_global_error_with_standard_bubble_->AsWeakPtr())) {} protected: + views::TestViewsDelegate views_delegate_; std::unique_ptr<StrictMock<MockGlobalErrorWithStandardBubble>> mock_global_error_with_standard_bubble_; views::View arg_view_;
diff --git a/chrome/browser/ui/views/harmony/layout_delegate.cc b/chrome/browser/ui/views/harmony/layout_delegate.cc index 4ecca84..79d88b02 100644 --- a/chrome/browser/ui/views/harmony/layout_delegate.cc +++ b/chrome/browser/ui/views/harmony/layout_delegate.cc
@@ -6,6 +6,7 @@ #include "base/lazy_instance.h" #include "base/logging.h" +#include "chrome/browser/ui/views/chrome_views_delegate.h" #include "chrome/browser/ui/views/harmony/harmony_layout_delegate.h" #include "ui/base/material_design/material_design_controller.h" #include "ui/views/layout/layout_constants.h" @@ -23,7 +24,8 @@ int LayoutDelegate::GetMetric(Metric metric) const { switch (metric) { case Metric::BUTTON_HORIZONTAL_PADDING: - return views::kButtonHorizontalPadding; + return ChromeViewsDelegate::GetInstance()->GetDefaultDistanceMetric( + views::DistanceMetric::BUTTON_HORIZONTAL_PADDING); case Metric::BUTTON_MAX_LINKABLE_WIDTH: return 0; // Buttons never expand during layout (add padding instead). case Metric::BUTTON_MINIMUM_WIDTH: @@ -31,19 +33,24 @@ case Metric::DIALOG_BUTTON_MARGIN: return views::kButtonHEdgeMarginNew; case Metric::DIALOG_BUTTON_MINIMUM_WIDTH: - return views::kDialogMinimumButtonWidth; + return ChromeViewsDelegate::GetInstance()->GetDefaultDistanceMetric( + views::DistanceMetric::DIALOG_BUTTON_MINIMUM_WIDTH); case Metric::DIALOG_BUTTON_TOP_SPACING: return 0; case Metric::DIALOG_CLOSE_BUTTON_MARGIN: - return views::kCloseButtonMargin; + return ChromeViewsDelegate::GetInstance()->GetDefaultDistanceMetric( + views::DistanceMetric::CLOSE_BUTTON_MARGIN); case Metric::PANEL_CONTENT_MARGIN: return views::kPanelHorizMargin; case Metric::RELATED_BUTTON_HORIZONTAL_SPACING: - return views::kRelatedButtonHSpacing; + return ChromeViewsDelegate::GetInstance()->GetDefaultDistanceMetric( + views::DistanceMetric::RELATED_BUTTON_HORIZONTAL); case Metric::RELATED_CONTROL_HORIZONTAL_SPACING: - return views::kRelatedControlHorizontalSpacing; + return ChromeViewsDelegate::GetInstance()->GetDefaultDistanceMetric( + views::DistanceMetric::RELATED_CONTROL_HORIZONTAL); case Metric::RELATED_CONTROL_VERTICAL_SPACING: - return views::kRelatedControlVerticalSpacing; + return ChromeViewsDelegate::GetInstance()->GetDefaultDistanceMetric( + views::DistanceMetric::RELATED_CONTROL_VERTICAL); case Metric::RELATED_LABEL_HORIZONTAL_SPACING: return views::kItemLabelSpacing; case Metric::SUBSECTION_HORIZONTAL_INDENT:
diff --git a/chrome/browser/ui/views/passwords/manage_passwords_bubble_view_interactive_uitest.cc b/chrome/browser/ui/views/passwords/manage_passwords_bubble_view_interactive_uitest.cc index 5bb18d38..6baa1e9 100644 --- a/chrome/browser/ui/views/passwords/manage_passwords_bubble_view_interactive_uitest.cc +++ b/chrome/browser/ui/views/passwords/manage_passwords_bubble_view_interactive_uitest.cc
@@ -26,6 +26,7 @@ #include "content/public/common/content_features.h" #include "net/url_request/test_url_fetcher_factory.h" #include "testing/gmock/include/gmock/gmock.h" +#include "ui/views/test/widget_test.h" using testing::Eq; using testing::Field; @@ -332,7 +333,12 @@ ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(focused_window)); content::RunAllPendingInMessageLoop(); - EXPECT_FALSE(browser()->window()->IsActive()); + gfx::NativeWindow window = browser()->window()->GetNativeWindow(); + views::Widget* widget = views::Widget::GetWidgetForNativeWindow(window); + ASSERT_NE(nullptr, widget); + + views::test::WidgetActivationWaiter inactive_waiter(widget, false); + inactive_waiter.Wait(); ManagePasswordsBubbleView::set_auto_signin_toast_timeout(0); SetupAutoSignin(std::move(local_credentials)); content::RunAllPendingInMessageLoop(); @@ -342,6 +348,7 @@ focused_window->window()->Close(); browser()->window()->Activate(); content::RunAllPendingInMessageLoop(); - EXPECT_TRUE(browser()->window()->IsActive()); + views::test::WidgetActivationWaiter active_waiter(widget, true); + active_waiter.Wait(); EXPECT_FALSE(IsBubbleShowing()); }
diff --git a/chrome/browser/ui/views/ssl_client_certificate_selector_browsertest.cc b/chrome/browser/ui/views/ssl_client_certificate_selector_browsertest.cc index 18bfd29b..b95b6ada 100644 --- a/chrome/browser/ui/views/ssl_client_certificate_selector_browsertest.cc +++ b/chrome/browser/ui/views/ssl_client_certificate_selector_browsertest.cc
@@ -9,6 +9,7 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ssl/ssl_client_auth_requestor_mock.h" #include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/browser/ui/views/ssl_client_certificate_selector.h" #include "chrome/test/base/in_process_browser_test.h" @@ -27,6 +28,7 @@ #include "net/url_request/url_request_context.h" #include "net/url_request/url_request_context_getter.h" #include "testing/gtest/include/gtest/gtest.h" +#include "ui/views/test/widget_test.h" #if defined(USE_NSS_CERTS) #include "crypto/scoped_test_nss_db.h" @@ -261,6 +263,12 @@ selector_1_->Init(); selector_1_->Show(); + gfx::NativeWindow window = browser_1_->window()->GetNativeWindow(); + views::Widget* widget = views::Widget::GetWidgetForNativeWindow(window); + ASSERT_NE(nullptr, widget); + views::test::WidgetActivationWaiter waiter(widget, true); + waiter.Wait(); + EXPECT_EQ(client_cert_1_.get(), selector_1_->GetSelectedCert()); }
diff --git a/chrome/browser/ui/views/toolbar/reload_button_unittest.cc b/chrome/browser/ui/views/toolbar/reload_button_unittest.cc index fe70511..00195421 100644 --- a/chrome/browser/ui/views/toolbar/reload_button_unittest.cc +++ b/chrome/browser/ui/views/toolbar/reload_button_unittest.cc
@@ -2,12 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "base/run_loop.h" #include "chrome/browser/ui/views/toolbar/reload_button.h" + +#include "base/run_loop.h" #include "chrome/test/base/chrome_render_view_host_test_harness.h" #include "chrome/test/base/testing_profile.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/events/event_utils.h" +#include "ui/views/test/test_views_delegate.h" class ReloadButtonTest : public ChromeRenderViewHostTestHarness { public: @@ -26,7 +28,13 @@ int reload_count() { return reload_.testing_reload_count_; } protected: + ReloadButton* reload() { return &reload_; } + + private: + views::TestViewsDelegate views_delegate_; ReloadButton reload_; + + DISALLOW_COPY_AND_ASSIGN(ReloadButtonTest); }; ReloadButtonTest::ReloadButtonTest() : reload_(profile(), nullptr) { @@ -59,18 +67,18 @@ // Press the button. This should start the double-click timer. ui::MouseEvent e(ui::ET_MOUSE_PRESSED, gfx::Point(), gfx::Point(), ui::EventTimeForNow(), 0, 0); - reload_.ButtonPressed(&reload_, e); + reload()->ButtonPressed(reload(), e); CheckState(true, ReloadButton::MODE_RELOAD, ReloadButton::MODE_RELOAD, true, false); // Now change the mode (as if the browser had started loading the page). This // should cancel the double-click timer since the button is not hovered. - reload_.ChangeMode(ReloadButton::MODE_STOP, false); + reload()->ChangeMode(ReloadButton::MODE_STOP, false); CheckState(true, ReloadButton::MODE_STOP, ReloadButton::MODE_STOP, false, false); // Press the button again. This should change back to reload. - reload_.ButtonPressed(&reload_, e); + reload()->ButtonPressed(reload(), e); CheckState(true, ReloadButton::MODE_RELOAD, ReloadButton::MODE_RELOAD, false, false); } @@ -79,12 +87,12 @@ // Start by pressing the button. ui::MouseEvent e(ui::ET_MOUSE_PRESSED, gfx::Point(), gfx::Point(), ui::EventTimeForNow(), 0, 0); - reload_.ButtonPressed(&reload_, e); + reload()->ButtonPressed(reload(), e); // Try to press the button again. This should do nothing because the timer is // running. int original_reload_count = reload_count(); - reload_.ButtonPressed(&reload_, e); + reload()->ButtonPressed(reload(), e); CheckState(true, ReloadButton::MODE_RELOAD, ReloadButton::MODE_RELOAD, true, false); EXPECT_EQ(original_reload_count, reload_count()); @@ -92,7 +100,7 @@ // Hover the button, and change mode. The visible mode should not change, // again because the timer is running. set_mouse_hovered(true); - reload_.ChangeMode(ReloadButton::MODE_STOP, false); + reload()->ChangeMode(ReloadButton::MODE_STOP, false); CheckState(true, ReloadButton::MODE_STOP, ReloadButton::MODE_RELOAD, true, false); @@ -106,13 +114,13 @@ // Change to stop and hover. ui::MouseEvent e(ui::ET_MOUSE_PRESSED, gfx::Point(), gfx::Point(), ui::EventTimeForNow(), 0, 0); - reload_.ButtonPressed(&reload_, e); - reload_.ChangeMode(ReloadButton::MODE_STOP, false); + reload()->ButtonPressed(reload(), e); + reload()->ChangeMode(ReloadButton::MODE_STOP, false); set_mouse_hovered(true); // Now change back to reload. This should result in a disabled stop button // due to the hover. - reload_.ChangeMode(ReloadButton::MODE_RELOAD, false); + reload()->ChangeMode(ReloadButton::MODE_RELOAD, false); CheckState(false, ReloadButton::MODE_RELOAD, ReloadButton::MODE_STOP, false, true); @@ -120,7 +128,7 @@ set_mouse_hovered(false); ui::MouseEvent e2(ui::ET_MOUSE_MOVED, gfx::Point(), gfx::Point(), ui::EventTimeForNow(), 0, 0); - reload_.OnMouseExited(e2); + reload()->OnMouseExited(e2); CheckState(true, ReloadButton::MODE_RELOAD, ReloadButton::MODE_RELOAD, false, false); } @@ -129,13 +137,13 @@ // Change to stop and hover. ui::MouseEvent e(ui::ET_MOUSE_PRESSED, gfx::Point(), gfx::Point(), ui::EventTimeForNow(), 0, 0); - reload_.ButtonPressed(&reload_, e); - reload_.ChangeMode(ReloadButton::MODE_STOP, false); + reload()->ButtonPressed(reload(), e); + reload()->ChangeMode(ReloadButton::MODE_STOP, false); set_mouse_hovered(true); // Press the button. This should change back to reload despite the hover, // because it's a direct user action. - reload_.ButtonPressed(&reload_, e); + reload()->ButtonPressed(reload(), e); CheckState(true, ReloadButton::MODE_RELOAD, ReloadButton::MODE_RELOAD, false, false); } @@ -144,10 +152,10 @@ // Change to stop, hover, and change back to reload. ui::MouseEvent e(ui::ET_MOUSE_PRESSED, gfx::Point(), gfx::Point(), ui::EventTimeForNow(), 0, 0); - reload_.ButtonPressed(&reload_, e); - reload_.ChangeMode(ReloadButton::MODE_STOP, false); + reload()->ButtonPressed(reload(), e); + reload()->ChangeMode(ReloadButton::MODE_STOP, false); set_mouse_hovered(true); - reload_.ChangeMode(ReloadButton::MODE_RELOAD, false); + reload()->ChangeMode(ReloadButton::MODE_RELOAD, false); // Now fire the stop-to-reload timer. This should reset the button. base::RunLoop().RunUntilIdle();
diff --git a/chrome/browser/ui/views/website_settings/permission_selector_row.cc b/chrome/browser/ui/views/website_settings/permission_selector_row.cc index 6554dae..7fca592 100644 --- a/chrome/browser/ui/views/website_settings/permission_selector_row.cc +++ b/chrome/browser/ui/views/website_settings/permission_selector_row.cc
@@ -26,11 +26,6 @@ #include "ui/views/view.h" #include "ui/views/widget/widget.h" -namespace { -// Minimum distance between the label and its corresponding menu. -const int kMinSeparationBetweenLabelAndMenu = 16; -} // namespace - namespace internal { // The |PermissionMenuButton| provides a menu for selecting a setting a @@ -74,6 +69,12 @@ PermissionMenuModel* model, bool show_menu_marker) : MenuButton(text, this, show_menu_marker), menu_model_(model) { + // Since PermissionMenuButtons are added to a GridLayout, they are not always + // sized to their preferred size. Disclosure arrows are always right-aligned, + // so if the text is not right-aligned, awkward space appears between the text + // and the arrow. + SetHorizontalAlignment(gfx::ALIGN_RIGHT); + // Update the themed border before the NativeTheme is applied. Usually this // happens in a call to LabelButton::OnNativeThemeChanged(). However, if // PermissionMenuButton called that from its override, the NativeTheme would @@ -232,39 +233,19 @@ PermissionSelectorRow::PermissionSelectorRow( Profile* profile, const GURL& url, - const WebsiteSettingsUI::PermissionInfo& permission) + const WebsiteSettingsUI::PermissionInfo& permission, + views::GridLayout* layout) : profile_(profile), icon_(NULL), menu_button_(NULL), combobox_(NULL) { - views::GridLayout* layout = new views::GridLayout(this); - SetLayoutManager(layout); - const int column_set_id = 0; - views::ColumnSet* column_set = layout->AddColumnSet(column_set_id); - column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 0, - views::GridLayout::FIXED, kPermissionIconColumnWidth, - 0); - column_set->AddPaddingColumn(0, kPermissionIconMarginLeft); - column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 0, - views::GridLayout::USE_PREF, 0, 0); - column_set->AddPaddingColumn(1, kMinSeparationBetweenLabelAndMenu); - column_set->AddColumn(views::GridLayout::TRAILING, views::GridLayout::FILL, 0, - views::GridLayout::USE_PREF, 0, 0); - - layout->StartRow(1, column_set_id); // Create the permission icon. icon_ = new NonAccessibleImageView(); const gfx::Image& image = WebsiteSettingsUI::GetPermissionIcon(permission); icon_->SetImage(image.ToImageSkia()); - layout->AddView(icon_, - 1, - 1, - views::GridLayout::CENTER, + layout->AddView(icon_, 1, 1, views::GridLayout::CENTER, views::GridLayout::CENTER); // Create the label that displays the permission type. - views::Label* label = new views::Label( + label_ = new views::Label( WebsiteSettingsUI::PermissionTypeToUIString(permission.type)); - layout->AddView(label, - 1, - 1, - views::GridLayout::LEADING, + layout->AddView(label_, 1, 1, views::GridLayout::LEADING, views::GridLayout::CENTER); // Create the menu model. menu_model_.reset(new PermissionMenuModel( @@ -290,10 +271,6 @@ observer_list_.AddObserver(observer); } -void PermissionSelectorRow::ChildPreferredSizeChanged(View* child) { - Layout(); -} - PermissionSelectorRow::~PermissionSelectorRow() { // Gross. On paper the Combobox and the ComboboxModelAdapter are both owned by // this class, but actually, the Combobox is owned by View and will be @@ -306,7 +283,7 @@ // Technically, the MenuButton has the same problem, but MenuButton doesn't // use its model in its destructor. if (combobox_) - RemoveChildView(combobox_); + combobox_->parent()->RemoveChildView(combobox_); } void PermissionSelectorRow::InitializeMenuButtonView( @@ -352,6 +329,10 @@ profile_, permission.type, permission.setting, permission.default_setting, content_settings::SETTING_SOURCE_USER)); menu_button_->SizeToPreferredSize(); + // Re-layout will be done at the |WebsiteSettingsPopupView| level, since + // that view may need to resize itself to accomodate the new sizes of its + // contents. + menu_button_->InvalidateLayout(); } else if (combobox_) { bool use_default = permission.setting == CONTENT_SETTING_DEFAULT; combobox_->UpdateSelectedIndex(use_default); @@ -360,3 +341,11 @@ for (PermissionSelectorRowObserver& observer : observer_list_) observer.OnPermissionChanged(permission); } + +views::View* PermissionSelectorRow::button() { + // These casts are required because the two arms of a ?: cannot have different + // types T1 and T2, even if the resulting value of the ?: is about to be a T + // and T1 and T2 are both subtypes of T. + return menu_button_ ? static_cast<views::View*>(menu_button_) + : static_cast<views::View*>(combobox_); +}
diff --git a/chrome/browser/ui/views/website_settings/permission_selector_row.h b/chrome/browser/ui/views/website_settings/permission_selector_row.h index 28310c39..51a9b62 100644 --- a/chrome/browser/ui/views/website_settings/permission_selector_row.h +++ b/chrome/browser/ui/views/website_settings/permission_selector_row.h
@@ -10,14 +10,12 @@ #include "base/compiler_specific.h" #include "base/macros.h" #include "base/observer_list.h" -#include "base/strings/string16.h" #include "chrome/browser/ui/views/website_settings/permission_selector_row_observer.h" #include "chrome/browser/ui/website_settings/permission_menu_model.h" #include "chrome/browser/ui/website_settings/website_settings_ui.h" #include "components/content_settings/core/common/content_settings.h" #include "components/content_settings/core/common/content_settings_types.h" #include "ui/views/controls/button/menu_button_listener.h" -#include "ui/views/view.h" class Profile; @@ -27,30 +25,37 @@ class PermissionMenuButton; } +namespace test { +class WebsiteSettingsPopupViewTestApi; +} + namespace views { class GridLayout; class ImageView; +class Label; +class View; } -// A PermissionSelectorRow is a row in the Page Info bubble that shows a +// A |PermissionSelectorRow| is a row in the Page Info bubble that shows a // permission that a site can have ambient access to, and allows the user to -// control whether that access is granted. -class PermissionSelectorRow : public views::View { +// control whether that access is granted. A |PermissionSelectorRow| is not +// itself a |View|, but creates some |View|s, which end up owned by the |View| +// hierarchy. +class PermissionSelectorRow { public: + // The |PermissionSelectorRow|'s constituent views are added to |layout|. PermissionSelectorRow(Profile* profile, const GURL& url, - const WebsiteSettingsUI::PermissionInfo& permission); + const WebsiteSettingsUI::PermissionInfo& permission, + views::GridLayout* layout); + virtual ~PermissionSelectorRow(); void AddObserver(PermissionSelectorRowObserver* observer); void PermissionChanged(const WebsiteSettingsUI::PermissionInfo& permission); - protected: - // Overridden from views::View. - void ChildPreferredSizeChanged(View* child) override; - private: - ~PermissionSelectorRow() override; + friend class test::WebsiteSettingsPopupViewTestApi; void InitializeMenuButtonView( views::GridLayout* layout, @@ -59,15 +64,21 @@ views::GridLayout* layout, const WebsiteSettingsUI::PermissionInfo& permission); + // Returns the "button" for this row, which is the control used to change the + // permission's value. This is either a |MenuButton| or a |Combobox|. + views::View* button(); + Profile* profile_; // Model for the permission's menu. std::unique_ptr<PermissionMenuModel> menu_model_; std::unique_ptr<internal::ComboboxModelAdapter> combobox_model_adapter_; - views::ImageView* icon_; // Owned by the views hierachy. - internal::PermissionMenuButton* menu_button_; // Owned by the views hierachy. - internal::PermissionCombobox* combobox_; // Owned by the views hierarchy. + // These are all owned by the views hierarchy: + views::ImageView* icon_; + views::Label* label_; + internal::PermissionMenuButton* menu_button_; + internal::PermissionCombobox* combobox_; base::ObserverList<PermissionSelectorRowObserver, false> observer_list_;
diff --git a/chrome/browser/ui/views/website_settings/website_settings_popup_view.cc b/chrome/browser/ui/views/website_settings/website_settings_popup_view.cc index 98b2ed0..707d035b 100644 --- a/chrome/browser/ui/views/website_settings/website_settings_popup_view.cc +++ b/chrome/browser/ui/views/website_settings/website_settings_popup_view.cc
@@ -97,6 +97,9 @@ // Spacing between rows in the site settings section const int kPermissionsVerticalSpacing = 12; +// Spacing between the label and the menu. +const int kPermissionMenuSpacing = 16; + // Button/styled label/link IDs ------------------------------------------------ const int BUTTON_CLOSE = 1337; const int STYLED_LABEL_SECURITY_DETAILS = 1338; @@ -464,7 +467,8 @@ const WebsiteSettingsUI::PermissionInfo& permission) { presenter_->OnSitePermissionChanged(permission.type, permission.setting); // The menu buttons for the permissions might have longer strings now, so we - // need to size the whole bubble. + // need to layout and size the whole bubble. + Layout(); SizeToContents(); } @@ -627,16 +631,29 @@ views::GridLayout::USE_PREF, 0, 0); + const int permissions_column = 1; + views::ColumnSet* permissions_set = layout->AddColumnSet(permissions_column); + permissions_set->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, + 0, views::GridLayout::FIXED, + kPermissionIconColumnWidth, 0); + permissions_set->AddPaddingColumn(0, kPermissionIconMarginLeft); + permissions_set->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, + 0, views::GridLayout::USE_PREF, 0, 0); + permissions_set->AddPaddingColumn(1, kPermissionMenuSpacing); + permissions_set->AddColumn(views::GridLayout::TRAILING, + views::GridLayout::FILL, 0, + views::GridLayout::USE_PREF, 0, 0); for (const auto& permission : permission_info_list) { - layout->StartRow(1, content_column); - PermissionSelectorRow* selector = new PermissionSelectorRow( - profile_, - web_contents() ? web_contents()->GetVisibleURL() : GURL::EmptyGURL(), - permission); + layout->StartRow(1, permissions_column); + std::unique_ptr<PermissionSelectorRow> selector = + base::MakeUnique<PermissionSelectorRow>( + profile_, + web_contents() ? web_contents()->GetVisibleURL() + : GURL::EmptyGURL(), + permission, layout); selector->AddObserver(this); - layout->AddView(selector, 1, 1, views::GridLayout::FILL, - views::GridLayout::CENTER); layout->AddPaddingRow(1, kPermissionsVerticalSpacing); + selector_rows_.push_back(std::move(selector)); } for (auto& object : chosen_object_info_list) {
diff --git a/chrome/browser/ui/views/website_settings/website_settings_popup_view.h b/chrome/browser/ui/views/website_settings/website_settings_popup_view.h index 0a5e461..f355c694 100644 --- a/chrome/browser/ui/views/website_settings/website_settings_popup_view.h +++ b/chrome/browser/ui/views/website_settings/website_settings_popup_view.h
@@ -11,6 +11,7 @@ #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "chrome/browser/ui/views/website_settings/chosen_object_row_observer.h" +#include "chrome/browser/ui/views/website_settings/permission_selector_row.h" #include "chrome/browser/ui/views/website_settings/permission_selector_row_observer.h" #include "chrome/browser/ui/website_settings/website_settings_ui.h" #include "content/public/browser/web_contents_observer.h" @@ -172,6 +173,11 @@ // The certificate provided by the site, if one exists. scoped_refptr<net::X509Certificate> certificate_; + // These rows bundle together all the |View|s involved in a single row of the + // permissions section, and keep those views updated when the underlying + // |Permission| changes. + std::vector<std::unique_ptr<PermissionSelectorRow>> selector_rows_; + base::WeakPtrFactory<WebsiteSettingsPopupView> weak_factory_; DISALLOW_COPY_AND_ASSIGN(WebsiteSettingsPopupView);
diff --git a/chrome/browser/ui/views/website_settings/website_settings_popup_view_unittest.cc b/chrome/browser/ui/views/website_settings/website_settings_popup_view_unittest.cc index 6b6db78..5e9255dc 100644 --- a/chrome/browser/ui/views/website_settings/website_settings_popup_view_unittest.cc +++ b/chrome/browser/ui/views/website_settings/website_settings_popup_view_unittest.cc
@@ -56,13 +56,21 @@ views::View* permissions_view() { return view_->permissions_view_; } PermissionSelectorRow* GetPermissionSelectorAt(int index) { - return static_cast<PermissionSelectorRow*>( - permissions_view()->child_at(index)); + return view_->selector_rows_[index].get(); + } + + // Returns the permission label text of the |index|th permission selector row. + // This function returns an empty string if the permission selector row's + // |label_| element isn't actually a |views::Label|. + base::string16 GetPermissionLabelTextAt(int index) { + views::View* view = GetPermissionSelectorAt(index)->label_; + if (view->GetClassName() == views::Label::kViewClassName) + return static_cast<views::Label*>(view)->text(); + return base::string16(); } base::string16 GetPermissionButtonTextAt(int index) { - const int kButtonIndex = 2; // Button should be the third child. - views::View* view = GetPermissionSelectorAt(index)->child_at(kButtonIndex); + views::View* view = GetPermissionSelectorAt(index)->button(); if (view->GetClassName() == views::MenuButton::kViewClassName) { return static_cast<views::MenuButton*>(view)->GetText(); } else if (view->GetClassName() == views::Combobox::kViewClassName) { @@ -165,6 +173,9 @@ #define MAYBE_SetPermissionInfo SetPermissionInfo #endif +// Each permission selector row is like this: [icon] [label] [selector] +constexpr int kViewsPerPermissionRow = 3; + // Test UI construction and reconstruction via // WebsiteSettingsPopupView::SetPermissionInfo(). TEST_F(WebsiteSettingsPopupViewTest, MAYBE_SetPermissionInfo) { @@ -175,7 +186,8 @@ list.back().setting = CONTENT_SETTING_DEFAULT; const int kExpectedChildren = - ExclusiveAccessManager::IsSimplifiedFullscreenUIEnabled() ? 11 : 13; + kViewsPerPermissionRow * + (ExclusiveAccessManager::IsSimplifiedFullscreenUIEnabled() ? 11 : 13); EXPECT_EQ(kExpectedChildren, api_->permissions_view()->child_count()); list.back().setting = CONTENT_SETTING_ALLOW; @@ -183,15 +195,10 @@ EXPECT_EQ(kExpectedChildren, api_->permissions_view()->child_count()); PermissionSelectorRow* selector = api_->GetPermissionSelectorAt(0); - EXPECT_EQ(3, selector->child_count()); + EXPECT_TRUE(selector); // Verify labels match the settings on the PermissionInfoList. - const int kLabelIndex = 1; - EXPECT_EQ(views::Label::kViewClassName, - selector->child_at(kLabelIndex)->GetClassName()); - views::Label* label = - static_cast<views::Label*>(selector->child_at(kLabelIndex)); - EXPECT_EQ(base::ASCIIToUTF16("Location"), label->text()); + EXPECT_EQ(base::ASCIIToUTF16("Location"), api_->GetPermissionLabelTextAt(0)); EXPECT_EQ(base::ASCIIToUTF16("Allow"), api_->GetPermissionButtonTextAt(0)); // Verify calling SetPermisisonInfo() directly updates the UI. @@ -221,7 +228,8 @@ // Test UI construction and reconstruction with USB devices. TEST_F(WebsiteSettingsPopupViewTest, SetPermissionInfoWithUsbDevice) { const int kExpectedChildren = - ExclusiveAccessManager::IsSimplifiedFullscreenUIEnabled() ? 11 : 13; + kViewsPerPermissionRow * + (ExclusiveAccessManager::IsSimplifiedFullscreenUIEnabled() ? 11 : 13); EXPECT_EQ(kExpectedChildren, api_->permissions_view()->child_count()); const GURL origin = GURL(kUrl).GetOrigin();
diff --git a/chrome/browser/ui/webui/interstitials/interstitial_ui.cc b/chrome/browser/ui/webui/interstitials/interstitial_ui.cc index 0f6e454..2317c5b 100644 --- a/chrome/browser/ui/webui/interstitials/interstitial_ui.cc +++ b/chrome/browser/ui/webui/interstitials/interstitial_ui.cc
@@ -15,10 +15,12 @@ #include "chrome/browser/safe_browsing/ui_manager.h" #include "chrome/browser/ssl/bad_clock_blocking_page.h" #include "chrome/browser/ssl/ssl_blocking_page.h" +#include "chrome/browser/supervised_user/supervised_user_interstitial.h" #include "chrome/common/features.h" #include "chrome/common/url_constants.h" #include "components/grit/components_resources.h" #include "components/security_interstitials/core/ssl_error_ui.h" +#include "components/supervised_user_error_page/supervised_user_error_page.h" #include "content/public/browser/interstitial_page_delegate.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_process_host.h" @@ -65,7 +67,7 @@ // not used in displaying any real interstitials. class InterstitialHTMLSource : public content::URLDataSource { public: - InterstitialHTMLSource() {} + explicit InterstitialHTMLSource(Profile* profile) : profile_(profile) {} ~InterstitialHTMLSource() override {} // content::URLDataSource: @@ -80,6 +82,8 @@ const content::URLDataSource::GotDataCallback& callback) override; private: + Profile* profile_; + DISALLOW_COPY_AND_ASSIGN(InterstitialHTMLSource); }; @@ -308,7 +312,7 @@ InterstitialUI::InterstitialUI(content::WebUI* web_ui) : WebUIController(web_ui) { Profile* profile = Profile::FromWebUI(web_ui); - content::URLDataSource::Add(profile, new InterstitialHTMLSource()); + content::URLDataSource::Add(profile, new InterstitialHTMLSource(profile)); } InterstitialUI::~InterstitialUI() { @@ -365,7 +369,12 @@ } #endif std::string html; - if (interstitial_delegate.get()) { + if (base::StartsWith(path, "supervised_user", base::CompareCase::SENSITIVE)) { + html = SupervisedUserInterstitial::GetHTMLContents( + profile_, profile_->IsChild() + ? supervised_user_error_page::ASYNC_CHECKER + : supervised_user_error_page::MANUAL); + } else if (interstitial_delegate.get()) { html = interstitial_delegate.get()->GetHTMLContents(); } else { html = ResourceBundle::GetSharedInstance()
diff --git a/chrome/browser/ui/webui/physical_web/physical_web_ui.cc b/chrome/browser/ui/webui/physical_web/physical_web_ui.cc index a37fb45..c7de25f 100644 --- a/chrome/browser/ui/webui/physical_web/physical_web_ui.cc +++ b/chrome/browser/ui/webui/physical_web/physical_web_ui.cc
@@ -25,6 +25,8 @@ source->AddLocalizedString(physical_web_ui::kTitle, IDS_PHYSICAL_WEB_UI_TITLE); + source->AddLocalizedString(physical_web_ui::kEmptyMessage, + IDS_PHYSICAL_WEB_UI_EMPTY_MESSAGE); source->SetJsonPath("strings.js"); source->AddResourcePath(physical_web_ui::kPhysicalWebJS, IDR_PHYSICAL_WEB_UI_JS);
diff --git a/chrome/browser/ui/webui/snippets_internals_message_handler.cc b/chrome/browser/ui/webui/snippets_internals_message_handler.cc index c67289d6..3d78bada 100644 --- a/chrome/browser/ui/webui/snippets_internals_message_handler.cc +++ b/chrome/browser/ui/webui/snippets_internals_message_handler.cc
@@ -75,8 +75,6 @@ return "ALL_SUGGESTIONS_EXPLICITLY_DISABLED"; case CategoryStatus::CATEGORY_EXPLICITLY_DISABLED: return "CATEGORY_EXPLICITLY_DISABLED"; - case CategoryStatus::SIGNED_OUT: - return "SIGNED_OUT"; case CategoryStatus::LOADING_ERROR: return "LOADING_ERROR"; }
diff --git a/chrome/common/url_constants.cc b/chrome/common/url_constants.cc index aa45e9b..ea2fd186 100644 --- a/chrome/common/url_constants.cc +++ b/chrome/common/url_constants.cc
@@ -747,6 +747,7 @@ const size_t kNumberOfChromeHostURLs = arraysize(kChromeHostURLs); const char* const kChromeDebugURLs[] = {content::kChromeUIBadCastCrashURL, + content::kChromeUIBrowserCrashURL, content::kChromeUICrashURL, content::kChromeUIDumpURL, content::kChromeUIKillURL,
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/TabLoadObserver.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/TabLoadObserver.java index 11efcc21..a7c486b2 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/TabLoadObserver.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/TabLoadObserver.java
@@ -44,7 +44,7 @@ } @Override - public void onLoadStarted(Tab tab, boolean toDifferentDocument) { + public void onPageLoadStarted(Tab tab, String url) { mTabLoadStartedCallback.notifyCalled(); }
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/suggestions/FakeSuggestionsSource.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/suggestions/FakeSuggestionsSource.java index c806196..b2969cad 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/suggestions/FakeSuggestionsSource.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/suggestions/FakeSuggestionsSource.java
@@ -91,6 +91,13 @@ } /** + * Notifies the observer that a full refresh is required. + */ + public void fireFullRefreshRequired() { + mObserver.onFullRefreshRequired(); + } + + /** * Removes a category from the fake source without notifying anyone. */ public void silentlyRemoveCategory(int category) {
diff --git a/chrome/test/base/testing_browser_process.cc b/chrome/test/base/testing_browser_process.cc index c2980ebe..8896b386 100644 --- a/chrome/test/base/testing_browser_process.cc +++ b/chrome/test/base/testing_browser_process.cc
@@ -24,7 +24,7 @@ #include "components/network_time/network_time_tracker.h" #include "components/policy/core/browser/browser_policy_connector.h" #include "components/prefs/pref_service.h" -#include "components/subresource_filter/core/browser/ruleset_service.h" +#include "components/subresource_filter/content/browser/content_ruleset_service.h" #include "content/public/browser/notification_service.h" #include "extensions/features/features.h" #include "media/media_features.h" @@ -222,7 +222,7 @@ return nullptr; } -subresource_filter::RulesetService* +subresource_filter::ContentRulesetService* TestingBrowserProcess::subresource_filter_ruleset_service() { return subresource_filter_ruleset_service_.get(); } @@ -461,8 +461,9 @@ } void TestingBrowserProcess::SetRulesetService( - std::unique_ptr<subresource_filter::RulesetService> ruleset_service) { - subresource_filter_ruleset_service_.swap(ruleset_service); + std::unique_ptr<subresource_filter::ContentRulesetService> + content_ruleset_service) { + subresource_filter_ruleset_service_.swap(content_ruleset_service); } void TestingBrowserProcess::SetRapporServiceImpl(
diff --git a/chrome/test/base/testing_browser_process.h b/chrome/test/base/testing_browser_process.h index 041c263..421de7e 100644 --- a/chrome/test/base/testing_browser_process.h +++ b/chrome/test/base/testing_browser_process.h
@@ -85,8 +85,8 @@ safe_browsing::SafeBrowsingService* safe_browsing_service() override; safe_browsing::ClientSideDetectionService* safe_browsing_detection_service() override; - subresource_filter::RulesetService* subresource_filter_ruleset_service() - override; + subresource_filter::ContentRulesetService* + subresource_filter_ruleset_service() override; net::URLRequestContextGetter* system_request_context() override; BrowserProcessPlatformPart* platform_part() override; @@ -141,7 +141,8 @@ void SetIOThread(IOThread* io_thread); void SetSafeBrowsingService(safe_browsing::SafeBrowsingService* sb_service); void SetRulesetService( - std::unique_ptr<subresource_filter::RulesetService> ruleset_service); + std::unique_ptr<subresource_filter::ContentRulesetService> + ruleset_service); void SetSystemRequestContext(net::URLRequestContextGetter* context_getter); void SetNotificationUIManager( std::unique_ptr<NotificationUIManager> notification_ui_manager); @@ -179,7 +180,7 @@ #endif scoped_refptr<safe_browsing::SafeBrowsingService> sb_service_; - std::unique_ptr<subresource_filter::RulesetService> + std::unique_ptr<subresource_filter::ContentRulesetService> subresource_filter_ruleset_service_; std::unique_ptr<network_time::NetworkTimeTracker> network_time_tracker_;
diff --git a/chrome/test/chromedriver/test/test_expectations b/chrome/test/chromedriver/test/test_expectations index 2ac40793..5ffb754 100644 --- a/chrome/test/chromedriver/test/test_expectations +++ b/chrome/test/chromedriver/test/test_expectations
@@ -107,7 +107,8 @@ _REVISION_NEGATIVE_FILTER['HEAD'] + [ # https://bugs.chromium.org/p/chromedriver/issues/detail?id=1674 'WindowSwitchingTest.testShouldBeAbleToIterateOverAllOpenWindows', -] + ] +) _REVISION_NEGATIVE_FILTER['57'] = ( _REVISION_NEGATIVE_FILTER['HEAD'] + [ # https://bugs.chromium.org/p/chromedriver/issues/detail?id=1625
diff --git a/chromecast/browser/cast_browser_main_parts.cc b/chromecast/browser/cast_browser_main_parts.cc index 6ae15530..bf8e156 100644 --- a/chromecast/browser/cast_browser_main_parts.cc +++ b/chromecast/browser/cast_browser_main_parts.cc
@@ -439,15 +439,14 @@ memory_pressure_monitor_.reset(new CastMemoryPressureMonitor()); #endif // defined(OS_ANDROID) + cast_browser_process_->SetNetLog(net_log_.get()); + url_request_context_factory_->InitializeOnUIThread(net_log_.get()); + cast_browser_process_->SetConnectivityChecker(ConnectivityChecker::Create( content::BrowserThread::GetTaskRunnerForThread( content::BrowserThread::IO), url_request_context_factory_->GetSystemGetter())); - cast_browser_process_->SetNetLog(net_log_.get()); - - url_request_context_factory_->InitializeOnUIThread(net_log_.get()); - cast_browser_process_->SetBrowserContext( base::MakeUnique<CastBrowserContext>(url_request_context_factory_)); cast_browser_process_->SetMetricsServiceClient(
diff --git a/chromecast/browser/url_request_context_factory.cc b/chromecast/browser/url_request_context_factory.cc index b6def5f..658c5ee9 100644 --- a/chromecast/browser/url_request_context_factory.cc +++ b/chromecast/browser/url_request_context_factory.cc
@@ -253,6 +253,7 @@ // in the future. http_server_properties_.reset(new net::HttpServerPropertiesImpl); + DCHECK(proxy_config_service_); proxy_service_ = net::ProxyService::CreateUsingSystemProxyResolver( std::move(proxy_config_service_), 0, NULL); system_dependencies_initialized_ = true;
diff --git a/cloud_print/DEPS b/cloud_print/DEPS index edd33b74..51643dee 100644 --- a/cloud_print/DEPS +++ b/cloud_print/DEPS
@@ -1,5 +1,4 @@ include_rules = [ "+chrome/common", "+chrome/installer/launcher_support", - "+virtual_driver_setup_resources", ]
diff --git a/cloud_print/virtual_driver/win/install/BUILD.gn b/cloud_print/virtual_driver/win/install/BUILD.gn index 2c8fbaa0..17b7fd2 100644 --- a/cloud_print/virtual_driver/win/install/BUILD.gn +++ b/cloud_print/virtual_driver/win/install/BUILD.gn
@@ -62,7 +62,7 @@ # TODO(thakis): Consider removing this in favor of the default directory, # https://crbug.com/697092 - output_dir = "$root_gen_dir/virtual_driver_setup_resources" + # output_dir = "$root_gen_dir/virtual_driver_setup_resources" outputs = [ "grit/virtual_driver_setup_resources.h",
diff --git a/cloud_print/virtual_driver/win/install/setup.cc b/cloud_print/virtual_driver/win/install/setup.cc index 64eef52..70ae0dd 100644 --- a/cloud_print/virtual_driver/win/install/setup.cc +++ b/cloud_print/virtual_driver/win/install/setup.cc
@@ -21,9 +21,9 @@ #include "base/win/windows_version.h" #include "cloud_print/common/win/cloud_print_utils.h" #include "cloud_print/common/win/install_utils.h" +#include "cloud_print/virtual_driver/win/install/grit/virtual_driver_setup_resources.h" #include "cloud_print/virtual_driver/win/virtual_driver_consts.h" #include "cloud_print/virtual_driver/win/virtual_driver_helpers.h" -#include "virtual_driver_setup_resources/grit/virtual_driver_setup_resources.h" #include <strsafe.h> // Must be after base headers to avoid deprecation // warnings.
diff --git a/components/autofill/content/renderer/password_generation_agent.cc b/components/autofill/content/renderer/password_generation_agent.cc index d31e213f..aed44577 100644 --- a/components/autofill/content/renderer/password_generation_agent.cc +++ b/components/autofill/content/renderer/password_generation_agent.cc
@@ -37,6 +37,8 @@ namespace { +using Logger = autofill::SavePasswordProgressLogger; + // Returns true if we think that this form is for account creation. |passwords| // is filled with the password field(s) in the form. bool GetAccountCreationPasswordFields( @@ -142,7 +144,7 @@ form_classifier_enabled_(false), password_agent_(password_agent), binding_(this) { - VLOG(2) << "Password Generation is " << (enabled_ ? "Enabled" : "Disabled"); + LogBoolean(Logger::STRING_GENERATION_RENDERER_ENABLED, enabled_); // PasswordGenerationAgent is guaranteed to outlive |render_frame|. render_frame->GetInterfaceRegistry()->AddInterface(base::Bind( &PasswordGenerationAgent::BindRequest, base::Unretained(this))); @@ -258,7 +260,7 @@ std::unique_ptr<PasswordForm> password_form( CreatePasswordFormFromWebForm(forms[i], nullptr, nullptr)); if (!password_form.get()) { - VLOG(2) << "Skipping form as it would not be saved"; + LogMessage(Logger::STRING_GENERATION_RENDERER_INVALID_PASSWORD_FORM); continue; } @@ -281,13 +283,14 @@ } if (!possible_account_creation_forms_.empty()) { - VLOG(2) << possible_account_creation_forms_.size() - << " possible account creation forms deteceted"; + LogNumber( + Logger::STRING_GENERATION_RENDERER_POSSIBLE_ACCOUNT_CREATION_FORMS, + possible_account_creation_forms_.size()); DetermineGenerationElement(); } } -bool PasswordGenerationAgent::ShouldAnalyzeDocument() const { +bool PasswordGenerationAgent::ShouldAnalyzeDocument() { // Make sure that this security origin is allowed to use password manager. // Generating a password that can't be saved is a bad idea. if (!render_frame() || @@ -296,7 +299,7 @@ ->document() .getSecurityOrigin() .canAccessPasswordManager()) { - VLOG(1) << "No PasswordManager access"; + LogMessage(Logger::STRING_GENERATION_RENDERER_NO_PASSWORD_MANAGER_ACCESS); return false; } @@ -313,6 +316,7 @@ password_is_generated_ = true; password_generation::LogPasswordGenerationEvent( password_generation::PASSWORD_ACCEPTED); + LogMessage(Logger::STRING_GENERATION_RENDERER_GENERATED_PASSWORD_ACCEPTED); for (auto& password_element : generation_form_data_->password_elements) { password_element.setValue(blink::WebString::fromUTF16(password), true /* sendEvents */); @@ -368,15 +372,14 @@ void PasswordGenerationAgent::DetermineGenerationElement() { if (generation_form_data_) { - VLOG(2) << "Account creation form already found"; + LogMessage(Logger::STRING_GENERATION_RENDERER_FORM_ALREADY_FOUND); return; } // Make sure local heuristics have identified a possible account creation // form. if (possible_account_creation_forms_.empty()) { - VLOG(2) << "Local hueristics have not detected a possible account " - << "creation form"; + LogMessage(Logger::STRING_GENERATION_RENDERER_NO_POSSIBLE_CREATION_FORMS); return; } @@ -390,28 +393,23 @@ VLOG(2) << "Bypassing additional checks."; } else if (!ContainsURL(not_blacklisted_password_form_origins_, possible_password_form->origin)) { - VLOG(2) << "Have not received confirmation that password form isn't " - << "blacklisted"; + LogMessage(Logger::STRING_GENERATION_RENDERER_NOT_BLACKLISTED); continue; } else { generation_data = FindFormGenerationData(generation_enabled_forms_, *possible_password_form); if (!generation_data) { if (AutocompleteAttributesSetForGeneration(*possible_password_form)) { - VLOG(2) << "Ignoring lack of Autofill signal due to Autocomplete " - << "attributes"; + LogMessage(Logger::STRING_GENERATION_RENDERER_AUTOCOMPLETE_ATTRIBUTE); password_generation::LogPasswordGenerationEvent( password_generation::AUTOCOMPLETE_ATTRIBUTES_ENABLED_GENERATION); } else { - VLOG(2) - << "Have not received confirmation from Autofill that form is " - << "used for account creation"; + LogMessage(Logger::STRING_GENERATION_RENDERER_NO_SERVER_SIGNAL); continue; } } } - - VLOG(2) << "Password generation eligible form found"; + LogMessage(Logger::STRING_GENERATION_RENDERER_ELIGIBLE_FORM_FOUND); std::vector<blink::WebInputElement> password_elements = generation_data ? FindPasswordElementsForGeneration( @@ -419,7 +417,7 @@ : possible_form_data.password_elements; if (password_elements.empty()) { // It might be if JavaScript changes field names. - VLOG(2) << "Fields for generation are not found"; + LogMessage(Logger::STRING_GENERATION_RENDERER_NO_FIELD_FOUND); return; } generation_form_data_.reset(new AccountCreationFormData( @@ -522,6 +520,7 @@ void PasswordGenerationAgent::ShowGenerationPopup() { if (!render_frame()) return; + LogMessage(Logger::STRING_GENERATION_RENDERER_SHOW_GENERATION_POPUP); GetPasswordManagerClient()->ShowPasswordGenerationPopup( render_frame()->GetRenderView()->ElementBoundsInWindow( generation_element_), @@ -601,4 +600,27 @@ return password_manager_client_; } +void PasswordGenerationAgent::LogMessage(Logger::StringID message_id) { + if (!password_agent_->logging_state_active()) + return; + RendererSavePasswordProgressLogger logger(GetPasswordManagerDriver().get()); + logger.LogMessage(message_id); +} + +void PasswordGenerationAgent::LogBoolean(Logger::StringID message_id, + bool truth_value) { + if (!password_agent_->logging_state_active()) + return; + RendererSavePasswordProgressLogger logger(GetPasswordManagerDriver().get()); + logger.LogBoolean(message_id, truth_value); +} + +void PasswordGenerationAgent::LogNumber(Logger::StringID message_id, + int number) { + if (!password_agent_->logging_state_active()) + return; + RendererSavePasswordProgressLogger logger(GetPasswordManagerDriver().get()); + logger.LogNumber(message_id, number); +} + } // namespace autofill
diff --git a/components/autofill/content/renderer/password_generation_agent.h b/components/autofill/content/renderer/password_generation_agent.h index 694c5fc..c7cb5fb2 100644 --- a/components/autofill/content/renderer/password_generation_agent.h +++ b/components/autofill/content/renderer/password_generation_agent.h
@@ -16,6 +16,7 @@ #include "base/memory/linked_ptr.h" #include "components/autofill/content/common/autofill_agent.mojom.h" #include "components/autofill/content/common/autofill_driver.mojom.h" +#include "components/autofill/content/renderer/renderer_save_password_progress_logger.h" #include "content/public/renderer/render_frame_observer.h" #include "mojo/public/cpp/bindings/binding.h" #include "third_party/WebKit/public/web/WebInputElement.h" @@ -66,7 +67,7 @@ protected: // Returns true if the document for |render_frame()| is one that we should // consider analyzing. Virtual so that it can be overriden during testing. - virtual bool ShouldAnalyzeDocument() const; + virtual bool ShouldAnalyzeDocument(); // Use to force enable during testing. void set_enabled(bool enabled) { enabled_ = enabled; } @@ -118,6 +119,12 @@ void RunFormClassifierAndSaveVote(const blink::WebFormElement& web_form, const PasswordForm& form); + void LogMessage(autofill::SavePasswordProgressLogger::StringID message_id); + void LogBoolean(autofill::SavePasswordProgressLogger::StringID message_id, + bool truth_value); + void LogNumber(autofill::SavePasswordProgressLogger::StringID message_id, + int number); + // Creates a password form to presave a generated password. It copies behavior // of CreatePasswordFormFromWebForm/FromUnownedInputElements, but takes // |password_value| from |generation_element_| and empties |username_value|.
diff --git a/components/autofill/content/renderer/test_password_generation_agent.cc b/components/autofill/content/renderer/test_password_generation_agent.cc index d8707b0f..84d937a79 100644 --- a/components/autofill/content/renderer/test_password_generation_agent.cc +++ b/components/autofill/content/renderer/test_password_generation_agent.cc
@@ -15,7 +15,7 @@ TestPasswordGenerationAgent::~TestPasswordGenerationAgent() {} -bool TestPasswordGenerationAgent::ShouldAnalyzeDocument() const { +bool TestPasswordGenerationAgent::ShouldAnalyzeDocument() { return true; }
diff --git a/components/autofill/content/renderer/test_password_generation_agent.h b/components/autofill/content/renderer/test_password_generation_agent.h index 333b4321..11aef9d 100644 --- a/components/autofill/content/renderer/test_password_generation_agent.h +++ b/components/autofill/content/renderer/test_password_generation_agent.h
@@ -21,7 +21,7 @@ // PasswordGenreationAgent implementation: // Always return true to allow loading of data URLs. - bool ShouldAnalyzeDocument() const override; + bool ShouldAnalyzeDocument() override; private: DISALLOW_COPY_AND_ASSIGN(TestPasswordGenerationAgent);
diff --git a/components/autofill/core/common/save_password_progress_logger.cc b/components/autofill/core/common/save_password_progress_logger.cc index 73be9b49..8a55fdd 100644 --- a/components/autofill/core/common/save_password_progress_logger.cc +++ b/components/autofill/core/common/save_password_progress_logger.cc
@@ -390,6 +390,39 @@ return "Form votes"; case SavePasswordProgressLogger::STRING_REUSE_FOUND: return "Password reused from "; + case SavePasswordProgressLogger::STRING_GENERATION_DISABLED_SAVING_DISABLED: + return "Generation disabled: saving disabled"; + case SavePasswordProgressLogger::STRING_GENERATION_DISABLED_NO_SYNC: + return "Generation disabled: no sync"; + case SavePasswordProgressLogger:: + STRING_GENERATION_DISABLED_CUSTOM_PASSPHRASE: + return "Generation disabled: custom passphrase"; + case STRING_GENERATION_RENDERER_ENABLED: + return "Generation renderer enabled"; + case STRING_GENERATION_RENDERER_INVALID_PASSWORD_FORM: + return "Generation invalid PasswordForm"; + case STRING_GENERATION_RENDERER_POSSIBLE_ACCOUNT_CREATION_FORMS: + return "Generation possible account creation forms"; + case STRING_GENERATION_RENDERER_NO_PASSWORD_MANAGER_ACCESS: + return "Generation: no PasswordManager access"; + case STRING_GENERATION_RENDERER_FORM_ALREADY_FOUND: + return "Generation: account creation form already found"; + case STRING_GENERATION_RENDERER_NO_POSSIBLE_CREATION_FORMS: + return "Generation: no possible account creation forms"; + case STRING_GENERATION_RENDERER_NOT_BLACKLISTED: + return "Generation: no non-blacklisted confirmation"; + case STRING_GENERATION_RENDERER_AUTOCOMPLETE_ATTRIBUTE: + return "Generation: autocomplete attributes found"; + case STRING_GENERATION_RENDERER_NO_SERVER_SIGNAL: + return "Generation: no server signal"; + case STRING_GENERATION_RENDERER_ELIGIBLE_FORM_FOUND: + return "Generation: eligible form found"; + case STRING_GENERATION_RENDERER_NO_FIELD_FOUND: + return "Generation: fields for generation are not found"; + case STRING_GENERATION_RENDERER_SHOW_GENERATION_POPUP: + return "Show generation popup"; + case STRING_GENERATION_RENDERER_GENERATED_PASSWORD_ACCEPTED: + return "Generated password accepted"; case SavePasswordProgressLogger::STRING_INVALID: return "INVALID"; // Intentionally no default: clause here -- all IDs need to get covered.
diff --git a/components/autofill/core/common/save_password_progress_logger.h b/components/autofill/core/common/save_password_progress_logger.h index de8a082..19c9e04c 100644 --- a/components/autofill/core/common/save_password_progress_logger.h +++ b/components/autofill/core/common/save_password_progress_logger.h
@@ -150,6 +150,22 @@ STRING_SERVER_PREDICTIONS, STRING_FORM_VOTES, STRING_REUSE_FOUND, + STRING_GENERATION_DISABLED_SAVING_DISABLED, + STRING_GENERATION_DISABLED_NO_SYNC, + STRING_GENERATION_DISABLED_CUSTOM_PASSPHRASE, + STRING_GENERATION_RENDERER_ENABLED, + STRING_GENERATION_RENDERER_INVALID_PASSWORD_FORM, + STRING_GENERATION_RENDERER_POSSIBLE_ACCOUNT_CREATION_FORMS, + STRING_GENERATION_RENDERER_NO_PASSWORD_MANAGER_ACCESS, + STRING_GENERATION_RENDERER_FORM_ALREADY_FOUND, + STRING_GENERATION_RENDERER_NO_POSSIBLE_CREATION_FORMS, + STRING_GENERATION_RENDERER_NOT_BLACKLISTED, + STRING_GENERATION_RENDERER_AUTOCOMPLETE_ATTRIBUTE, + STRING_GENERATION_RENDERER_NO_SERVER_SIGNAL, + STRING_GENERATION_RENDERER_ELIGIBLE_FORM_FOUND, + STRING_GENERATION_RENDERER_NO_FIELD_FOUND, + STRING_GENERATION_RENDERER_SHOW_GENERATION_POPUP, + STRING_GENERATION_RENDERER_GENERATED_PASSWORD_ACCEPTED, STRING_INVALID, // Represents a string returned in a case of an error. STRING_MAX = STRING_INVALID };
diff --git a/components/ntp_snippets/bookmarks/bookmark_last_visit_utils.cc b/components/ntp_snippets/bookmarks/bookmark_last_visit_utils.cc index 21ecd811..c2688710 100644 --- a/components/ntp_snippets/bookmarks/bookmark_last_visit_utils.cc +++ b/components/ntp_snippets/bookmarks/bookmark_last_visit_utils.cc
@@ -11,6 +11,7 @@ #include <utility> #include "base/bind.h" +#include "base/stl_util.h" #include "base/strings/string_number_conversions.h" #include "base/time/time.h" #include "components/bookmarks/browser/bookmark_model.h" @@ -29,9 +30,8 @@ base::Time last_visited; }; -const char* kBookmarksURLBlacklist[] = {"chrome://newtab/", - "chrome-native://newtab/", - "chrome://bookmarks/"}; +const char* kBookmarksURLBlacklist[] = { + "chrome://newtab/", "chrome-native://newtab/", "chrome://bookmarks/"}; const char kBookmarkLastVisitDateOnMobileKey[] = "last_visited"; const char kBookmarkLastVisitDateOnDesktopKey[] = "last_visited_desktop"; @@ -106,10 +106,11 @@ // If there are bookmarks for |url|, set their last visit date to now. std::string now = FormatLastVisitDate(base::Time::Now()); for (const BookmarkNode* node : bookmarks_for_url) { - bookmark_model->SetNodeMetaInfo( - node, is_mobile_platform ? kBookmarkLastVisitDateOnMobileKey - : kBookmarkLastVisitDateOnDesktopKey, - now); + bookmark_model->SetNodeMetaInfo(node, + is_mobile_platform + ? kBookmarkLastVisitDateOnMobileKey + : kBookmarkLastVisitDateOnDesktopKey, + now); // If the bookmark has been dismissed from NTP before, a new visit overrides // such a dismissal. bookmark_model->DeleteNodeMetaInfo(node, kBookmarkDismissedFromNTP); @@ -243,22 +244,19 @@ bookmark_model->GetBookmarks(&bookmarks); // Remove the bookmark URLs which have at least one non-dismissed bookmark. - bookmarks.erase( - std::remove_if( - bookmarks.begin(), bookmarks.end(), - [&bookmark_model](const BookmarkModel::URLAndTitle& bookmark) { - std::vector<const BookmarkNode*> bookmarks_for_url; - bookmark_model->GetNodesByURL(bookmark.url, &bookmarks_for_url); - DCHECK(!bookmarks_for_url.empty()); + base::EraseIf( + bookmarks, [&bookmark_model](const BookmarkModel::URLAndTitle& bookmark) { + std::vector<const BookmarkNode*> bookmarks_for_url; + bookmark_model->GetNodesByURL(bookmark.url, &bookmarks_for_url); + DCHECK(!bookmarks_for_url.empty()); - for (const BookmarkNode* node : bookmarks_for_url) { - if (!IsDismissedFromNTPForBookmark(*node)) { - return true; - } - } - return false; - }), - bookmarks.end()); + for (const BookmarkNode* node : bookmarks_for_url) { + if (!IsDismissedFromNTPForBookmark(*node)) { + return true; + } + } + return false; + }); // Insert into |result|. std::vector<const BookmarkNode*> result; @@ -306,7 +304,7 @@ ClearLastVisitedMetadataIfBetween(bookmark_model, *bookmark, begin, end, kBookmarkLastVisitDateOnMobileKey); ClearLastVisitedMetadataIfBetween(bookmark_model, *bookmark, begin, end, - kBookmarkLastVisitDateOnDesktopKey); + kBookmarkLastVisitDateOnDesktopKey); } } }
diff --git a/components/ntp_snippets/category_status.h b/components/ntp_snippets/category_status.h index 2f6c7cd..caf0ddf 100644 --- a/components/ntp_snippets/category_status.h +++ b/components/ntp_snippets/category_status.h
@@ -31,9 +31,6 @@ // the service configuration. CATEGORY_EXPLICITLY_DISABLED, - // Content suggestions are not available because the user is not signed in. - SIGNED_OUT, - // Content suggestions are not available because an error occurred when // loading or updating them. LOADING_ERROR
diff --git a/components/ntp_snippets/remote/remote_suggestions_provider_impl.cc b/components/ntp_snippets/remote/remote_suggestions_provider_impl.cc index 3e517b7e..81acdbe0 100644 --- a/components/ntp_snippets/remote/remote_suggestions_provider_impl.cc +++ b/components/ntp_snippets/remote/remote_suggestions_provider_impl.cc
@@ -74,13 +74,11 @@ void EraseByPrimaryID(RemoteSuggestion::PtrVector* suggestions, const std::vector<std::string>& ids) { std::set<std::string> ids_lookup(ids.begin(), ids.end()); - suggestions->erase( - std::remove_if( - suggestions->begin(), suggestions->end(), - [&ids_lookup](const std::unique_ptr<RemoteSuggestion>& suggestion) { - return base::ContainsValue(ids_lookup, suggestion->id()); - }), - suggestions->end()); + base::EraseIf( + *suggestions, + [&ids_lookup](const std::unique_ptr<RemoteSuggestion>& suggestion) { + return base::ContainsValue(ids_lookup, suggestion->id()); + }); } void EraseMatchingSuggestions( @@ -91,23 +89,18 @@ const std::vector<std::string>& suggestion_ids = suggestion->GetAllIDs(); compare_against_ids.insert(suggestion_ids.begin(), suggestion_ids.end()); } - suggestions->erase( - std::remove_if(suggestions->begin(), suggestions->end(), - [&compare_against_ids]( - const std::unique_ptr<RemoteSuggestion>& suggestion) { - return HasIntersection(suggestion->GetAllIDs(), - compare_against_ids); - }), - suggestions->end()); + base::EraseIf( + *suggestions, [&compare_against_ids]( + const std::unique_ptr<RemoteSuggestion>& suggestion) { + return HasIntersection(suggestion->GetAllIDs(), compare_against_ids); + }); } void RemoveNullPointers(RemoteSuggestion::PtrVector* suggestions) { - suggestions->erase( - std::remove_if(suggestions->begin(), suggestions->end(), - [](const std::unique_ptr<RemoteSuggestion>& suggestion) { - return !suggestion; - }), - suggestions->end()); + base::EraseIf(*suggestions, + [](const std::unique_ptr<RemoteSuggestion>& suggestion) { + return !suggestion; + }); } void RemoveIncompleteSuggestions(RemoteSuggestion::PtrVector* suggestions) { @@ -118,12 +111,10 @@ int num_suggestions = suggestions->size(); // Remove suggestions that do not have all the info we need to display it to // the user. - suggestions->erase( - std::remove_if(suggestions->begin(), suggestions->end(), - [](const std::unique_ptr<RemoteSuggestion>& suggestion) { - return !suggestion->is_complete(); - }), - suggestions->end()); + base::EraseIf(*suggestions, + [](const std::unique_ptr<RemoteSuggestion>& suggestion) { + return !suggestion->is_complete(); + }); int num_suggestions_removed = num_suggestions - suggestions->size(); UMA_HISTOGRAM_BOOLEAN("NewTabPage.Snippets.IncompleteSnippetsAfterFetch", num_suggestions_removed > 0); @@ -244,9 +235,8 @@ const ContentSuggestion::ID& suggestion_id, const GURL& url, const ImageFetchedCallback& callback) { - if (url.is_empty() || - !thumbnail_requests_throttler_.DemandQuotaForRequest( - /*interactive_request=*/true)) { + if (url.is_empty() || !thumbnail_requests_throttler_.DemandQuotaForRequest( + /*interactive_request=*/true)) { // Return an empty image. Directly, this is never synchronous with the // original FetchSuggestionImage() call - an asynchronous database query has // happened in the meantime. @@ -278,9 +268,7 @@ category_ranker_(category_ranker), suggestions_fetcher_(std::move(suggestions_fetcher)), database_(std::move(database)), - image_fetcher_(std::move(image_fetcher), - pref_service, - database_.get()), + image_fetcher_(std::move(image_fetcher), pref_service, database_.get()), status_service_(std::move(status_service)), fetch_when_ready_(false), fetch_when_ready_interactive_(false),
diff --git a/components/password_manager/core/browser/password_generation_manager.cc b/components/password_manager/core/browser/password_generation_manager.cc index 2e6f35f..a30adf8 100644 --- a/components/password_manager/core/browser/password_generation_manager.cc +++ b/components/password_manager/core/browser/password_generation_manager.cc
@@ -9,9 +9,11 @@ #include "components/autofill/core/browser/field_types.h" #include "components/autofill/core/browser/form_structure.h" #include "components/autofill/core/common/password_form_generation_data.h" +#include "components/password_manager/core/browser/browser_save_password_progress_logger.h" #include "components/password_manager/core/browser/password_manager.h" #include "components/password_manager/core/browser/password_manager_client.h" #include "components/password_manager/core/browser/password_manager_driver.h" +#include "components/password_manager/core/browser/password_manager_util.h" using autofill::AutofillField; using autofill::FieldSignature; @@ -20,6 +22,10 @@ namespace password_manager { +namespace { +using Logger = autofill::SavePasswordProgressLogger; +} + PasswordGenerationManager::PasswordGenerationManager( PasswordManagerClient* client, PasswordManagerDriver* driver) @@ -36,17 +42,15 @@ std::vector<autofill::PasswordFormGenerationData> forms_eligible_for_generation; - for (auto form_it = forms.begin(); form_it != forms.end(); ++form_it) { - FormStructure* form = *form_it; - AutofillField* generation_field = nullptr; - AutofillField* confirmation_field = nullptr; - for (auto field_it = form->begin(); field_it != form->end(); ++field_it) { - AutofillField* field = field_it->get(); + for (const FormStructure* form : forms) { + const AutofillField* generation_field = nullptr; + const AutofillField* confirmation_field = nullptr; + for (const std::unique_ptr<AutofillField>& field : *form) { if (field->server_type() == autofill::ACCOUNT_CREATION_PASSWORD || field->server_type() == autofill::NEW_PASSWORD) { - generation_field = field; + generation_field = field.get(); } else if (field->server_type() == autofill::CONFIRMATION_PASSWORD) { - confirmation_field = field; + confirmation_field = field.get(); } } if (generation_field) { @@ -67,16 +71,29 @@ // (1) Password sync is enabled, and // (2) Password saving is enabled. bool PasswordGenerationManager::IsGenerationEnabled() const { + std::unique_ptr<Logger> logger; + if (password_manager_util::IsLoggingActive(client_)) { + logger.reset( + new BrowserSavePasswordProgressLogger(client_->GetLogManager())); + } + if (!client_->IsSavingAndFillingEnabledForCurrentPage()) { - VLOG(2) << "Generation disabled because password saving is disabled"; + if (logger) + logger->LogMessage(Logger::STRING_GENERATION_DISABLED_SAVING_DISABLED); return false; } // Don't consider sync enabled if the user has a custom passphrase. See // http://crbug.com/358998 for more details. if (client_->GetPasswordSyncState() != SYNCING_NORMAL_ENCRYPTION) { - VLOG(2) << "Generation disabled because passwords are not being synced or" - << " custom passphrase is used."; + if (logger) { + if (client_->GetPasswordSyncState() == NOT_SYNCING_PASSWORDS) + logger->LogMessage(Logger::STRING_GENERATION_DISABLED_NO_SYNC); + else if (client_->GetPasswordSyncState() == + SYNCING_WITH_CUSTOM_PASSPHRASE) + logger->LogMessage( + Logger::STRING_GENERATION_DISABLED_CUSTOM_PASSPHRASE); + } return false; }
diff --git a/components/physical_web/webui/physical_web_ui_constants.cc b/components/physical_web/webui/physical_web_ui_constants.cc index 82d1af39..ba84fcc 100644 --- a/components/physical_web/webui/physical_web_ui_constants.cc +++ b/components/physical_web/webui/physical_web_ui_constants.cc
@@ -16,6 +16,7 @@ // Strings. const char kTitle[] = "title"; +const char kEmptyMessage[] = "emptyMessage"; const char kPageInfoDescription[] = "pageInfoDescription"; const char kPageInfoIcon[] = "pageInfoIcon"; const char kPageInfoTitle[] = "pageInfoTitle";
diff --git a/components/physical_web/webui/physical_web_ui_constants.h b/components/physical_web/webui/physical_web_ui_constants.h index 2eb8523..320bf4c2 100644 --- a/components/physical_web/webui/physical_web_ui_constants.h +++ b/components/physical_web/webui/physical_web_ui_constants.h
@@ -20,6 +20,7 @@ // Strings. // Must match the constants used in the resource files. extern const char kTitle[]; +extern const char kEmptyMessage[]; extern const char kPageInfoDescription[]; extern const char kPageInfoIcon[]; extern const char kPageInfoTitle[];
diff --git a/components/physical_web/webui/resources/physical_web.html b/components/physical_web/webui/resources/physical_web.html index a5a0ba6..e051510 100644 --- a/components/physical_web/webui/resources/physical_web.html +++ b/components/physical_web/webui/resources/physical_web.html
@@ -20,7 +20,7 @@ <script src="chrome://physical-web/strings.js"></script> </head> <body> -<div id="body-container" style="visibility:visible"> +<div id="body-container" hidden> <h1 i18n-content="title"></h1> @@ -38,6 +38,9 @@ </div> +<div id="empty-list-container" i18n-content="emptyMessage" hidden> +</div> + <script src="chrome://resources/js/i18n_template.js"></script> <script src="chrome://resources/js/jstemplate_compiled.js"></script> </body>
diff --git a/components/physical_web/webui/resources/physical_web.js b/components/physical_web/webui/resources/physical_web.js index 418dc1d..70d856f 100644 --- a/components/physical_web/webui/resources/physical_web.js +++ b/components/physical_web/webui/resources/physical_web.js
@@ -24,8 +24,12 @@ function returnNearbyURLs(nearbyUrlsData) { var bodyContainer = $('body-container'); renderTemplate(nearbyUrlsData); + bodyContainer.hidden = false; - bodyContainer.style.visibility = 'visible'; + if (nearbyUrlsData['metadata'].length == 0) { + var emptyMessage = $('empty-list-container'); + emptyMessage.hidden = false; + } } document.addEventListener('DOMContentLoaded', requestNearbyURLs);
diff --git a/components/safe_browsing_db/safe_browsing_prefs.cc b/components/safe_browsing_db/safe_browsing_prefs.cc index 66c1dbb6..3895131c 100644 --- a/components/safe_browsing_db/safe_browsing_prefs.cc +++ b/components/safe_browsing_db/safe_browsing_prefs.cc
@@ -57,6 +57,25 @@ MAX_SBER_PREF }; +// A histogram for tracking a nullable boolean, which can be false, true or +// null. These values are written to logs. New enum values can be added, but +// existing enums must never be renumbered or deleted and reused. +enum NullableBoolean { + NULLABLE_BOOLEAN_FALSE = 0, + NULLABLE_BOOLEAN_TRUE = 1, + NULLABLE_BOOLEAN_NULL = 2, + MAX_NULLABLE_BOOLEAN +}; + +NullableBoolean GetPrefValueOrNull(const PrefService& prefs, + const std::string& pref_name) { + if (!prefs.HasPrefPath(pref_name)) { + return NULLABLE_BOOLEAN_NULL; + } + return prefs.GetBoolean(pref_name) ? NULLABLE_BOOLEAN_TRUE + : NULLABLE_BOOLEAN_FALSE; +} + // Update the correct UMA metric based on which pref was changed and which UI // the change was made on. void RecordExtendedReportingPrefChanged( @@ -125,6 +144,10 @@ "safebrowsing.scout_reporting_enabled"; const char kSafeBrowsingScoutGroupSelected[] = "safebrowsing.scout_group_selected"; +const char kSafeBrowsingSawInterstitialExtendedReporting[] = + "safebrowsing.saw_interstitial_sber1"; +const char kSafeBrowsingSawInterstitialScoutReporting[] = + "safebrowsing.saw_interstitial_sber2"; } // namespace prefs namespace safe_browsing { @@ -224,12 +247,14 @@ // group (above) that was reverted. We want to restore the user to a // reasonable state based on the ScoutGroup and ScoutReporting preferences. UMA_HISTOGRAM_ENUMERATION(kScoutTransitionMetricName, CONTROL, MAX_REASONS); + bool transitioned = false; if (prefs->GetBoolean(prefs::kSafeBrowsingScoutReportingEnabled)) { // User opted-in to Scout which is broader than legacy Extended Reporting. // Opt them in to Extended Reporting. prefs->SetBoolean(prefs::kSafeBrowsingExtendedReportingEnabled, true); UMA_HISTOGRAM_ENUMERATION(kScoutTransitionMetricName, ROLLBACK_SBER2_IMPLIES_SBER1, MAX_REASONS); + transitioned = true; } else if (prefs->GetBoolean(prefs::kSafeBrowsingScoutGroupSelected)) { // User was in the Scout Group (ie: seeing the Scout opt-in text) but did // NOT opt-in to Scout. Assume this was a conscious choice and remove @@ -251,12 +276,20 @@ UMA_HISTOGRAM_ENUMERATION(kScoutTransitionMetricName, ROLLBACK_NO_SBER2_CLEAR_SBER1, MAX_REASONS); } + transitioned = true; } // Also clear both the Scout settings to start over from a clean state and // avoid the above logic from triggering on next restart. prefs->ClearPref(prefs::kSafeBrowsingScoutGroupSelected); prefs->ClearPref(prefs::kSafeBrowsingScoutReportingEnabled); + + // Also forget that the user has seen any interstitials if they're + // reverting back to a clean state. + if (transitioned) { + prefs->ClearPref(prefs::kSafeBrowsingSawInterstitialExtendedReporting); + prefs->ClearPref(prefs::kSafeBrowsingSawInterstitialScoutReporting); + } } } @@ -276,26 +309,38 @@ UMA_HISTOGRAM_BOOLEAN("SafeBrowsing.Pref.Extended", IsExtendedReportingEnabled(prefs)); + // Track whether this user has ever seen a security interstitial. + UMA_HISTOGRAM_BOOLEAN( + "SafeBrowsing.Pref.SawInterstitial.SBER1Pref", + prefs.GetBoolean(prefs::kSafeBrowsingSawInterstitialExtendedReporting)); + UMA_HISTOGRAM_BOOLEAN( + "SafeBrowsing.Pref.SawInterstitial.SBER2Pref", + prefs.GetBoolean(prefs::kSafeBrowsingSawInterstitialScoutReporting)); + // These metrics track the Scout transition. if (prefs.GetBoolean(prefs::kSafeBrowsingScoutGroupSelected)) { // Users in the Scout group: currently seeing the Scout opt-in. - UMA_HISTOGRAM_BOOLEAN( + UMA_HISTOGRAM_ENUMERATION( "SafeBrowsing.Pref.Scout.ScoutGroup.SBER1Pref", - prefs.GetBoolean(prefs::kSafeBrowsingExtendedReportingEnabled)); - UMA_HISTOGRAM_BOOLEAN( + GetPrefValueOrNull(prefs, prefs::kSafeBrowsingExtendedReportingEnabled), + MAX_NULLABLE_BOOLEAN); + UMA_HISTOGRAM_ENUMERATION( "SafeBrowsing.Pref.Scout.ScoutGroup.SBER2Pref", - prefs.GetBoolean(prefs::kSafeBrowsingScoutReportingEnabled)); + GetPrefValueOrNull(prefs, prefs::kSafeBrowsingScoutReportingEnabled), + MAX_NULLABLE_BOOLEAN); } else { // Users not in the Scout group: currently seeing the SBER opt-in. - UMA_HISTOGRAM_BOOLEAN( + UMA_HISTOGRAM_ENUMERATION( "SafeBrowsing.Pref.Scout.NoScoutGroup.SBER1Pref", - prefs.GetBoolean(prefs::kSafeBrowsingExtendedReportingEnabled)); + GetPrefValueOrNull(prefs, prefs::kSafeBrowsingExtendedReportingEnabled), + MAX_NULLABLE_BOOLEAN); // The following metric is a corner case. User was previously in the // Scout group and was able to opt-in to the Scout pref, but was since // removed from the Scout group (eg: by rolling back a Scout experiment). - UMA_HISTOGRAM_BOOLEAN( + UMA_HISTOGRAM_ENUMERATION( "SafeBrowsing.Pref.Scout.NoScoutGroup.SBER2Pref", - prefs.GetBoolean(prefs::kSafeBrowsingScoutReportingEnabled)); + GetPrefValueOrNull(prefs, prefs::kSafeBrowsingScoutReportingEnabled), + MAX_NULLABLE_BOOLEAN); } } @@ -384,6 +429,12 @@ CAN_SHOW_SCOUT_OPT_IN_SAW_FIRST_INTERSTITIAL, MAX_REASONS); } + + // Remember that this user saw an interstitial with the current opt-in text. + prefs->SetBoolean(IsScout(*prefs) + ? prefs::kSafeBrowsingSawInterstitialScoutReporting + : prefs::kSafeBrowsingSawInterstitialExtendedReporting, + true); } } // namespace safe_browsing
diff --git a/components/safe_browsing_db/safe_browsing_prefs.h b/components/safe_browsing_db/safe_browsing_prefs.h index da25461..54666f3 100644 --- a/components/safe_browsing_db/safe_browsing_prefs.h +++ b/components/safe_browsing_db/safe_browsing_prefs.h
@@ -23,6 +23,14 @@ // affects which of SafeBrowsingExtendedReporting or SafeBrowsingScoutReporting // is used. extern const char kSafeBrowsingScoutGroupSelected[]; + +// Boolean indicating whether the user has ever seen a security interstitial +// containing the legacy Extended Reporting opt-in. +extern const char kSafeBrowsingSawInterstitialExtendedReporting[]; + +// Boolean indicating whether the user has ever seen a security interstitial +// containing the new Scout opt-in. +extern const char kSafeBrowsingSawInterstitialScoutReporting[]; } namespace safe_browsing {
diff --git a/components/safe_browsing_db/safe_browsing_prefs_unittest.cc b/components/safe_browsing_db/safe_browsing_prefs_unittest.cc index af38c78..303f878 100644 --- a/components/safe_browsing_db/safe_browsing_prefs_unittest.cc +++ b/components/safe_browsing_db/safe_browsing_prefs_unittest.cc
@@ -24,6 +24,10 @@ prefs::kSafeBrowsingScoutReportingEnabled, false); prefs_.registry()->RegisterBooleanPref( prefs::kSafeBrowsingScoutGroupSelected, false); + prefs_.registry()->RegisterBooleanPref( + prefs::kSafeBrowsingSawInterstitialExtendedReporting, false); + prefs_.registry()->RegisterBooleanPref( + prefs::kSafeBrowsingSawInterstitialScoutReporting, false); ResetExperiments(/*can_show_scout=*/false, /*only_show_scout=*/false); }
diff --git a/components/signin/core/browser/android/java/src/org/chromium/components/signin/AccountManagerDelegate.java b/components/signin/core/browser/android/java/src/org/chromium/components/signin/AccountManagerDelegate.java index 436e0d1..249c4e9 100644 --- a/components/signin/core/browser/android/java/src/org/chromium/components/signin/AccountManagerDelegate.java +++ b/components/signin/core/browser/android/java/src/org/chromium/components/signin/AccountManagerDelegate.java
@@ -8,6 +8,7 @@ import android.accounts.AuthenticatorDescription; import android.app.Activity; import android.support.annotation.AnyThread; +import android.support.annotation.Nullable; import android.support.annotation.WorkerThread; import org.chromium.base.Callback; @@ -80,5 +81,6 @@ * @param callback The callback to indicate whether update is succeed or not. */ @AnyThread - void updateCredentials(Account account, Activity activity, Callback<Boolean> callback); + void updateCredentials( + Account account, Activity activity, @Nullable Callback<Boolean> callback); }
diff --git a/components/signin/core/browser/android/java/src/org/chromium/components/signin/AccountManagerHelper.java b/components/signin/core/browser/android/java/src/org/chromium/components/signin/AccountManagerHelper.java index 0d71fa4..93745b6 100644 --- a/components/signin/core/browser/android/java/src/org/chromium/components/signin/AccountManagerHelper.java +++ b/components/signin/core/browser/android/java/src/org/chromium/components/signin/AccountManagerHelper.java
@@ -9,6 +9,7 @@ import android.app.Activity; import android.content.Context; import android.os.AsyncTask; +import android.support.annotation.Nullable; import org.chromium.base.Callback; import org.chromium.base.Log; @@ -354,7 +355,8 @@ * Asks the user to enter a new password for an account, updating the saved credentials for the * account. */ - public void updateCredentials(Account account, Activity activity, Callback<Boolean> callback) { + public void updateCredentials( + Account account, Activity activity, @Nullable Callback<Boolean> callback) { mAccountManager.updateCredentials(account, activity, callback); }
diff --git a/components/signin/core/browser/android/java/src/org/chromium/components/signin/SystemAccountManagerDelegate.java b/components/signin/core/browser/android/java/src/org/chromium/components/signin/SystemAccountManagerDelegate.java index f26590e8..ebbc3dda 100644 --- a/components/signin/core/browser/android/java/src/org/chromium/components/signin/SystemAccountManagerDelegate.java +++ b/components/signin/core/browser/android/java/src/org/chromium/components/signin/SystemAccountManagerDelegate.java
@@ -171,28 +171,26 @@ return; } - mAccountManager.updateCredentials( - account, "android", null, activity, new AccountManagerCallback<Bundle>() { - @Override - public void run(AccountManagerFuture<Bundle> future) { - assert future.isDone(); - Bundle bundle = null; - try { - bundle = future.getResult(); - } catch (AuthenticatorException | IOException e) { - Log.e(TAG, "Error while update credentials: ", e); - } catch (OperationCanceledException e) { - Log.w(TAG, "Updating credentials was cancelled."); - } - if (bundle != null - && bundle.getString(AccountManager.KEY_ACCOUNT_NAME) != null - && bundle.getString(AccountManager.KEY_ACCOUNT_TYPE) != null) { - callback.onResult(true); - } else { - callback.onResult(false); - } - } - }, null /* handler */); + AccountManagerCallback<Bundle> realCallback = new AccountManagerCallback<Bundle>() { + @Override + public void run(AccountManagerFuture<Bundle> future) { + Bundle bundle = null; + try { + bundle = future.getResult(); + } catch (AuthenticatorException | IOException e) { + Log.e(TAG, "Error while update credentials: ", e); + } catch (OperationCanceledException e) { + Log.w(TAG, "Updating credentials was cancelled."); + } + boolean success = bundle != null + && bundle.getString(AccountManager.KEY_ACCOUNT_NAME) != null + && bundle.getString(AccountManager.KEY_ACCOUNT_TYPE) != null; + if (callback != null) { + callback.onResult(success); + } + } + }; + mAccountManager.updateCredentials(account, "android", null, activity, realCallback, null); } protected boolean hasGetAccountsPermission() {
diff --git a/components/signin/core/browser/android/javatests/src/org/chromium/components/signin/test/util/MockAccountManager.java b/components/signin/core/browser/android/javatests/src/org/chromium/components/signin/test/util/MockAccountManager.java index d7a67c7..5d26d5e 100644 --- a/components/signin/core/browser/android/javatests/src/org/chromium/components/signin/test/util/MockAccountManager.java +++ b/components/signin/core/browser/android/javatests/src/org/chromium/components/signin/test/util/MockAccountManager.java
@@ -184,6 +184,10 @@ public void updateCredentials( Account account, Activity activity, final Callback<Boolean> callback) { ThreadUtils.assertOnUiThread(); + if (callback == null) { + return; + } + ThreadUtils.postOnUiThread(new Runnable() { @Override public void run() {
diff --git a/components/signin/core/browser/gaia_cookie_manager_service.cc b/components/signin/core/browser/gaia_cookie_manager_service.cc index 415f03d3..3076b95 100644 --- a/components/signin/core/browser/gaia_cookie_manager_service.cc +++ b/components/signin/core/browser/gaia_cookie_manager_service.cc
@@ -58,6 +58,7 @@ false, }; +// The maximum number of retries for a fetcher used in this class. const int kMaxFetcherRetries = 8; // Name of the GAIA cookie that is being observed to detect when available @@ -131,6 +132,7 @@ } void GaiaCookieManagerService::ExternalCcResultFetcher::Start() { + DCHECK(!helper_->external_cc_result_fetched_); m_external_cc_result_start_time_ = base::Time::Now(); CleanupTransientState(); @@ -151,7 +153,8 @@ } bool GaiaCookieManagerService::ExternalCcResultFetcher::IsRunning() { - return helper_->gaia_auth_fetcher_ || fetchers_.size() > 0u; + return helper_->gaia_auth_fetcher_ || fetchers_.size() > 0u || + timer_.IsRunning(); } void GaiaCookieManagerService::ExternalCcResultFetcher::TimeoutForTests() { @@ -160,8 +163,6 @@ void GaiaCookieManagerService::ExternalCcResultFetcher:: OnGetCheckConnectionInfoSuccess(const std::string& data) { - helper_->fetcher_backoff_.InformOfRequest(true); - gaia_auth_fetcher_timer_.Stop(); std::unique_ptr<base::Value> value = base::JSONReader::Read(data); const base::ListValue* list; if (!value || !value->GetAsList(&list)) { @@ -196,15 +197,17 @@ void GaiaCookieManagerService::ExternalCcResultFetcher:: OnGetCheckConnectionInfoError(const GoogleServiceAuthError& error) { - if (++helper_->fetcher_retries_ < kMaxFetcherRetries && - error.IsTransientError()) { - helper_->fetcher_backoff_.InformOfRequest(false); - gaia_auth_fetcher_timer_.Start( - FROM_HERE, helper_->fetcher_backoff_.GetTimeUntilRelease(), - this, &GaiaCookieManagerService::ExternalCcResultFetcher::Start); - return; - } + VLOG(1) << "GaiaCookieManagerService::ExternalCcResultFetcher::" + << "OnGetCheckConnectionInfoError " << error.ToString(); + // Chrome does not have any retry logic for fetching ExternalCcResult. The + // ExternalCcResult is only used to inform Gaia that Chrome has already + // checked the connection to other sites. + // + // In case fetching the ExternalCcResult fails: + // * The result of merging accounts to Gaia cookies will not be affected. + // * Gaia will need make its own call about whether to check them itself, + // of make some other assumptions. CleanupTransientState(); GetCheckConnectionInfoCompleted(false); } @@ -257,6 +260,7 @@ } void GaiaCookieManagerService::ExternalCcResultFetcher::Timeout() { + VLOG(1) << " GaiaCookieManagerService::ExternalCcResultFetcher::Timeout"; CleanupTransientState(); GetCheckConnectionInfoCompleted(false); }
diff --git a/components/signin/core/browser/gaia_cookie_manager_service.h b/components/signin/core/browser/gaia_cookie_manager_service.h index ae8a8947..30d0562f 100644 --- a/components/signin/core/browser/gaia_cookie_manager_service.h +++ b/components/signin/core/browser/gaia_cookie_manager_service.h
@@ -163,8 +163,6 @@ ResultMap results_; base::Time m_external_cc_result_start_time_; - base::OneShotTimer gaia_auth_fetcher_timer_; - DISALLOW_COPY_AND_ASSIGN(ExternalCcResultFetcher); };
diff --git a/components/subresource_filter/content/browser/BUILD.gn b/components/subresource_filter/content/browser/BUILD.gn index c3c4429..238f45e 100644 --- a/components/subresource_filter/content/browser/BUILD.gn +++ b/components/subresource_filter/content/browser/BUILD.gn
@@ -8,8 +8,8 @@ "activation_state_computing_navigation_throttle.h", "async_document_subresource_filter.cc", "async_document_subresource_filter.h", - "content_ruleset_service_delegate.cc", - "content_ruleset_service_delegate.h", + "content_ruleset_service.cc", + "content_ruleset_service.h", "content_subresource_filter_driver_factory.cc", "content_subresource_filter_driver_factory.h", "subframe_navigation_filtering_throttle.cc", @@ -39,7 +39,7 @@ testonly = true sources = [ "async_document_subresource_filter_unittest.cc", - "content_ruleset_service_delegate_unittest.cc", + "content_ruleset_service_unittest.cc", "content_subresource_filter_driver_factory_unittest.cc", "subframe_navigation_filtering_throttle_unittest.cc", "verified_ruleset_dealer_unittest.cc",
diff --git a/components/subresource_filter/content/browser/content_ruleset_service_delegate.cc b/components/subresource_filter/content/browser/content_ruleset_service.cc similarity index 74% rename from components/subresource_filter/content/browser/content_ruleset_service_delegate.cc rename to components/subresource_filter/content/browser/content_ruleset_service.cc index 079798aa..adcc930d 100644 --- a/components/subresource_filter/content/browser/content_ruleset_service_delegate.cc +++ b/components/subresource_filter/content/browser/content_ruleset_service.cc
@@ -2,13 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "components/subresource_filter/content/browser/content_ruleset_service_delegate.h" +#include "components/subresource_filter/content/browser/content_ruleset_service.h" #include <utility> #include "base/logging.h" #include "base/macros.h" #include "components/subresource_filter/content/common/subresource_filter_messages.h" +#include "components/subresource_filter/core/browser/ruleset_service.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/notification_service.h" #include "content/public/browser/notification_source.h" @@ -42,7 +43,7 @@ } // namespace -ContentRulesetServiceDelegate::ContentRulesetServiceDelegate() { +ContentRulesetService::ContentRulesetService() { // Must rely on notifications as RenderProcessHostObserver::RenderProcessReady // would only be called after queued IPC messages (potentially triggering a // navigation) had already been sent to the new renderer. @@ -51,24 +52,24 @@ content::NotificationService::AllBrowserContextsAndSources()); } -ContentRulesetServiceDelegate::~ContentRulesetServiceDelegate() { +ContentRulesetService::~ContentRulesetService() { CloseFileOnFileThread(&ruleset_data_); } -void ContentRulesetServiceDelegate::SetRulesetPublishedCallbackForTesting( +void ContentRulesetService::SetRulesetPublishedCallbackForTesting( base::Closure callback) { ruleset_published_callback_ = callback; } -void ContentRulesetServiceDelegate::PostAfterStartupTask(base::Closure task) { +void ContentRulesetService::PostAfterStartupTask(base::Closure task) { content::BrowserThread::PostAfterStartupTask( - FROM_HERE, content::BrowserThread::GetTaskRunnerForThread( - content::BrowserThread::UI), + FROM_HERE, + content::BrowserThread::GetTaskRunnerForThread( + content::BrowserThread::UI), task); } -void ContentRulesetServiceDelegate::PublishNewRulesetVersion( - base::File ruleset_data) { +void ContentRulesetService::PublishNewRulesetVersion(base::File ruleset_data) { DCHECK(ruleset_data.IsValid()); CloseFileOnFileThread(&ruleset_data_); ruleset_data_ = std::move(ruleset_data); @@ -81,7 +82,19 @@ ruleset_published_callback_.Run(); } -void ContentRulesetServiceDelegate::Observe( +void ContentRulesetService::set_ruleset_service( + std::unique_ptr<RulesetService> ruleset_service) { + ruleset_service_ = std::move(ruleset_service); +} + +void ContentRulesetService::IndexAndStoreAndPublishRulesetIfNeeded( + const UnindexedRulesetInfo& unindexed_ruleset_info) { + DCHECK(ruleset_service_); + ruleset_service_->IndexAndStoreAndPublishRulesetIfNeeded( + unindexed_ruleset_info); +} + +void ContentRulesetService::Observe( int type, const content::NotificationSource& source, const content::NotificationDetails& details) {
diff --git a/components/subresource_filter/content/browser/content_ruleset_service_delegate.h b/components/subresource_filter/content/browser/content_ruleset_service.h similarity index 78% rename from components/subresource_filter/content/browser/content_ruleset_service_delegate.h rename to components/subresource_filter/content/browser/content_ruleset_service.h index ba5338c6..734e81d 100644 --- a/components/subresource_filter/content/browser/content_ruleset_service_delegate.h +++ b/components/subresource_filter/content/browser/content_ruleset_service.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef COMPONENTS_SUBRESOURCE_FILTER_CONTENT_BROWSER_CONTENT_RULESET_SERVICE_DELEGATE_H_ -#define COMPONENTS_SUBRESOURCE_FILTER_CONTENT_BROWSER_CONTENT_RULESET_SERVICE_DELEGATE_H_ +#ifndef COMPONENTS_SUBRESOURCE_FILTER_CONTENT_BROWSER_CONTENT_RULESET_SERVICE_H_ +#define COMPONENTS_SUBRESOURCE_FILTER_CONTENT_BROWSER_CONTENT_RULESET_SERVICE_H_ #include "base/callback.h" #include "base/files/file.h" @@ -14,7 +14,11 @@ namespace subresource_filter { -// The content-layer specific implementation of RulesetServiceDelegate. +class RulesetService; +struct UnindexedRulesetInfo; + +// The content-layer specific implementation of RulesetServiceDelegate. Owns the +// underlying RulesetService. // // Its main responsibility is receiving new versions of subresource filtering // rules from the RulesetService, and distributing them to renderer processes, @@ -42,11 +46,11 @@ // // Note: UnverifiedRulesetDealer is shortened to *RulesetDealer above. There is // also a VerifiedRulesetDealer which is used similarly on the browser side. -class ContentRulesetServiceDelegate : public RulesetServiceDelegate, - content::NotificationObserver { +class ContentRulesetService : public RulesetServiceDelegate, + content::NotificationObserver { public: - ContentRulesetServiceDelegate(); - ~ContentRulesetServiceDelegate() override; + ContentRulesetService(); + ~ContentRulesetService() override; void SetRulesetPublishedCallbackForTesting(base::Closure callback); @@ -54,6 +58,12 @@ void PostAfterStartupTask(base::Closure task) override; void PublishNewRulesetVersion(base::File ruleset_data) override; + void set_ruleset_service(std::unique_ptr<RulesetService> ruleset_service); + + // Forwards calls to the underlying ruleset_service_. + void IndexAndStoreAndPublishRulesetIfNeeded( + const UnindexedRulesetInfo& unindex_ruleset_info); + private: // content::NotificationObserver: void Observe(int type, @@ -64,9 +74,11 @@ base::File ruleset_data_; base::Closure ruleset_published_callback_; - DISALLOW_COPY_AND_ASSIGN(ContentRulesetServiceDelegate); + std::unique_ptr<RulesetService> ruleset_service_; + + DISALLOW_COPY_AND_ASSIGN(ContentRulesetService); }; } // namespace subresource_filter -#endif // COMPONENTS_SUBRESOURCE_FILTER_CONTENT_BROWSER_CONTENT_RULESET_SERVICE_DELEGATE_H_ +#endif // COMPONENTS_SUBRESOURCE_FILTER_CONTENT_BROWSER_CONTENT_RULESET_SERVICE_H_
diff --git a/components/subresource_filter/content/browser/content_ruleset_service_delegate_unittest.cc b/components/subresource_filter/content/browser/content_ruleset_service_unittest.cc similarity index 89% rename from components/subresource_filter/content/browser/content_ruleset_service_delegate_unittest.cc rename to components/subresource_filter/content/browser/content_ruleset_service_unittest.cc index 643835a..69a64ce3 100644 --- a/components/subresource_filter/content/browser/content_ruleset_service_delegate_unittest.cc +++ b/components/subresource_filter/content/browser/content_ruleset_service_unittest.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "components/subresource_filter/content/browser/content_ruleset_service_delegate.h" +#include "components/subresource_filter/content/browser/content_ruleset_service.h" #include <stddef.h> @@ -94,10 +94,9 @@ } // namespace -class SubresourceFilterContentRulesetServiceDelegateTest - : public ::testing::Test { +class SubresourceFilterContentRulesetServiceTest : public ::testing::Test { public: - SubresourceFilterContentRulesetServiceDelegateTest() + SubresourceFilterContentRulesetServiceTest() : old_browser_client_(nullptr), existing_renderer_(&browser_context_) {} protected: @@ -134,20 +133,19 @@ content::TestBrowserContext browser_context_; NotifyingMockRenderProcessHost existing_renderer_; - DISALLOW_COPY_AND_ASSIGN(SubresourceFilterContentRulesetServiceDelegateTest); + DISALLOW_COPY_AND_ASSIGN(SubresourceFilterContentRulesetServiceTest); }; -TEST_F(SubresourceFilterContentRulesetServiceDelegateTest, - NoRuleset_NoIPCMessages) { +TEST_F(SubresourceFilterContentRulesetServiceTest, NoRuleset_NoIPCMessages) { NotifyingMockRenderProcessHost existing_renderer(browser_context()); - ContentRulesetServiceDelegate delegate; + ContentRulesetService service; NotifyingMockRenderProcessHost new_renderer(browser_context()); base::RunLoop().RunUntilIdle(); EXPECT_EQ(0u, existing_renderer.sink().message_count()); EXPECT_EQ(0u, new_renderer.sink().message_count()); } -TEST_F(SubresourceFilterContentRulesetServiceDelegateTest, +TEST_F(SubresourceFilterContentRulesetServiceTest, PublishedRuleset_IsDistributedToExistingAndNewRenderers) { const char kTestFileContents[] = "foobar"; base::WriteFile(scoped_temp_file(), kTestFileContents, @@ -158,12 +156,12 @@ base::File::FLAG_OPEN | base::File::FLAG_READ); NotifyingMockRenderProcessHost existing_renderer(browser_context()); - ContentRulesetServiceDelegate delegate; + ContentRulesetService service; MockClosureTarget publish_callback_target; - delegate.SetRulesetPublishedCallbackForTesting(base::Bind( + service.SetRulesetPublishedCallbackForTesting(base::Bind( &MockClosureTarget::Call, base::Unretained(&publish_callback_target))); EXPECT_CALL(publish_callback_target, Call()).Times(1); - delegate.PublishNewRulesetVersion(std::move(file)); + service.PublishNewRulesetVersion(std::move(file)); base::RunLoop().RunUntilIdle(); ::testing::Mock::VerifyAndClearExpectations(&publish_callback_target); @@ -179,12 +177,11 @@ second_renderer.sink().GetMessageAt(0), kTestFileContents)); } -TEST_F(SubresourceFilterContentRulesetServiceDelegateTest, - PostAfterStartupTask) { - ContentRulesetServiceDelegate delegate; +TEST_F(SubresourceFilterContentRulesetServiceTest, PostAfterStartupTask) { + ContentRulesetService service; MockClosureTarget mock_closure_target; - delegate.PostAfterStartupTask(base::Bind( + service.PostAfterStartupTask(base::Bind( &MockClosureTarget::Call, base::Unretained(&mock_closure_target))); EXPECT_CALL(mock_closure_target, Call()).Times(1);
diff --git a/components/subresource_filter/content/renderer/unverified_ruleset_dealer.h b/components/subresource_filter/content/renderer/unverified_ruleset_dealer.h index e46240a..329e612 100644 --- a/components/subresource_filter/content/renderer/unverified_ruleset_dealer.h +++ b/components/subresource_filter/content/renderer/unverified_ruleset_dealer.h
@@ -24,7 +24,7 @@ // sure that the file is valid. // // See RulesetDealerBase for details on the lifetime of MemoryMappedRuleset, and -// the distribution pipeline diagram in content_ruleset_service_delegate.h. +// the distribution pipeline diagram in content_ruleset_service.h. class UnverifiedRulesetDealer : public RulesetDealer, public content::RenderThreadObserver { public:
diff --git a/components/subresource_filter/core/browser/ruleset_service.cc b/components/subresource_filter/core/browser/ruleset_service.cc index 179375b..4625672 100644 --- a/components/subresource_filter/core/browser/ruleset_service.cc +++ b/components/subresource_filter/core/browser/ruleset_service.cc
@@ -215,11 +215,11 @@ RulesetService::RulesetService( PrefService* local_state, scoped_refptr<base::SequencedTaskRunner> blocking_task_runner, - std::unique_ptr<RulesetServiceDelegate> delegate, + RulesetServiceDelegate* delegate, const base::FilePath& indexed_ruleset_base_dir) : local_state_(local_state), blocking_task_runner_(blocking_task_runner), - delegate_(std::move(delegate)), + delegate_(delegate), is_after_startup_(false), indexed_ruleset_base_dir_(indexed_ruleset_base_dir) { DCHECK(delegate_);
diff --git a/components/subresource_filter/core/browser/ruleset_service.h b/components/subresource_filter/core/browser/ruleset_service.h index d460f14f..ef84c0ca 100644 --- a/components/subresource_filter/core/browser/ruleset_service.h +++ b/components/subresource_filter/core/browser/ruleset_service.h
@@ -170,7 +170,7 @@ // See class comments for details of arguments. RulesetService(PrefService* local_state, scoped_refptr<base::SequencedTaskRunner> blocking_task_runner, - std::unique_ptr<RulesetServiceDelegate> delegate, + RulesetServiceDelegate* delegate, const base::FilePath& indexed_ruleset_base_dir); virtual ~RulesetService(); @@ -187,9 +187,6 @@ virtual void IndexAndStoreAndPublishRulesetIfNeeded( const UnindexedRulesetInfo& unindexed_ruleset_info); - // Exposed for browser tests. - RulesetServiceDelegate* delegate() { return delegate_.get(); } - private: friend class SubresourceFilteringRulesetServiceTest; FRIEND_TEST_ALL_PREFIXES(SubresourceFilteringRulesetServiceTest, @@ -252,7 +249,9 @@ PrefService* const local_state_; scoped_refptr<base::SequencedTaskRunner> blocking_task_runner_; - std::unique_ptr<RulesetServiceDelegate> delegate_; + + // Must outlive |this| object. + RulesetServiceDelegate* delegate_; UnindexedRulesetInfo queued_unindexed_ruleset_info_; bool is_after_startup_;
diff --git a/components/subresource_filter/core/browser/ruleset_service_unittest.cc b/components/subresource_filter/core/browser/ruleset_service_unittest.cc index 0e300937..dccef008 100644 --- a/components/subresource_filter/core/browser/ruleset_service_unittest.cc +++ b/components/subresource_filter/core/browser/ruleset_service_unittest.cc
@@ -145,8 +145,7 @@ public: SubresourceFilteringRulesetServiceTest() : task_runner_(new base::TestSimpleTaskRunner), - task_runner_handle_(task_runner_), - mock_delegate_(nullptr) {} + task_runner_handle_(task_runner_) {} protected: void SetUp() override { @@ -172,15 +171,14 @@ } void ResetRulesetService() { + mock_delegate_ = base::MakeUnique<MockRulesetServiceDelegate>(); service_ = base::MakeUnique<RulesetService>( - &pref_service_, task_runner_, - base::WrapUnique(mock_delegate_ = new MockRulesetServiceDelegate), - base_dir()); + &pref_service_, task_runner_, mock_delegate_.get(), base_dir()); } void ClearRulesetService() { - mock_delegate_ = nullptr; service_.reset(); + mock_delegate_.reset(); } // Creates a new file with the given license |contents| at a unique temporary @@ -269,7 +267,7 @@ PrefService* prefs() { return &pref_service_; } RulesetService* service() { return service_.get(); } - MockRulesetServiceDelegate* mock_delegate() { return mock_delegate_; } + MockRulesetServiceDelegate* mock_delegate() { return mock_delegate_.get(); } virtual base::FilePath effective_temp_dir() const { return scoped_temp_dir_.GetPath(); @@ -295,8 +293,8 @@ TestRulesetPair test_ruleset_2_; TestRulesetPair test_ruleset_3_; + std::unique_ptr<MockRulesetServiceDelegate> mock_delegate_; std::unique_ptr<RulesetService> service_; - MockRulesetServiceDelegate* mock_delegate_; // Weak, owned by |service_|. DISALLOW_COPY_AND_ASSIGN(SubresourceFilteringRulesetServiceTest); };
diff --git a/components/supervised_user_error_page/resources/supervised_user_block_interstitial.css b/components/supervised_user_error_page/resources/supervised_user_block_interstitial.css index 2f03ba0..a381ab8d 100644 --- a/components/supervised_user_error_page/resources/supervised_user_block_interstitial.css +++ b/components/supervised_user_error_page/resources/supervised_user_block_interstitial.css
@@ -1,32 +1,134 @@ /* Copyright 2014 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. */ + Use of this source code is governed by a BSD-style license that can be + found in the LICENSE file. */ + body { - background-color: rgb(247, 247, 247); - font-size: 10pt; - margin: 150px 60px 0 30px; + background-color: #f7f7f7; + color: #646464; } -#main-frame-blocked { - margin: auto; - max-width: 600px; - min-width: 200px; +a { + color: #585858; +} + +button { + border: 0; + border-radius: 2px; + box-sizing: border-box; + color: #fff; + cursor: pointer; + float: right; + font-size: .875em; + margin: 0; + padding: 10px 24px; + transition: box-shadow 200ms cubic-bezier(0.4, 0, 0.2, 1); + user-select: none; +} + +[dir='rtl'] button { + float: left; +} + +.primary-button { + background: rgb(66, 133, 244); +} + +.primary-button:active { + background: rgb(50, 102, 213); + outline: 0; +} + +button:hover { + box-shadow: 0 1px 3px rgba(0, 0, 0, .50); +} + +#details { + color: #696969; + margin: 45px 0 50px; +} + +#details p:not(:first-of-type) { + margin-top: 20px; +} + +#details-header { + font-weight: bold; +} + +#details-button-container { + box-shadow: inherit; +} + +.details-button { + background: inherit; + border: 0; + float: none; + margin: 0; + padding: 10px 0; + text-transform: uppercase; +} + +.details-button:hover { + box-shadow: inherit; + text-decoration: underline; } h1 { - font-size: 1.8em; + color: #333; + font-size: 1.6em; font-weight: normal; - margin: 5px 0 25px 0; + line-height: 1.25em; + margin-bottom: 16px; } -#block-page-message { - color: rgb(97,97,97); - font-size: 0.667em; - margin-top: 16px; +h2 { + font-size: 1.2em; + font-weight: normal; +} + +html { + -webkit-text-size-adjust: 100%; + font-size: 125%; +} + +.icon { + background-repeat: no-repeat; + background-size: 100%; + height: 72px; + margin: 0 0 40px; + width: 72px; +} + +.main-frame-blocked { + box-sizing: border-box; + font-size: 1em; + line-height: 1.6em; + margin: 100px auto 0; + max-width: 600px; + width: 100%; +} + +#main-message > p:not([hidden]) { + display: inline; +} + +.button-container { + margin-top: 51px; +} + +.button-container::after { + clear: both; + content: ''; + display: table; + width: 100%; +} + +.small-link { + color: #696969; + font-size: .875em; } .avatar-img { - -webkit-user-select: none; border: 3px solid rgb(251, 251, 251); border-radius: 50%; content: -webkit-image-set( @@ -37,61 +139,13 @@ margin-top: 5px; max-width: 45px; position: relative; + user-select: none; } #feedback { margin-top: 50px; } -#feedback-link { - color: rgb(66, 133, 244); -} - -#request-access-button { - background-color: rgb(66, 133, 244); - color: rgb(255, 255, 255); - cursor: pointer; - font-size: 12px; - font-weight: bold; - min-width: 88px; - padding: 10px 15px; - transition: box-shadow 200ms cubic-bezier(0.4, 0, 0.2, 1); - transition-delay: 200ms; -} - -#request-access-button:hover { - background-color: rgb(30, 136, 229); -} - -#request-access-button:active { - background-color: rgb(25,118,210); - box-shadow: 0 8px 17px 0 rgba(0, 0, 0, 0.2); - transition-delay: 0s; -} - -#details-button-container { - color: rgb(97,97,97); - cursor: pointer; - display: inline; - font-size: 12px; -} - -#button-container { - align-items: baseline; - display: flex; - justify-content: space-between; - margin-top: 60px; -} - -#details { - color: rgb(97,97,97); - font-size: 14px; -} - -#details-header { - font-weight: bold; -} - .custodian-information { align-items: center; display: flex; @@ -108,46 +162,356 @@ padding: 1px 0; } -@media (max-width: 600px) { - #button-container { - display: flex; - flex-flow: column; - justify-content: flex-start; - order: 2; + +@media (max-width: 700px) { + .main-frame-blocked { + padding: 0 10%; + } +} + +@media (max-height: 600px) { + #feedback { + margin-top: 35px; + } +} + +@media (max-width: 420px) { + button, + [dir='rtl'] button, + .small-link { + float: none; + font-size: .825em; + font-weight: 400; + margin: 0; text-transform: uppercase; - } - - #details-button-container { - font-weight: bold; - margin: auto; - order: 2; - padding: 0 15px; - text-align: center; - width: 100%; - } - - #request-access-button { - margin-bottom: 30px; - order: 1; - text-align: center; width: 100%; } #details { - margin: auto; - order: 1; + margin: 20px 0 20px 0; } - .hidden-on-mobile { - display: none; + #details p:not(:first-of-type) { + margin-top: 10px; } - #main-frame-blocked { + .details-button { + margin-top: 20px; + text-align: center; + width: 100%; + } + + .main-frame-blocked { + padding: 0 5%; + } + + .button-container { + margin-top: 30px; + } +} + +/** + * Mobile specific styling. + * Navigation buttons are anchored to the bottom of the screen. + * Details message replaces the top content in its own scrollable area. + */ + +@media (max-width: 420px) and (max-height: 736px) and (orientation: portrait) { + .details-button { + border: 0; + margin: 8px 0 0; + } + + .secondary-button { + -webkit-margin-end: 0; + margin-top: 16px; + } +} + +/* Fixed nav. */ +@media (min-width: 240px) and (max-width: 420px) and + (min-height: 401px) and (max-height: 736px) and (orientation:portrait), + (min-width: 421px) and (max-width: 736px) and (min-height: 240px) and + (max-height: 420px) and (orientation:landscape) { + body .button-container { + background: #f7f7f7; + bottom: 0; + box-shadow: 0 -22px 40px rgb(247, 247, 247); + left: 0; + margin: 0; + max-width: 736px; + padding-left: 24px; + padding-right: 24px; + position: fixed; + z-index: 2; + } + + .main-frame-blocked { + max-width: 736px; + } + + #details, + #information-container { + padding-bottom: 40px; + } +} + +@media (max-width: 420px) and (max-height: 736px) and (orientation: portrait), + (max-width: 736px) and (max-height: 420px) and (orientation: landscape) { + body { + margin: 0 auto; + } + + button, + [dir='rtl'] button, + button.small-link { + font-family: Roboto-Regular,Helvetica; + font-size: .933em; + font-weight: 600; + margin: 6px 0; + text-transform: uppercase; + transform: translatez(0); + } + + .button-container { + box-sizing: border-box; + padding-bottom: 8px; + width: 100%; + } + + #details { + box-sizing: border-box; + height: auto; + margin: 0; + opacity: 1; + padding-top: 40px; + transition: opacity 250ms cubic-bezier(0.4, 0, 0.2, 1); + } + + #details[hidden], + #information-container[hidden] { + display: block; + height: 0; + opacity: 0; + overflow: hidden; + transition: none; + } + + .details-button { + padding-bottom: 16px; + padding-top: 16px; + } + + h1 { + font-size: 1.5em; + margin-bottom: 8px; + } + + .icon { + margin-bottom: 12px; + } + + .main-frame-blocked { + box-sizing: border-box; + margin: 24px auto 12px; + padding: 0 24px; + position: relative; + } + + .main-frame-blocked p { + font-size: .95em; + line-height: 1.61em; + margin-top: 8px; + } + + #information-container { + margin: 0; + transition: opacity 100ms cubic-bezier(0.4, 0, 0.2, 1); + } + + .small-link { + border: 0; + } +} + +@media (min-height: 400px) and (orientation:portrait) { + .main-frame-blocked { + margin-bottom: 145px; + } +} + +@media (min-height: 299px) and (orientation:portrait) { + .button-container { + padding-bottom: 16px; + } +} + +@media (min-height: 405px) and (max-height: 736px) and + (max-width: 420px) and (orientation:portrait) { + .icon { + margin-bottom: 24px; + } + + .main-frame-blocked { + margin-top: 64px; + } +} + +@media (min-height: 480px) and (max-width: 420px) and + (max-height: 736px) and (orientation: portrait), + (min-height: 338px) and (max-height: 420px) and (max-width: 736px) and + (orientation: landscape) { + .icon { + margin-bottom: 24px; + } + + .button-container { + padding-bottom: 24px; + } +} + +@media (min-height: 500px) and (max-width: 414px) and (orientation: portrait) { + .main-frame-blocked { + margin-top: 96px; + } +} + +/* Phablet sizing */ +@media (min-width: 375px) and (min-height: 641px) and (max-height: 736px) and + (max-width: 414px) and (orientation: portrait) { + button, + [dir='rtl'] button, + .small-link { + font-size: 1em; + padding-bottom: 12px; + padding-top: 12px; + } + + body:not(.offline) .icon { + height: 80px; + width: 80px; + } + + .details-button { + margin-top: 28px; + } + + h1 { + font-size: 1.7em; + } + + .icon { + margin-bottom: 28px; + } + + .main-frame-blocked { + padding: 28px; + } + + .main-frame-blocked p { + font-size: 1.05em; + } + + .button-container { + padding: 28px; + } +} + +@media (min-width: 420px) and (max-width: 736px) and + (min-height: 240px) and (max-height: 298px) and + (orientation:landscape) { + body:not(.offline) .icon { + height: 50px; + width: 50px; + } + + .icon { + padding-top: 0; + } + + .main-frame-blocked { + margin-top: 16px; + } + + .button-container { + padding: 0 24px 8px; + } +} + +@media (min-width: 420px) and (max-width: 736px) and + (min-height: 240px) and (max-height: 420px) and + (orientation:landscape) { + .details-button { + margin: 0; + } + + .main-frame-blocked { + margin-bottom: 70px; + } + + .button-container { + margin-top: 0; + } +} + +/* Phablet landscape */ +@media (min-width: 680px) and (max-height: 414px) { + .main-frame-blocked { + margin: 24px auto; + } + + .button-container { + margin: 16px auto 0; + } +} + +@media (max-height: 240px) and (orientation: landscape), + (max-height: 480px) and (orientation: portrait), + (max-width: 419px) and (max-height: 323px) { + body:not(.offline) .icon { + height: 56px; + width: 56px; + } + + .icon { + margin-bottom: 16px; + } +} + +/* Small mobile screens. No fixed nav. */ +@media (max-height: 400px) and (orientation: portrait), + (max-height: 239px) and (orientation: landscape), + (max-width: 419px) and (max-height: 399px) { + .main-frame-blocked { display: flex; - flex-flow: column; + flex-direction: column; + margin-bottom: 0; } - #feedback { - margin-top: 35px; + #details { + flex: 1 1 auto; + order: 0; + } + + #information-container { + flex: 1 1 auto; + order: 0; + } + + .button-container { + flex: 0 1 auto; + margin-top: 8px; + order: 1; + padding-left: 0; + padding-right: 0; + position: relative; + width: 100%; + } +} + +@media (max-width: 239px) and (orientation: portrait) { + .button-container { + padding-left: 0; + padding-right: 0; } }
diff --git a/components/supervised_user_error_page/resources/supervised_user_block_interstitial.html b/components/supervised_user_error_page/resources/supervised_user_block_interstitial.html index 69142c2..2a7de4b 100644 --- a/components/supervised_user_error_page/resources/supervised_user_block_interstitial.html +++ b/components/supervised_user_error_page/resources/supervised_user_block_interstitial.html
@@ -1,27 +1,26 @@ <!doctype html> <html i18n-values="dir:textdirection;lang:language"> <head> -<meta name="viewport" content="width=device-width"> <meta charset="utf-8"> +<meta name="viewport" + content="initial-scale=1, minimum-scale=1, width=device-width"> <title i18n-content="blockPageTitle"></title> -<link rel="stylesheet" href="../../../ui/webui/resources/css/widgets.css"> <link rel="stylesheet" href="supervised_user_block_interstitial.css"> <script src="../../../ui/webui/resources/js/cr.js"></script> <script src="../../../ui/webui/resources/js/util.js"></script> <script src="supervised_user_block_interstitial.js"></script> </head> - <body> -<div id="main-frame-blocked"> +<div class="main-frame-blocked"> <div id="information-container"> - <h1> - <div id="block-page-header" i18n-content="blockPageHeader"></div> - <div id="block-page-message" i18n-content="blockPageMessage"></div> - <div id="request-failed-message" i18n-content="requestFailedMessage" - hidden></div> - <div id="request-sent-message" i18n-content="requestSentMessage" hidden> - </div> - </h1> + <div class="icon" id="icon"></div> + <div id="main-message"> + <h1 id="block-page-header" i18n-content="blockPageHeader"></h1> + <p id="block-page-message" i18n-content="blockPageMessage"></p> + <h1 id="request-failed-message" i18n-content="requestFailedMessage" + hidden></h1> + <h1 id="request-sent-message" i18n-content="requestSentMessage" hidden></h1> + </div> <div id="custodians-information" hidden> <div id="custodian-information" class="custodian-information"> <img id="custodian-avatar-img" class="avatar-img"> @@ -39,19 +38,14 @@ </div> </div> </div> - <div id="button-container"> + <div class="button-container"> + <button id="request-access-button" class="primary-button" i18n-content="requestAccessButton"> + </button> <div id="details-button-container"> - <a id="show-details-link" i18n-content="showDetailsLink" - hidden class="button"> - </a> - <a id="hide-details-link" i18n-content="hideDetailsLink" - hidden class="button"></a> - <a id="back-button" i18n-content="backButton" - hidden class="button"></a> + <button id="show-details-link" class="details-button small-link" i18n-content="showDetailsLink" hidden></button> + <button id="hide-details-link" class="details-button small-link" i18n-content="hideDetailsLink" hidden></button> + <button id="back-button" class="details-button small-link" i18n-content="backButton" hidden></button> </div> - <div id="request-access-button" class="button" - i18n-content="requestAccessButton"> - </div> </div> <div id="details" hidden> <p id="details-header" i18n-content="blockReasonHeader"></p>
diff --git a/components/supervised_user_error_page/resources/supervised_user_block_interstitial.js b/components/supervised_user_error_page/resources/supervised_user_block_interstitial.js index 18a46c8..6b9abf4 100644 --- a/components/supervised_user_error_page/resources/supervised_user_block_interstitial.js +++ b/components/supervised_user_error_page/resources/supervised_user_block_interstitial.js
@@ -2,6 +2,40 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +var mobileNav = false; + +var showDetails = false; + +/** + * For small screen mobile the navigation buttons are moved + * below the advanced text. + */ +function onResize() { + var mediaQuery = '(min-width: 240px) and (max-width: 420px) and ' + + '(max-height: 736px) and (min-height: 401px) and ' + + '(orientation: portrait), (max-width: 736px) and ' + + '(max-height: 420px) and (min-height: 240px) and ' + + '(min-width: 421px) and (orientation: landscape)'; + + // Check for change in nav status. + if (mobileNav != window.matchMedia(mediaQuery).matches) { + mobileNav = !mobileNav; + updateDetails(); + } +} + +function updateDetails() { + $('information-container').hidden = mobileNav && showDetails; + $('details').hidden = !showDetails; +} + +function setupMobileNav() { + window.addEventListener('resize', onResize); + onResize(); +} + +document.addEventListener('DOMContentLoaded', setupMobileNav); + function sendCommand(cmd) { window.domAutomationController.setAutomationId(1); window.domAutomationController.send(cmd); @@ -57,18 +91,16 @@ sendCommand('back'); }; $('show-details-link').onclick = function(event) { - $('details').hidden = false; + showDetails = true; $('show-details-link').hidden = true; $('hide-details-link').hidden = false; - $('information-container').classList.add('hidden-on-mobile'); - $('request-access-button').classList.add('hidden-on-mobile'); + updateDetails(); }; $('hide-details-link').onclick = function(event) { - $('details').hidden = true; + showDetails = false; $('show-details-link').hidden = false; $('hide-details-link').hidden = true; - $('information-container').classList.remove('hidden-on-mobile'); - $('request-access-button').classList.remove('hidden-on-mobile'); + updateDetails(); }; if (window.domAutomationController && loadTimeData.getBoolean('showFeedbackLink')) { @@ -88,17 +120,20 @@ console.log('setRequestStatus(' + isSuccessful +')'); $('block-page-header').hidden = true; $('block-page-message').hidden = true; + $('hide-details-link').hidden = true; + showDetails = false; + updateDetails(); + if (isSuccessful) { $('request-failed-message').hidden = true; $('request-sent-message').hidden = false; - $('show-details-link').hidden = true; - $('hide-details-link').hidden = true; - $('details').hidden = true; $('back-button').hidden = !window.domAutomationController; $('request-access-button').hidden = true; + $('show-details-link').hidden = true; } else { $('request-failed-message').hidden = false; $('request-access-button').hidden = false; + $('show-details-link').hidden = false; } }
diff --git a/components/supervised_user_error_page/supervised_user_error_page.cc b/components/supervised_user_error_page/supervised_user_error_page.cc index 308996d76..e098c062 100644 --- a/components/supervised_user_error_page/supervised_user_error_page.cc +++ b/components/supervised_user_error_page/supervised_user_error_page.cc
@@ -23,11 +23,9 @@ static const int kAvatarSize1x = 45; static const int kAvatarSize2x = 90; -#if defined(GOOGLE_CHROME_BUILD) bool ReasonIsAutomatic(FilteringBehaviorReason reason) { return reason == ASYNC_CHECKER || reason == BLACKLIST; } -#endif std::string BuildAvatarImageUrl(const std::string& url, int size) { std::string result = url; @@ -124,10 +122,9 @@ reason, is_child_account, second_custodian.empty()))); strings.SetString("blockReasonHeader", l10n_util::GetStringUTF16( IDS_SUPERVISED_USER_BLOCK_HEADER)); - bool show_feedback = false; -#if defined(GOOGLE_CHROME_BUILD) - show_feedback = is_child_account && ReasonIsAutomatic(reason); -#endif + bool show_feedback = ReasonIsAutomatic(reason); + DCHECK(is_child_account || !show_feedback); + strings.SetBoolean("showFeedbackLink", show_feedback); strings.SetString("feedbackLink", l10n_util::GetStringUTF16( IDS_BLOCK_INTERSTITIAL_SEND_FEEDBACK));
diff --git a/components/supervised_user_error_page/supervised_user_error_page_unittest.cc b/components/supervised_user_error_page/supervised_user_error_page_unittest.cc index fbd5e2e1..7565ff4 100644 --- a/components/supervised_user_error_page/supervised_user_error_page_unittest.cc +++ b/components/supervised_user_error_page/supervised_user_error_page_unittest.cc
@@ -40,8 +40,7 @@ {DEFAULT, false, true, IDS_SUPERVISED_USER_BLOCK_MESSAGE_DEFAULT}, {DEFAULT, true, true, IDS_CHILD_BLOCK_MESSAGE_DEFAULT_SINGLE_PARENT}, {DEFAULT, true, false, IDS_CHILD_BLOCK_MESSAGE_DEFAULT_MULTI_PARENT}, - {ASYNC_CHECKER, false, false, IDS_SUPERVISED_USER_BLOCK_MESSAGE_SAFE_SITES}, - {ASYNC_CHECKER, false, true, IDS_SUPERVISED_USER_BLOCK_MESSAGE_SAFE_SITES}, + // SafeSites is not enabled for supervised users. {ASYNC_CHECKER, true, true, IDS_SUPERVISED_USER_BLOCK_MESSAGE_SAFE_SITES}, {ASYNC_CHECKER, true, false, IDS_SUPERVISED_USER_BLOCK_MESSAGE_SAFE_SITES}, {MANUAL, false, false, IDS_SUPERVISED_USER_BLOCK_MESSAGE_MANUAL}, @@ -93,13 +92,12 @@ EXPECT_THAT(result, testing::HasSubstr(param.second_custodian)); EXPECT_THAT(result, testing::HasSubstr(param.second_custodian_email)); } -#if defined(GOOGLE_CHROME_BUILD) - if (param.is_child_account && - (param.reason == ASYNC_CHECKER || param.reason == BLACKLIST)) + if (param.reason == ASYNC_CHECKER || param.reason == BLACKLIST) { EXPECT_THAT(result, testing::HasSubstr("\"showFeedbackLink\":true")); - else -#endif + } else { EXPECT_THAT(result, testing::HasSubstr("\"showFeedbackLink\":false")); + } + // Messages containing parameters aren't tested since they get modified before // they are added to the result. if (param.allow_access_requests) { @@ -201,7 +199,7 @@ {true, "url1", "url2", "custodian", "custodian_email", "custodian2", "custodian2_email", false, DEFAULT, true}, {true, "url1", "url2", "custodian", "custodian_email", "custodian2", - "custodian2_email", false, ASYNC_CHECKER, true}, + "custodian2_email", true, ASYNC_CHECKER, true}, }; INSTANTIATE_TEST_CASE_P(GetBlockMessageIDParameterized,
diff --git a/components/supervised_user_error_page_strings.grdp b/components/supervised_user_error_page_strings.grdp index de4c44a1..264f4d6 100644 --- a/components/supervised_user_error_page_strings.grdp +++ b/components/supervised_user_error_page_strings.grdp
@@ -44,7 +44,7 @@ We could not reach your parents at the moment. Please try again. </message> <message name="IDS_BLOCK_INTERSTITIAL_SEND_FEEDBACK" desc="The text for a link to submit feedback about a blocked site."> - Was this unexpected? <ph name="BEGIN_LINK"><a is="action-link" id="feedback-link"></ph>Let us know<ph name="END_LINK"></a></ph> + Was this unexpected? <ph name="BEGIN_LINK"><a href="#" id="feedback-link"></ph>Let us know<ph name="END_LINK"></a></ph> </message> <message name="IDS_BLOCK_INTERSTITIAL_SHOW_DETAILS" desc="The text for the link to show details about the interstitial."> Details
diff --git a/content/browser/notifications/platform_notification_context_impl.cc b/content/browser/notifications/platform_notification_context_impl.cc index c7a6b2c..2cf1d98 100644 --- a/content/browser/notifications/platform_notification_context_impl.cc +++ b/content/browser/notifications/platform_notification_context_impl.cc
@@ -8,6 +8,7 @@ #include "base/files/file_util.h" #include "base/memory/ptr_util.h" #include "base/metrics/histogram_macros.h" +#include "base/stl_util.h" #include "base/threading/sequenced_worker_pool.h" #include "content/browser/notifications/blink_notification_service_impl.h" #include "content/browser/notifications/notification_database.h" @@ -131,13 +132,11 @@ void PlatformNotificationContextImpl::RemoveService( BlinkNotificationServiceImpl* service) { DCHECK_CURRENTLY_ON(BrowserThread::IO); - auto services_to_remove = std::remove_if( - services_.begin(), services_.end(), + base::EraseIf( + services_, [service](const std::unique_ptr<BlinkNotificationServiceImpl>& ptr) { return ptr.get() == service; }); - - services_.erase(services_to_remove, services_.end()); } void PlatformNotificationContextImpl::ReadNotificationData(
diff --git a/content/browser/renderer_host/text_input_manager.cc b/content/browser/renderer_host/text_input_manager.cc index c472b34c..6a96396 100644 --- a/content/browser/renderer_host/text_input_manager.cc +++ b/content/browser/renderer_host/text_input_manager.cc
@@ -102,7 +102,11 @@ // already synthesized the loss of TextInputState for the |view| before (see // below). So we can forget about this method ever being called (no observer // calls necessary). + // NOTE: Android requires state to be returned even when the current state + // is/becomes NONE. Otherwise IME may become irresponsive. +#if !defined(OS_ANDROID) return; +#endif } // Since |view| is registered, we already have a previous value for its
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc index f8910b4..8647047 100644 --- a/content/browser/web_contents/web_contents_impl.cc +++ b/content/browser/web_contents/web_contents_impl.cc
@@ -173,7 +173,7 @@ const char kDotGoogleDotCom[] = ".google.com"; #if defined(OS_ANDROID) -const char kWebContentsAndroidKey[] = "web_contents_android"; +const void* const kWebContentsAndroidKey = &kWebContentsAndroidKey; #endif // OS_ANDROID base::LazyInstance<std::vector<WebContentsImpl::CreatedCallback>>::
diff --git a/content/child/service_worker/service_worker_network_provider.cc b/content/child/service_worker/service_worker_network_provider.cc index 555f509..7a13d72 100644 --- a/content/child/service_worker/service_worker_network_provider.cc +++ b/content/child/service_worker/service_worker_network_provider.cc
@@ -6,6 +6,8 @@ #include "base/atomic_sequence_num.h" #include "content/child/child_thread_impl.h" +#include "content/child/request_extra_data.h" +#include "content/child/service_worker/service_worker_handle_reference.h" #include "content/child/service_worker/service_worker_provider_context.h" #include "content/common/navigation_params.h" #include "content/common/service_worker/service_worker_messages.h" @@ -14,6 +16,7 @@ #include "content/public/common/browser_side_navigation_policy.h" #include "ipc/ipc_sync_channel.h" #include "third_party/WebKit/public/platform/WebSecurityOrigin.h" +#include "third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerNetworkProvider.h" #include "third_party/WebKit/public/web/WebLocalFrame.h" #include "third_party/WebKit/public/web/WebSandboxFlags.h" @@ -21,8 +24,6 @@ namespace { -const char kUserDataKey[] = "SWProviderKey"; - // Must be unique in the child process. int GetNextProviderId() { static base::StaticAtomicSequenceNumber sequence; @@ -42,22 +43,44 @@ return true; } +// An WebServiceWorkerNetworkProvider for frame. This wraps +// ServiceWorkerNetworkProvider implementation and is owned by blink. +class WebServiceWorkerNetworkProviderForFrame + : public blink::WebServiceWorkerNetworkProvider { + public: + WebServiceWorkerNetworkProviderForFrame( + std::unique_ptr<ServiceWorkerNetworkProvider> provider) + : provider_(std::move(provider)) {} + + void willSendRequest(blink::WebURLRequest& request) override { + RequestExtraData* extra_data = + static_cast<RequestExtraData*>(request.getExtraData()); + if (!extra_data) + extra_data = new RequestExtraData(); + extra_data->set_service_worker_provider_id(provider_->provider_id()); + request.setExtraData(extra_data); + } + + bool isControlledByServiceWorker() override { + return provider_->IsControlledByServiceWorker(); + } + + int64_t serviceWorkerID() override { + if (provider_->context() && provider_->context()->controller()) + return provider_->context()->controller()->version_id(); + return kInvalidServiceWorkerVersionId; + } + + ServiceWorkerNetworkProvider* provider() { return provider_.get(); } + + private: + std::unique_ptr<ServiceWorkerNetworkProvider> provider_; +}; + } // namespace -void ServiceWorkerNetworkProvider::AttachToDocumentState( - base::SupportsUserData* datasource_userdata, - std::unique_ptr<ServiceWorkerNetworkProvider> network_provider) { - datasource_userdata->SetUserData(&kUserDataKey, network_provider.release()); -} - -ServiceWorkerNetworkProvider* ServiceWorkerNetworkProvider::FromDocumentState( - base::SupportsUserData* datasource_userdata) { - return static_cast<ServiceWorkerNetworkProvider*>( - datasource_userdata->GetUserData(&kUserDataKey)); -} - // static -std::unique_ptr<ServiceWorkerNetworkProvider> +std::unique_ptr<blink::WebServiceWorkerNetworkProvider> ServiceWorkerNetworkProvider::CreateForNavigation( int route_id, const RequestNavigationParams& request_params, @@ -114,7 +137,16 @@ network_provider = std::unique_ptr<ServiceWorkerNetworkProvider>( new ServiceWorkerNetworkProvider()); } - return network_provider; + return base::MakeUnique<WebServiceWorkerNetworkProviderForFrame>( + std::move(network_provider)); +} + +// static +ServiceWorkerNetworkProvider* +ServiceWorkerNetworkProvider::FromWebServiceWorkerNetworkProvider( + blink::WebServiceWorkerNetworkProvider* provider) { + return static_cast<WebServiceWorkerNetworkProviderForFrame*>(provider) + ->provider(); } ServiceWorkerNetworkProvider::ServiceWorkerNetworkProvider(
diff --git a/content/child/service_worker/service_worker_network_provider.h b/content/child/service_worker/service_worker_network_provider.h index c991aec..94afa943 100644 --- a/content/child/service_worker/service_worker_network_provider.h +++ b/content/child/service_worker/service_worker_network_provider.h
@@ -18,12 +18,13 @@ namespace blink { class WebLocalFrame; +class WebServiceWorkerNetworkProvider; } // namespace blink namespace content { -class ServiceWorkerProviderContext; struct RequestNavigationParams; +class ServiceWorkerProviderContext; // A unique provider_id is generated for each instance. // Instantiated prior to the main resource load being started and remains @@ -35,22 +36,20 @@ // // Basically, it's a scoped integer that sends an ipc upon construction // and destruction. -class CONTENT_EXPORT ServiceWorkerNetworkProvider - : public base::SupportsUserData::Data { +class CONTENT_EXPORT ServiceWorkerNetworkProvider { public: - // Ownership is transferred to the DocumentState. - static void AttachToDocumentState( - base::SupportsUserData* document_state, - std::unique_ptr<ServiceWorkerNetworkProvider> network_provider); + // Creates a ServiceWorkerNetworkProvider for navigation and wraps it + // with WebServiceWorkerNetworkProvider to be owned by Blink. + static std::unique_ptr<blink::WebServiceWorkerNetworkProvider> + CreateForNavigation(int route_id, + const RequestNavigationParams& request_params, + blink::WebLocalFrame* frame, + bool content_initiated); - static ServiceWorkerNetworkProvider* FromDocumentState( - base::SupportsUserData* document_state); - - static std::unique_ptr<ServiceWorkerNetworkProvider> CreateForNavigation( - int route_id, - const RequestNavigationParams& request_params, - blink::WebLocalFrame* frame, - bool content_initiated); + // Valid only for WebServiceWorkerNetworkProvider created by + // CreateForNavigation. + static ServiceWorkerNetworkProvider* FromWebServiceWorkerNetworkProvider( + blink::WebServiceWorkerNetworkProvider*); // PlzNavigate // The |browser_provider_id| is initialized by the browser for navigations. @@ -61,8 +60,9 @@ ServiceWorkerNetworkProvider(int route_id, ServiceWorkerProviderType type, bool is_parent_frame_secure); + ServiceWorkerNetworkProvider(); - ~ServiceWorkerNetworkProvider() override; + ~ServiceWorkerNetworkProvider(); int provider_id() const { return provider_id_; } ServiceWorkerProviderContext* context() const { return context_.get(); }
diff --git a/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java b/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java index b22367f..35bd096 100644 --- a/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java +++ b/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java
@@ -2416,7 +2416,8 @@ /** * @see View#onDragEvent(DragEvent) */ - @TargetApi(Build.VERSION_CODES.N) + // TODO(hush): uncomment below when we build with API 24. + // @TargetApi(Build.VERSION_CODES.N) public boolean onDragEvent(DragEvent event) { if (mNativeContentViewCore == 0 || Build.VERSION.SDK_INT <= Build.VERSION_CODES.M) { return false; @@ -2436,8 +2437,9 @@ StringBuilder content = new StringBuilder(""); if (event.getAction() == DragEvent.ACTION_DROP) { - // TODO(hush): obtain dragdrop permissions, when dragging files into Chrome/WebView is - // supported. Not necessary to do so for now, because only text dragging is supported. + // TODO(hush): obtain dragdrop permissions (via reflection?), when dragging files into + // Chrome/WebView is supported. Not necessary to do so for now, because only text + // dragging is supported. ClipData clipData = event.getClipData(); final int itemCount = clipData.getItemCount(); for (int i = 0; i < itemCount; i++) {
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc index e3199573..5a7b201 100644 --- a/content/renderer/render_frame_impl.cc +++ b/content/renderer/render_frame_impl.cc
@@ -187,6 +187,7 @@ #include "third_party/WebKit/public/platform/WebURLError.h" #include "third_party/WebKit/public/platform/WebURLResponse.h" #include "third_party/WebKit/public/platform/WebVector.h" +#include "third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerNetworkProvider.h" #include "third_party/WebKit/public/platform/scheduler/renderer/renderer_scheduler.h" #include "third_party/WebKit/public/web/WebColorSuggestion.h" #include "third_party/WebKit/public/web/WebConsoleMessage.h" @@ -2987,16 +2988,14 @@ if (!ChildThreadImpl::current()) return nullptr; // May be null in some tests. ServiceWorkerNetworkProvider* provider = - ServiceWorkerNetworkProvider::FromDocumentState( - DocumentState::FromDataSource(frame_->dataSource())); - DCHECK(provider); + ServiceWorkerNetworkProvider::FromWebServiceWorkerNetworkProvider( + frame_->dataSource()->getServiceWorkerNetworkProvider()); if (!provider->context()) { // The context can be null when the frame is sandboxed. return nullptr; } return new WebServiceWorkerProviderImpl( - ChildThreadImpl::current()->thread_safe_sender(), - provider->context()); + ChildThreadImpl::current()->thread_safe_sender(), provider->context()); } void RenderFrameImpl::didAccessInitialDocument() { @@ -3418,12 +3417,10 @@ // Create the serviceworker's per-document network observing object if it // does not exist (When navigation happens within a page, the provider already // exists). - if (ServiceWorkerNetworkProvider::FromDocumentState( - DocumentState::FromDataSource(datasource))) + if (datasource->getServiceWorkerNetworkProvider()) return; - ServiceWorkerNetworkProvider::AttachToDocumentState( - DocumentState::FromDataSource(datasource), + datasource->setServiceWorkerNetworkProvider( ServiceWorkerNetworkProvider::CreateForNavigation( routing_id_, navigation_state->request_params(), frame, content_initiated)); @@ -4280,31 +4277,30 @@ // when it is re-created in the new process. bool should_replace_current_entry = data_source->replacesCurrentHistoryItem(); - int provider_id = kInvalidServiceWorkerProviderId; + // Initializes service worker related request info. if (request.getFrameType() == blink::WebURLRequest::FrameTypeTopLevel || request.getFrameType() == blink::WebURLRequest::FrameTypeNested) { // |provisionalDataSource| may be null in some content::ResourceFetcher // use cases, we don't hook those requests. if (frame->provisionalDataSource()) { - ServiceWorkerNetworkProvider* provider = - ServiceWorkerNetworkProvider::FromDocumentState( - DocumentState::FromDataSource(frame->provisionalDataSource())); + blink::WebServiceWorkerNetworkProvider* provider = + frame->provisionalDataSource()->getServiceWorkerNetworkProvider(); DCHECK(provider); - provider_id = provider->provider_id(); + provider->willSendRequest(request); } } else if (frame->dataSource()) { - ServiceWorkerNetworkProvider* provider = - ServiceWorkerNetworkProvider::FromDocumentState( - DocumentState::FromDataSource(frame->dataSource())); + blink::WebServiceWorkerNetworkProvider* provider = + frame->dataSource()->getServiceWorkerNetworkProvider(); DCHECK(provider); - provider_id = provider->provider_id(); + provider->willSendRequest(request); + // If the provider does not have a controller at this point, the renderer // expects the request to never be handled by a controlling service worker, // so set the ServiceWorkerMode to skip local workers here. Otherwise, a // service worker that is in the process of becoming the controller (i.e., // via claim()) on the browser-side could handle the request and break // the assumptions of the renderer. - if (!provider->IsControlledByServiceWorker() && + if (!provider->isControlledByServiceWorker() && request.getServiceWorkerMode() != blink::WebURLRequest::ServiceWorkerMode::None) { request.setServiceWorkerMode( @@ -4315,7 +4311,10 @@ WebFrame* parent = frame->parent(); int parent_routing_id = parent ? GetRoutingIdForFrameOrProxy(parent) : -1; - RequestExtraData* extra_data = new RequestExtraData(); + RequestExtraData* extra_data = + static_cast<RequestExtraData*>(request.getExtraData()); + if (!extra_data) + extra_data = new RequestExtraData(); extra_data->set_visibility_state(visibilityState()); extra_data->set_custom_user_agent(custom_user_agent); extra_data->set_requested_with(requested_with); @@ -4329,7 +4328,6 @@ navigation_state->common_params().allow_download); extra_data->set_transition_type(transition_type); extra_data->set_should_replace_current_entry(should_replace_current_entry); - extra_data->set_service_worker_provider_id(provider_id); extra_data->set_stream_override(std::move(stream_override)); bool is_prefetch = GetContentClient()->renderer()->IsPrefetchOnly(this, request); @@ -4661,22 +4659,6 @@ return screen_orientation_dispatcher_; } -bool RenderFrameImpl::isControlledByServiceWorker(WebDataSource& data_source) { - ServiceWorkerNetworkProvider* provider = - ServiceWorkerNetworkProvider::FromDocumentState( - DocumentState::FromDataSource(&data_source)); - return provider->IsControlledByServiceWorker(); -} - -int64_t RenderFrameImpl::serviceWorkerID(WebDataSource& data_source) { - ServiceWorkerNetworkProvider* provider = - ServiceWorkerNetworkProvider::FromDocumentState( - DocumentState::FromDataSource(&data_source)); - if (provider->context() && provider->context()->controller()) - return provider->context()->controller()->version_id(); - return kInvalidServiceWorkerVersionId; -} - void RenderFrameImpl::postAccessibilityEvent(const blink::WebAXObject& obj, blink::WebAXEvent event) { HandleWebAccessibilityEvent(obj, event);
diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h index 763807cf..b16656cc 100644 --- a/content/renderer/render_frame_impl.h +++ b/content/renderer/render_frame_impl.h
@@ -649,8 +649,6 @@ blink::WebString doNotTrackValue() override; bool allowWebGL(bool default_value) override; blink::WebScreenOrientationClient* webScreenOrientationClient() override; - bool isControlledByServiceWorker(blink::WebDataSource& data_source) override; - int64_t serviceWorkerID(blink::WebDataSource& data_source) override; void postAccessibilityEvent(const blink::WebAXObject& obj, blink::WebAXEvent event) override; void handleAccessibilityFindInPageResult(
diff --git a/content/renderer/render_view_browsertest.cc b/content/renderer/render_view_browsertest.cc index 3f3668c3..6faaaa70 100644 --- a/content/renderer/render_view_browsertest.cc +++ b/content/renderer/render_view_browsertest.cc
@@ -66,6 +66,7 @@ #include "third_party/WebKit/public/platform/WebHTTPBody.h" #include "third_party/WebKit/public/platform/WebString.h" #include "third_party/WebKit/public/platform/WebURLResponse.h" +#include "third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerNetworkProvider.h" #include "third_party/WebKit/public/web/WebDataSource.h" #include "third_party/WebKit/public/web/WebDeviceEmulationParams.h" #include "third_party/WebKit/public/web/WebFrameContentDumper.h" @@ -1956,34 +1957,37 @@ } TEST_F(RenderViewImplTest, ServiceWorkerNetworkProviderSetup) { - ServiceWorkerNetworkProvider* provider = NULL; - RequestExtraData* extra_data = NULL; + blink::WebServiceWorkerNetworkProvider* webprovider = nullptr; + ServiceWorkerNetworkProvider* provider = nullptr; + RequestExtraData* extra_data = nullptr; // Make sure each new document has a new provider and // that the main request is tagged with the provider's id. LoadHTML("<b>A Document</b>"); ASSERT_TRUE(GetMainFrame()->dataSource()); - provider = ServiceWorkerNetworkProvider::FromDocumentState( - DocumentState::FromDataSource(GetMainFrame()->dataSource())); - ASSERT_TRUE(provider); + webprovider = GetMainFrame()->dataSource()->getServiceWorkerNetworkProvider(); + ASSERT_TRUE(webprovider); extra_data = static_cast<RequestExtraData*>( GetMainFrame()->dataSource()->getRequest().getExtraData()); ASSERT_TRUE(extra_data); - EXPECT_EQ(extra_data->service_worker_provider_id(), - provider->provider_id()); + provider = ServiceWorkerNetworkProvider::FromWebServiceWorkerNetworkProvider( + webprovider); + ASSERT_TRUE(provider); + EXPECT_EQ(extra_data->service_worker_provider_id(), provider->provider_id()); int provider1_id = provider->provider_id(); LoadHTML("<b>New Document B Goes Here</b>"); ASSERT_TRUE(GetMainFrame()->dataSource()); - provider = ServiceWorkerNetworkProvider::FromDocumentState( - DocumentState::FromDataSource(GetMainFrame()->dataSource())); + webprovider = GetMainFrame()->dataSource()->getServiceWorkerNetworkProvider(); + ASSERT_TRUE(provider); + provider = ServiceWorkerNetworkProvider::FromWebServiceWorkerNetworkProvider( + webprovider); ASSERT_TRUE(provider); EXPECT_NE(provider1_id, provider->provider_id()); extra_data = static_cast<RequestExtraData*>( GetMainFrame()->dataSource()->getRequest().getExtraData()); ASSERT_TRUE(extra_data); - EXPECT_EQ(extra_data->service_worker_provider_id(), - provider->provider_id()); + EXPECT_EQ(extra_data->service_worker_provider_id(), provider->provider_id()); // See that subresource requests are also tagged with the provider's id. EXPECT_EQ(frame(), RenderFrameImpl::FromWebFrame(GetMainFrame())); @@ -1993,8 +1997,7 @@ frame()->willSendRequest(GetMainFrame(), request); extra_data = static_cast<RequestExtraData*>(request.getExtraData()); ASSERT_TRUE(extra_data); - EXPECT_EQ(extra_data->service_worker_provider_id(), - provider->provider_id()); + EXPECT_EQ(extra_data->service_worker_provider_id(), provider->provider_id()); } TEST_F(RenderViewImplTest, OnSetAccessibilityMode) {
diff --git a/content/renderer/service_worker/service_worker_context_client.cc b/content/renderer/service_worker/service_worker_context_client.cc index babd858..838a19b4 100644 --- a/content/renderer/service_worker/service_worker_context_client.cc +++ b/content/renderer/service_worker/service_worker_context_client.cc
@@ -61,12 +61,11 @@ #include "third_party/WebKit/public/platform/modules/payments/WebPaymentAppRequest.h" #include "third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerClientQueryOptions.h" #include "third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerError.h" +#include "third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerNetworkProvider.h" #include "third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerRequest.h" #include "third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerResponse.h" -#include "third_party/WebKit/public/web/WebDataSource.h" #include "third_party/WebKit/public/web/modules/serviceworker/WebServiceWorkerContextClient.h" #include "third_party/WebKit/public/web/modules/serviceworker/WebServiceWorkerContextProxy.h" -#include "third_party/WebKit/public/web/modules/serviceworker/WebServiceWorkerNetworkProvider.h" namespace content { @@ -84,36 +83,28 @@ WorkerContextDestroyed(embedded_worker_id); } -// We store an instance of this class in the "extra data" of the WebDataSource -// and attach a ServiceWorkerNetworkProvider to it as base::UserData. -// (see createServiceWorkerNetworkProvider). -class DataSourceExtraData - : public blink::WebDataSource::ExtraData, - public base::SupportsUserData { - public: - DataSourceExtraData() {} - ~DataSourceExtraData() override {} -}; - // Called on the main thread only and blink owns it. class WebServiceWorkerNetworkProviderImpl : public blink::WebServiceWorkerNetworkProvider { public: + explicit WebServiceWorkerNetworkProviderImpl( + std::unique_ptr<ServiceWorkerNetworkProvider> provider) + : provider_(std::move(provider)) {} + // Blink calls this method for each request starting with the main script, // we tag them with the provider id. - void willSendRequest(blink::WebDataSource* data_source, - blink::WebURLRequest& request) override { - ServiceWorkerNetworkProvider* provider = - ServiceWorkerNetworkProvider::FromDocumentState( - static_cast<DataSourceExtraData*>(data_source->getExtraData())); + void willSendRequest(blink::WebURLRequest& request) override { std::unique_ptr<RequestExtraData> extra_data(new RequestExtraData); - extra_data->set_service_worker_provider_id(provider->provider_id()); + extra_data->set_service_worker_provider_id(provider_->provider_id()); extra_data->set_originated_from_service_worker(true); // Service workers are only available in secure contexts, so all requests // are initiated in a secure context. extra_data->set_initiated_in_secure_context(true); request.setExtraData(extra_data.release()); } + + private: + std::unique_ptr<ServiceWorkerNetworkProvider> provider_; }; ServiceWorkerStatusCode EventResultToStatus( @@ -795,8 +786,7 @@ } blink::WebServiceWorkerNetworkProvider* -ServiceWorkerContextClient::createServiceWorkerNetworkProvider( - blink::WebDataSource* data_source) { +ServiceWorkerContextClient::createServiceWorkerNetworkProvider() { DCHECK(main_thread_task_runner_->RunsTasksOnCurrentThread()); // Create a content::ServiceWorkerNetworkProvider for this data source so @@ -811,15 +801,8 @@ provider->SetServiceWorkerVersionId(service_worker_version_id_, embedded_worker_id_); - // The provider is kept around for the lifetime of the DataSource - // and ownership is transferred to the DataSource. - DataSourceExtraData* extra_data = new DataSourceExtraData(); - data_source->setExtraData(extra_data); - ServiceWorkerNetworkProvider::AttachToDocumentState(extra_data, - std::move(provider)); - // Blink is responsible for deleting the returned object. - return new WebServiceWorkerNetworkProviderImpl(); + return new WebServiceWorkerNetworkProviderImpl(std::move(provider)); } blink::WebServiceWorkerProvider*
diff --git a/content/renderer/service_worker/service_worker_context_client.h b/content/renderer/service_worker/service_worker_context_client.h index ba76461..cc7ae1d 100644 --- a/content/renderer/service_worker/service_worker_context_client.h +++ b/content/renderer/service_worker/service_worker_context_client.h
@@ -40,7 +40,6 @@ namespace blink { class WebDataConsumerHandle; -class WebDataSource; struct WebServiceWorkerClientQueryOptions; class WebServiceWorkerContextProxy; class WebServiceWorkerProvider; @@ -176,8 +175,8 @@ double dispatch_event_time) override; // Called on the main thread. - blink::WebServiceWorkerNetworkProvider* createServiceWorkerNetworkProvider( - blink::WebDataSource* data_source) override; + blink::WebServiceWorkerNetworkProvider* createServiceWorkerNetworkProvider() + override; blink::WebServiceWorkerProvider* createServiceWorkerProvider() override; void postMessageToClient(const blink::WebString& uuid,
diff --git a/content/renderer/shared_worker/embedded_shared_worker_stub.cc b/content/renderer/shared_worker/embedded_shared_worker_stub.cc index eb8d6e33..cb5ef55 100644 --- a/content/renderer/shared_worker/embedded_shared_worker_stub.cc +++ b/content/renderer/shared_worker/embedded_shared_worker_stub.cc
@@ -26,10 +26,9 @@ #include "ipc/ipc_message_macros.h" #include "third_party/WebKit/public/platform/URLConversion.h" #include "third_party/WebKit/public/platform/WebSecurityOrigin.h" -#include "third_party/WebKit/public/web/WebDataSource.h" +#include "third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerNetworkProvider.h" #include "third_party/WebKit/public/web/WebSharedWorker.h" #include "third_party/WebKit/public/web/WebSharedWorkerClient.h" -#include "third_party/WebKit/public/web/modules/serviceworker/WebServiceWorkerNetworkProvider.h" #include "url/origin.h" namespace content { @@ -66,33 +65,21 @@ } }; -// We store an instance of this class in the "extra data" of the WebDataSource -// and attach a ServiceWorkerNetworkProvider to it as base::UserData. -// (see createServiceWorkerNetworkProvider). -class DataSourceExtraData - : public blink::WebDataSource::ExtraData, - public base::SupportsUserData { - public: - DataSourceExtraData() {} - ~DataSourceExtraData() override {} - bool is_secure_context = false; -}; - // Called on the main thread only and blink owns it. class WebServiceWorkerNetworkProviderImpl : public blink::WebServiceWorkerNetworkProvider { public: + WebServiceWorkerNetworkProviderImpl( + std::unique_ptr<ServiceWorkerNetworkProvider> provider, + bool is_secure_context) + : provider_(std::move(provider)), is_secure_context_(is_secure_context) {} + // Blink calls this method for each request starting with the main script, // we tag them with the provider id. - void willSendRequest(blink::WebDataSource* data_source, - blink::WebURLRequest& request) override { - ServiceWorkerNetworkProvider* provider = - GetNetworkProviderFromDataSource(data_source); + void willSendRequest(blink::WebURLRequest& request) override { std::unique_ptr<RequestExtraData> extra_data(new RequestExtraData); - extra_data->set_service_worker_provider_id(provider->provider_id()); - extra_data->set_initiated_in_secure_context( - static_cast<DataSourceExtraData*>(data_source->getExtraData()) - ->is_secure_context); + extra_data->set_service_worker_provider_id(provider_->provider_id()); + extra_data->set_initiated_in_secure_context(is_secure_context_); request.setExtraData(extra_data.release()); // If the provider does not have a controller at this point, the renderer // expects subresource requests to never be handled by a controlling service @@ -102,7 +89,7 @@ // request and break the assumptions of the renderer. if (request.getRequestContext() != blink::WebURLRequest::RequestContextSharedWorker && - !provider->IsControlledByServiceWorker() && + !provider_->IsControlledByServiceWorker() && request.getServiceWorkerMode() != blink::WebURLRequest::ServiceWorkerMode::None) { request.setServiceWorkerMode( @@ -110,26 +97,19 @@ } } - bool isControlledByServiceWorker(blink::WebDataSource& data_source) override { - ServiceWorkerNetworkProvider* provider = - GetNetworkProviderFromDataSource(&data_source); - return provider->IsControlledByServiceWorker(); + bool isControlledByServiceWorker() override { + return provider_->IsControlledByServiceWorker(); } - int64_t serviceWorkerID(blink::WebDataSource& data_source) override { - ServiceWorkerNetworkProvider* provider = - GetNetworkProviderFromDataSource(&data_source); - if (provider->context()->controller()) - return provider->context()->controller()->version_id(); + int64_t serviceWorkerID() override { + if (provider_->context()->controller()) + return provider_->context()->controller()->version_id(); return kInvalidServiceWorkerVersionId; } private: - ServiceWorkerNetworkProvider* GetNetworkProviderFromDataSource( - const blink::WebDataSource* data_source) { - return ServiceWorkerNetworkProvider::FromDocumentState( - static_cast<DataSourceExtraData*>(data_source->getExtraData())); - } + std::unique_ptr<ServiceWorkerNetworkProvider> provider_; + const bool is_secure_context_; }; } // namespace @@ -245,8 +225,7 @@ } blink::WebServiceWorkerNetworkProvider* -EmbeddedSharedWorkerStub::createServiceWorkerNetworkProvider( - blink::WebDataSource* data_source) { +EmbeddedSharedWorkerStub::createServiceWorkerNetworkProvider() { // Create a content::ServiceWorkerNetworkProvider for this data source so // we can observe its requests. std::unique_ptr<ServiceWorkerNetworkProvider> provider( @@ -254,16 +233,9 @@ route_id_, SERVICE_WORKER_PROVIDER_FOR_SHARED_WORKER, true /* is_parent_frame_secure */)); - // The provider is kept around for the lifetime of the DataSource - // and ownership is transferred to the DataSource. - DataSourceExtraData* extra_data = new DataSourceExtraData(); - extra_data->is_secure_context = IsOriginSecure(url_); - data_source->setExtraData(extra_data); - ServiceWorkerNetworkProvider::AttachToDocumentState(extra_data, - std::move(provider)); - // Blink is responsible for deleting the returned object. - return new WebServiceWorkerNetworkProviderImpl(); + return new WebServiceWorkerNetworkProviderImpl(std::move(provider), + IsOriginSecure(url_)); } void EmbeddedSharedWorkerStub::sendDevToolsMessage(
diff --git a/content/renderer/shared_worker/embedded_shared_worker_stub.h b/content/renderer/shared_worker/embedded_shared_worker_stub.h index 20656c8..4985746 100644 --- a/content/renderer/shared_worker/embedded_shared_worker_stub.h +++ b/content/renderer/shared_worker/embedded_shared_worker_stub.h
@@ -73,8 +73,8 @@ blink::WebWorkerContentSettingsClientProxy* createWorkerContentSettingsClientProxy( const blink::WebSecurityOrigin& origin) override; - blink::WebServiceWorkerNetworkProvider* createServiceWorkerNetworkProvider( - blink::WebDataSource*) override; + blink::WebServiceWorkerNetworkProvider* createServiceWorkerNetworkProvider() + override; void sendDevToolsMessage(int session_id, int call_id, const blink::WebString& message,
diff --git a/ios/chrome/browser/ui/bookmarks/BUILD.gn b/ios/chrome/browser/ui/bookmarks/BUILD.gn index 5887084..bbe8c4e 100644 --- a/ios/chrome/browser/ui/bookmarks/BUILD.gn +++ b/ios/chrome/browser/ui/bookmarks/BUILD.gn
@@ -2,65 +2,15 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -source_set("bookmarks") { +source_set("bookmarks_arc") { + configs += [ "//build/config/compiler:enable_arc" ] sources = [ - "bookmark_collection_cells.h", - "bookmark_collection_cells.mm", - "bookmark_collection_view.h", - "bookmark_collection_view.mm", - "bookmark_collection_view_background.h", - "bookmark_collection_view_background.mm", - "bookmark_controller_factory.h", - "bookmark_controller_factory.mm", - "bookmark_edit_view_controller.h", - "bookmark_edit_view_controller.mm", - "bookmark_elevated_toolbar.h", - "bookmark_elevated_toolbar.mm", - "bookmark_extended_button.h", - "bookmark_extended_button.mm", - "bookmark_folder_collection_view.h", - "bookmark_folder_collection_view.mm", - "bookmark_folder_editor_view_controller.h", - "bookmark_folder_editor_view_controller.mm", - "bookmark_folder_table_view_cell.h", - "bookmark_folder_table_view_cell.mm", - "bookmark_folder_view_controller.h", - "bookmark_folder_view_controller.mm", "bookmark_home_handset_view_controller.h", "bookmark_home_handset_view_controller.mm", - "bookmark_home_primary_view.h", "bookmark_home_tablet_ntp_controller.h", "bookmark_home_tablet_ntp_controller.mm", - "bookmark_home_view_controller.h", - "bookmark_home_view_controller.mm", - "bookmark_home_waiting_view.h", - "bookmark_home_waiting_view.mm", - "bookmark_interaction_controller.h", - "bookmark_interaction_controller.mm", - "bookmark_menu_cell.h", - "bookmark_menu_cell.mm", - "bookmark_menu_item.h", - "bookmark_menu_item.mm", - "bookmark_menu_view.h", - "bookmark_menu_view.mm", - "bookmark_model_bridge_observer.h", - "bookmark_model_bridge_observer.mm", - "bookmark_navigation_controller.h", - "bookmark_navigation_controller.mm", - "bookmark_panel_view.h", - "bookmark_panel_view.mm", - "bookmark_position_cache.h", - "bookmark_position_cache.mm", - "bookmark_promo_cell.h", - "bookmark_promo_cell.mm", - "bookmark_promo_controller.h", - "bookmark_promo_controller.mm", "bookmark_utils_ios.h", "bookmark_utils_ios.mm", - "undo_manager_bridge_observer.h", - "undo_manager_bridge_observer.mm", - "undo_manager_wrapper.h", - "undo_manager_wrapper.mm", ] deps = [ ":resources", @@ -121,13 +71,151 @@ ] } +source_set("bookmarks") { + sources = [ + "bookmark_collection_cells.h", + "bookmark_collection_cells.mm", + "bookmark_collection_view.h", + "bookmark_collection_view.mm", + "bookmark_collection_view_background.h", + "bookmark_collection_view_background.mm", + "bookmark_controller_factory.h", + "bookmark_controller_factory.mm", + "bookmark_edit_view_controller.h", + "bookmark_edit_view_controller.mm", + "bookmark_elevated_toolbar.h", + "bookmark_elevated_toolbar.mm", + "bookmark_extended_button.h", + "bookmark_extended_button.mm", + "bookmark_folder_collection_view.h", + "bookmark_folder_collection_view.mm", + "bookmark_folder_editor_view_controller.h", + "bookmark_folder_editor_view_controller.mm", + "bookmark_folder_table_view_cell.h", + "bookmark_folder_table_view_cell.mm", + "bookmark_folder_view_controller.h", + "bookmark_folder_view_controller.mm", + "bookmark_home_primary_view.h", + "bookmark_home_view_controller.h", + "bookmark_home_view_controller.mm", + "bookmark_home_waiting_view.h", + "bookmark_home_waiting_view.mm", + "bookmark_interaction_controller.h", + "bookmark_interaction_controller.mm", + "bookmark_menu_cell.h", + "bookmark_menu_cell.mm", + "bookmark_menu_item.h", + "bookmark_menu_item.mm", + "bookmark_menu_view.h", + "bookmark_menu_view.mm", + "bookmark_model_bridge_observer.h", + "bookmark_model_bridge_observer.mm", + "bookmark_navigation_controller.h", + "bookmark_navigation_controller.mm", + "bookmark_panel_view.h", + "bookmark_panel_view.mm", + "bookmark_position_cache.h", + "bookmark_position_cache.mm", + "bookmark_promo_cell.h", + "bookmark_promo_cell.mm", + "bookmark_promo_controller.h", + "bookmark_promo_controller.mm", + "undo_manager_bridge_observer.h", + "undo_manager_bridge_observer.mm", + "undo_manager_wrapper.h", + "undo_manager_wrapper.mm", + ] + deps = [ + ":resources", + "//base", + "//base:i18n", + "//components/bookmarks/browser", + "//components/favicon/core", + "//components/favicon_base", + "//components/pref_registry", + "//components/prefs", + "//components/query_parser", + "//components/signin/core/browser", + "//components/strings", + "//components/undo", + "//components/url_formatter", + "//google_apis", + "//ios/chrome/app/strings", + "//ios/chrome/app/theme", + "//ios/chrome/browser", + "//ios/chrome/browser/bookmarks", + "//ios/chrome/browser/bookmarks:bookmarks_utils", + "//ios/chrome/browser/browser_state", + "//ios/chrome/browser/favicon", + "//ios/chrome/browser/metrics:metrics_internal", + "//ios/chrome/browser/signin", + "//ios/chrome/browser/tabs", + "//ios/chrome/browser/ui", + "//ios/chrome/browser/ui/alert_coordinator", + "//ios/chrome/browser/ui/bookmarks/bars", + "//ios/chrome/browser/ui/bookmarks/cells", + "//ios/chrome/browser/ui/collection_view", + "//ios/chrome/browser/ui/collection_view/cells", + "//ios/chrome/browser/ui/colors", + "//ios/chrome/browser/ui/commands", + "//ios/chrome/browser/ui/icons", + "//ios/chrome/browser/ui/keyboard", + "//ios/chrome/browser/ui/material_components", + "//ios/chrome/browser/ui/ntp", + "//ios/chrome/browser/undo", + "//ios/public/provider/chrome/browser", + "//ios/public/provider/chrome/browser/ui", + "//ios/third_party/material_components_ios", + "//ios/third_party/material_roboto_font_loader_ios", + "//ios/web", + "//skia", + "//ui/base", + "//ui/gfx", + "//url", + ] + public_deps = [ + ":bookmarks_arc", + ] + allow_circular_includes_from = [ + "//ios/chrome/browser/ui/bookmarks/bars", + "//ios/chrome/browser/ui/bookmarks/cells", + ":bookmarks_arc", + ] + libs = [ + "CoreGraphics.framework", + "QuartzCore.framework", + "UIKit.framework", + ] +} + +source_set("unit_tests_arc") { + configs += [ "//build/config/compiler:enable_arc" ] + testonly = true + sources = [ + "bookmark_utils_ios_unittest.mm", + ] + deps = [ + ":bookmarks", + "//base", + "//components/bookmarks/browser", + "//components/bookmarks/test", + "//ios/chrome/browser", + "//ios/chrome/browser/bookmarks", + "//ios/chrome/browser/browser_state:test_support", + "//ios/web:test_support", + "//testing/gtest", + ] +} + source_set("unit_tests") { testonly = true sources = [ "bookmark_home_view_controller_unittest.mm", "bookmark_ios_unittest.mm", "bookmark_position_cache_unittest.mm", - "bookmark_utils_ios_unittest.mm", + ] + public_deps = [ + ":unit_tests_arc", ] deps = [ ":bookmarks",
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_home_handset_view_controller.mm b/ios/chrome/browser/ui/bookmarks/bookmark_home_handset_view_controller.mm index 0c88d0d7..cc4e76b 100644 --- a/ios/chrome/browser/ui/bookmarks/bookmark_home_handset_view_controller.mm +++ b/ios/chrome/browser/ui/bookmarks/bookmark_home_handset_view_controller.mm
@@ -6,10 +6,7 @@ #include <memory> -#import "base/ios/weak_nsobject.h" #include "base/logging.h" -#include "base/mac/objc_property_releaser.h" -#include "base/mac/scoped_nsobject.h" #include "base/metrics/user_metrics.h" #include "base/metrics/user_metrics_action.h" #include "base/strings/sys_string_conversions.h" @@ -42,6 +39,10 @@ #include "ui/base/l10n/l10n_util.h" #include "ui/base/l10n/l10n_util_mac.h" +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + using bookmarks::BookmarkNode; namespace { @@ -59,56 +60,54 @@ BookmarkPromoControllerDelegate> { // Bridge to register for bookmark changes. std::unique_ptr<bookmarks::BookmarkModelBridge> _bridge; - base::mac::ObjCPropertyReleaser - _propertyReleaser_BookmarkHomeHandsetViewController; } // This views holds the primary content of this view controller. At any point in // time, it contains exactly one of the BookmarkCollectionView subclasses. -@property(nonatomic, retain) UIView* contentView; +@property(nonatomic, strong) UIView* contentView; // The possible views that can be shown from the menu. -@property(nonatomic, retain) BookmarkFolderCollectionView* folderView; +@property(nonatomic, strong) BookmarkFolderCollectionView* folderView; // This view is created and used if the model is not fully loaded yet by the // time this controller starts. -@property(nonatomic, retain) BookmarkHomeWaitingView* waitForModelView; +@property(nonatomic, strong) BookmarkHomeWaitingView* waitForModelView; // The menu with all the folders and special entries. -@property(nonatomic, retain) BookmarkMenuView* menuView; +@property(nonatomic, strong) BookmarkMenuView* menuView; // At any point in time, there is exactly one collection view whose view is part // of the view hierarchy. This property determine which collection view is // visible. Not by accident, this property also reflects the selected menu item // in the BookmarkMenuView. -@property(nonatomic, retain) BookmarkMenuItem* primaryMenuItem; +@property(nonatomic, strong) BookmarkMenuItem* primaryMenuItem; // When the view is first shown on the screen, this property represents the // cached value of the y of the content offset of the primary view. This // property is set to nil after it is used. -@property(nonatomic, retain) NSNumber* cachedContentPosition; +@property(nonatomic, strong) NSNumber* cachedContentPosition; // The navigation bar sits on top of the main content. -@property(nonatomic, retain) BookmarkNavigationBar* navigationBar; +@property(nonatomic, strong) BookmarkNavigationBar* navigationBar; // The layout code in this class relies on the assumption that the editingBar // has the same frame as the navigationBar. -@property(nonatomic, retain) BookmarkEditingBar* editingBar; +@property(nonatomic, strong) BookmarkEditingBar* editingBar; // The action sheet coordinator used when trying to edit a single bookmark. -@property(nonatomic, retain) ActionSheetCoordinator* actionSheetCoordinator; +@property(nonatomic, strong) ActionSheetCoordinator* actionSheetCoordinator; // The view controller used to view and edit a single bookmark. -@property(nonatomic, retain) BookmarkEditViewController* editViewController; +@property(nonatomic, strong) BookmarkEditViewController* editViewController; // The view controller used to pick a folder in which to move the selected // bookmarks. -@property(nonatomic, retain) BookmarkFolderViewController* folderSelector; +@property(nonatomic, strong) BookmarkFolderViewController* folderSelector; // The view controller to present when editing the current folder. -@property(nonatomic, retain) BookmarkFolderEditorViewController* folderEditor; +@property(nonatomic, strong) BookmarkFolderEditorViewController* folderEditor; #pragma mark Specific to this class. // The panel view slides on top of the content to display the menu. -@property(nonatomic, retain) BookmarkPanelView* panelView; +@property(nonatomic, strong) BookmarkPanelView* panelView; // Either the menu or the primaryView can scrollToTop. @property(nonatomic, assign) BOOL scrollingMenuToTop; // The controller managing the display of the promo cell and the promo view // controller. -@property(nonatomic, retain) BookmarkPromoController* bookmarkPromoController; +@property(nonatomic, strong) BookmarkPromoController* bookmarkPromoController; #pragma mark View loading and switching // This method is called if the view needs to be loaded and the model is not @@ -239,9 +238,6 @@ browserState:(ios::ChromeBrowserState*)browserState { self = [super initWithLoader:loader browserState:browserState]; if (self) { - _propertyReleaser_BookmarkHomeHandsetViewController.Init( - self, [BookmarkHomeHandsetViewController class]); - _bridge.reset(new bookmarks::BookmarkModelBridge(self, self.bookmarks)); // It is important to initialize the promo controller with the browser state // passed in, as it could be incognito. @@ -261,7 +257,6 @@ _folderSelector.delegate = nil; _panelView.delegate = nil; - [super dealloc]; } - (void)removeEditNode:(const BookmarkNode*)node @@ -278,8 +273,8 @@ - (void)viewDidLoad { [super viewDidLoad]; - base::scoped_nsobject<BookmarkNavigationBar> bar( - [[BookmarkNavigationBar alloc] initWithFrame:[self navigationBarFrame]]); + BookmarkNavigationBar* bar = + [[BookmarkNavigationBar alloc] initWithFrame:[self navigationBarFrame]]; self.navigationBar = bar; [self.navigationBar setEditTarget:self action:@selector(navigationBarWantsEditing:)]; @@ -316,8 +311,8 @@ DCHECK([self isViewLoaded]); // Present a waiting view. - base::scoped_nsobject<BookmarkHomeWaitingView> waitingView( - [[BookmarkHomeWaitingView alloc] initWithFrame:self.view.bounds]); + BookmarkHomeWaitingView* waitingView = + [[BookmarkHomeWaitingView alloc] initWithFrame:self.view.bounds]; self.waitForModelView = waitingView; [self.view addSubview:self.waitForModelView]; [self.waitForModelView startWaiting]; @@ -327,15 +322,15 @@ DCHECK(self.bookmarks->loaded()); DCHECK([self isViewLoaded]); - self.panelView = base::scoped_nsobject<BookmarkPanelView>( + self.panelView = [[BookmarkPanelView alloc] initWithFrame:[self frameForPrimaryView] - menuViewWidth:kBookmarkMenuWidth]); + menuViewWidth:kBookmarkMenuWidth]; self.panelView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; self.panelView.delegate = self; [self.view insertSubview:self.panelView atIndex:0]; - self.contentView = base::scoped_nsobject<UIView>([[UIView alloc] init]); + self.contentView = [[UIView alloc] init]; self.contentView.frame = self.panelView.contentView.bounds; self.contentView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; @@ -343,10 +338,9 @@ // The user can swipe the BookmarkPanelView to show the menuView. // Therefore, it must be created here. - self.menuView = - base::scoped_nsobject<BookmarkMenuView>([[BookmarkMenuView alloc] - initWithBrowserState:self.browserState - frame:self.panelView.menuView.bounds]); + self.menuView = [[BookmarkMenuView alloc] + initWithBrowserState:self.browserState + frame:self.panelView.menuView.bounds]; self.menuView.delegate = self; [self.panelView.menuView addSubview:self.menuView]; self.menuView.autoresizingMask = @@ -379,10 +373,9 @@ if (self.folderView) return; - base::scoped_nsobject<BookmarkFolderCollectionView> view( - [[BookmarkFolderCollectionView alloc] - initWithBrowserState:self.browserState - frame:[self frameForPrimaryView]]); + BookmarkFolderCollectionView* view = [[BookmarkFolderCollectionView alloc] + initWithBrowserState:self.browserState + frame:[self frameForPrimaryView]]; self.folderView = view; self.folderView.delegate = self; [self.folderView setEditing:self.editing animated:NO]; @@ -438,8 +431,8 @@ } if (!self.editingBar) { - self.editingBar = base::scoped_nsobject<BookmarkEditingBar>( - [[BookmarkEditingBar alloc] initWithFrame:self.navigationBar.frame]); + self.editingBar = + [[BookmarkEditingBar alloc] initWithFrame:self.navigationBar.frame]; [self.editingBar setCancelTarget:self action:@selector(editingBarCancel)]; [self.editingBar setDeleteTarget:self action:@selector(editingBarDelete)]; [self.editingBar setMoveTarget:self action:@selector(editingBarMove)]; @@ -602,20 +595,20 @@ forCell:(BookmarkItemCell*)cell { DCHECK(!self.editViewController); DCHECK(!self.actionSheetCoordinator); - self.actionSheetCoordinator = [[[ActionSheetCoordinator alloc] - initWithBaseViewController:self - title:nil - message:nil - rect:CGRectZero - view:nil] autorelease]; - base::WeakNSObject<BookmarkHomeHandsetViewController> weakSelf(self); + self.actionSheetCoordinator = + [[ActionSheetCoordinator alloc] initWithBaseViewController:self + title:nil + message:nil + rect:CGRectZero + view:nil]; + __weak BookmarkHomeHandsetViewController* weakSelf = self; // Select action. [self.actionSheetCoordinator addItemWithTitle:l10n_util::GetNSString(IDS_IOS_BOOKMARK_ACTION_SELECT) action:^{ [weakSelf selectFirstNode:node withCell:cell]; - weakSelf.get().actionSheetCoordinator = nil; + weakSelf.actionSheetCoordinator = nil; } style:UIAlertActionStyleDefault]; @@ -624,7 +617,7 @@ addItemWithTitle:l10n_util::GetNSString(IDS_IOS_BOOKMARK_ACTION_EDIT) action:^{ [weakSelf editNode:node]; - weakSelf.get().actionSheetCoordinator = nil; + weakSelf.actionSheetCoordinator = nil; } style:UIAlertActionStyleDefault]; @@ -635,7 +628,7 @@ std::set<const BookmarkNode*> nodes; nodes.insert(node); [weakSelf moveNodes:nodes]; - weakSelf.get().actionSheetCoordinator = nil; + weakSelf.actionSheetCoordinator = nil; } style:UIAlertActionStyleDefault]; @@ -646,7 +639,7 @@ std::set<const BookmarkNode*> nodes; nodes.insert(node); [weakSelf deleteNodes:nodes]; - weakSelf.get().actionSheetCoordinator = nil; + weakSelf.actionSheetCoordinator = nil; } style:UIAlertActionStyleDestructive]; @@ -654,7 +647,7 @@ [self.actionSheetCoordinator addItemWithTitle:l10n_util::GetNSString(IDS_CANCEL) action:^{ - weakSelf.get().actionSheetCoordinator = nil; + weakSelf.actionSheetCoordinator = nil; } style:UIAlertActionStyleCancel]; @@ -703,17 +696,16 @@ self.folderEditor = folderEditor; editorController = folderEditor; } else { - base::scoped_nsobject<BookmarkEditViewController> controller([ - [BookmarkEditViewController alloc] initWithBookmark:node - browserState:self.browserState]); + BookmarkEditViewController* controller = + [[BookmarkEditViewController alloc] initWithBookmark:node + browserState:self.browserState]; self.editViewController = controller; self.editViewController.delegate = self; editorController = self.editViewController; } DCHECK(editorController); - base::scoped_nsobject<UINavigationController> navController( - [[BookmarkNavigationController alloc] - initWithRootViewController:editorController]); + UINavigationController* navController = [[BookmarkNavigationController alloc] + initWithRootViewController:editorController]; [navController setModalPresentationStyle:UIModalPresentationFormSheet]; [self presentViewController:navController animated:YES completion:NULL]; } @@ -723,17 +715,15 @@ DCHECK(nodes.size() > 0); const BookmarkNode* editedNode = *(nodes.begin()); const BookmarkNode* selectedFolder = editedNode->parent(); - self.folderSelector = base::scoped_nsobject<BookmarkFolderViewController>( - [[BookmarkFolderViewController alloc] - initWithBookmarkModel:self.bookmarks - allowsNewFolders:YES - editedNodes:nodes - allowsCancel:YES - selectedFolder:selectedFolder]); + self.folderSelector = [[BookmarkFolderViewController alloc] + initWithBookmarkModel:self.bookmarks + allowsNewFolders:YES + editedNodes:nodes + allowsCancel:YES + selectedFolder:selectedFolder]; self.folderSelector.delegate = self; - base::scoped_nsobject<UINavigationController> navController( - [[BookmarkNavigationController alloc] - initWithRootViewController:self.folderSelector]); + UINavigationController* navController = [[BookmarkNavigationController alloc] + initWithRootViewController:self.folderSelector]; [navController setModalPresentationStyle:UIModalPresentationFormSheet]; [self presentViewController:navController animated:YES completion:NULL]; } @@ -898,9 +888,9 @@ folderEditor.delegate = self; self.folderEditor = folderEditor; - base::scoped_nsobject<BookmarkNavigationController> navController( + BookmarkNavigationController* navController = [[BookmarkNavigationController alloc] - initWithRootViewController:self.folderEditor]); + initWithRootViewController:self.folderEditor]; [navController setModalPresentationStyle:UIModalPresentationFormSheet]; [self presentViewController:navController animated:YES completion:NULL]; } @@ -1016,20 +1006,19 @@ return; DCHECK(self.waitForModelView); - base::WeakNSObject<BookmarkHomeHandsetViewController> weakSelf(self); + __weak BookmarkHomeHandsetViewController* weakSelf = self; [self.waitForModelView stopWaitingWithCompletion:^{ - base::scoped_nsobject<BookmarkHomeHandsetViewController> strongSelf( - [weakSelf retain]); + BookmarkHomeHandsetViewController* strongSelf = weakSelf; // Early return if the controller has been deallocated. if (!strongSelf) return; [UIView animateWithDuration:0.2 animations:^{ - strongSelf.get().waitForModelView.alpha = 0.0; + strongSelf.waitForModelView.alpha = 0.0; } completion:^(BOOL finished) { - [strongSelf.get().waitForModelView removeFromSuperview]; - strongSelf.get().waitForModelView = nil; + [strongSelf.waitForModelView removeFromSuperview]; + strongSelf.waitForModelView = nil; }]; [strongSelf loadBookmarkViews]; }];
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_home_tablet_ntp_controller.mm b/ios/chrome/browser/ui/bookmarks/bookmark_home_tablet_ntp_controller.mm index d2775972a..d4f8616 100644 --- a/ios/chrome/browser/ui/bookmarks/bookmark_home_tablet_ntp_controller.mm +++ b/ios/chrome/browser/ui/bookmarks/bookmark_home_tablet_ntp_controller.mm
@@ -7,10 +7,7 @@ #include <memory> #include "base/ios/block_types.h" -#import "base/ios/weak_nsobject.h" #include "base/logging.h" -#include "base/mac/objc_property_releaser.h" -#include "base/mac/scoped_nsobject.h" #include "base/metrics/user_metrics.h" #include "base/metrics/user_metrics_action.h" #include "base/strings/sys_string_conversions.h" @@ -46,6 +43,10 @@ #include "ui/base/l10n/l10n_util_mac.h" #include "ui/base/page_transition_types.h" +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + using bookmarks::BookmarkNode; namespace { @@ -61,7 +62,7 @@ @end @interface ContentView : UIView -@property(nonatomic, assign) id<ContentViewDelegate> delegate; +@property(nonatomic, weak) id<ContentViewDelegate> delegate; @end @implementation ContentView @@ -85,7 +86,7 @@ // Bridge to register for bookmark changes. std::unique_ptr<bookmarks::BookmarkModelBridge> _bridge; ios::ChromeBrowserState* _browserState; // Weak. - id<UrlLoader> _loader; // Weak. + __weak id<UrlLoader> _loader; // The following 2 ivars both represent the set of nodes being edited. // The set is for fast lookup. @@ -94,19 +95,16 @@ // DO NOT modify these two ivars directly. std::set<const BookmarkNode*> _editNodes; std::vector<const BookmarkNode*> _editNodesOrdered; - - base::mac::ObjCPropertyReleaser - _propertyReleaser_BookmarkHomeTabletNTPController; } -@property(nonatomic, retain) BookmarkPanelView* panelView; +@property(nonatomic, strong) BookmarkPanelView* panelView; #pragma mark - Properties and methods akin to BookmarkHomeViewController // Whether the view controller is in editing mode. @property(nonatomic, assign) BOOL editing; // The set of edited index paths. -@property(nonatomic, retain) NSMutableArray* editIndexPaths; +@property(nonatomic, strong) NSMutableArray* editIndexPaths; // The bookmark model used. @property(nonatomic, assign, readonly) bookmarks::BookmarkModel* bookmarks; // The user's browser state model used. @@ -128,44 +126,44 @@ // This views holds the primary content of this controller. At any point in // time, it contains exactly one of the BookmarkCollectionView subclasses. -@property(nonatomic, retain) ContentView* contentView; +@property(nonatomic, strong) ContentView* contentView; // The possible views that can be shown from the menu. -@property(nonatomic, retain) BookmarkFolderCollectionView* folderView; +@property(nonatomic, strong) BookmarkFolderCollectionView* folderView; // This view is created and used if the model is not fully loaded yet by the // time this controller starts. -@property(nonatomic, retain) BookmarkHomeWaitingView* waitForModelView; +@property(nonatomic, strong) BookmarkHomeWaitingView* waitForModelView; // The menu with all the folders and special entries. -@property(nonatomic, retain) BookmarkMenuView* menuView; +@property(nonatomic, strong) BookmarkMenuView* menuView; // At any point in time, there is exactly one collection view whose view is part // of the view hierarchy. This property determines which collection view is // visible. Not by accident, this property also reflects the selected menu item // in the BookmarkMenuView. -@property(nonatomic, retain) BookmarkMenuItem* primaryMenuItem; +@property(nonatomic, strong) BookmarkMenuItem* primaryMenuItem; // When the view is first shown on the screen, this property represents the // cached value of the y of the content offset of the primary view. This // property is set to nil after it is used. -@property(nonatomic, retain) +@property(nonatomic, strong) NSNumber* cachedContentPosition; // FIXME: INACTIVE // The navigation bar sits on top of the main content. -@property(nonatomic, retain) BookmarkNavigationBar* navigationBar; +@property(nonatomic, strong) BookmarkNavigationBar* navigationBar; // The editing bar present when items are selected. -@property(nonatomic, retain) BookmarkEditingBar* editingBar; +@property(nonatomic, strong) BookmarkEditingBar* editingBar; // The action sheet coordinator used when trying to edit a single bookmark. -@property(nonatomic, retain) ActionSheetCoordinator* actionSheetCoordinator; +@property(nonatomic, strong) ActionSheetCoordinator* actionSheetCoordinator; // The view controller used to view and edit a single bookmark. -@property(nonatomic, retain) BookmarkEditViewController* editViewController; +@property(nonatomic, strong) BookmarkEditViewController* editViewController; // The view controller used to pick a folder in which to move the selected // bookmarks. -@property(nonatomic, retain) BookmarkFolderViewController* folderSelector; +@property(nonatomic, strong) BookmarkFolderViewController* folderSelector; // The view controller to present when editing the current folder. -@property(nonatomic, retain) +@property(nonatomic, strong) BookmarkFolderEditorViewController* folderEditor; // FIX // The controller managing the display of the promo cell and the promo view // controller. -@property(nonatomic, retain) BookmarkPromoController* bookmarkPromoController; +@property(nonatomic, strong) BookmarkPromoController* bookmarkPromoController; #pragma mark Specific to this class. @@ -307,8 +305,6 @@ DCHECK(browserState); _browserState = browserState->GetOriginalChromeBrowserState(); _loader = loader; - _propertyReleaser_BookmarkHomeTabletNTPController.Init( - self, [BookmarkHomeTabletNTPController class]); _bookmarks = ios::BookmarkModelFactory::GetForBrowserState(_browserState); _bridge.reset(new bookmarks::BookmarkModelBridge(self, _bookmarks)); @@ -331,8 +327,6 @@ _editViewController.delegate = nil; _folderSelector.delegate = nil; - - [super dealloc]; } - (ios::ChromeBrowserState*)browserState { @@ -446,8 +440,8 @@ DCHECK(self.contentView); // Present a waiting view. - base::scoped_nsobject<BookmarkHomeWaitingView> waitingView( - [[BookmarkHomeWaitingView alloc] initWithFrame:self.view.bounds]); + BookmarkHomeWaitingView* waitingView = + [[BookmarkHomeWaitingView alloc] initWithFrame:self.view.bounds]; self.waitForModelView = waitingView; [self.view addSubview:self.waitForModelView]; [self.waitForModelView startWaiting]; @@ -467,10 +461,9 @@ LayoutRect menuLayout = LayoutRectMake(0, self.view.bounds.size.width, 0, self.menuWidth, self.view.bounds.size.height); - self.menuView = - base::scoped_nsobject<BookmarkMenuView>([[BookmarkMenuView alloc] - initWithBrowserState:self.browserState - frame:LayoutRectGetRect(menuLayout)]); + self.menuView = [[BookmarkMenuView alloc] + initWithBrowserState:self.browserState + frame:LayoutRectGetRect(menuLayout)]; self.menuView.delegate = self; self.menuView.autoresizingMask = UIViewAutoresizingFlexibleHeight; @@ -505,10 +498,9 @@ if (self.folderView) return; - base::scoped_nsobject<BookmarkFolderCollectionView> view( - [[BookmarkFolderCollectionView alloc] - initWithBrowserState:self.browserState - frame:CGRectZero]); + BookmarkFolderCollectionView* view = [[BookmarkFolderCollectionView alloc] + initWithBrowserState:self.browserState + frame:CGRectZero]; self.folderView = view; self.folderView.delegate = self; [self.folderView setEditing:self.editing animated:NO]; @@ -581,9 +573,9 @@ if ([self shouldPresentMenuInSlideInPanel]) { // Create (if needed), and add the panelView to the view hierarchy. if (!self.panelView) { - self.panelView = base::scoped_nsobject<BookmarkPanelView>( + self.panelView = [[BookmarkPanelView alloc] initWithFrame:CGRectZero - menuViewWidth:[self menuWidth]]); + menuViewWidth:[self menuWidth]]; } [self.view addSubview:self.panelView]; CGSize size = self.contentView.bounds.size; @@ -636,8 +628,8 @@ } if (!self.editingBar) { - self.editingBar = base::scoped_nsobject<BookmarkEditingBar>( - [[BookmarkEditingBar alloc] initWithFrame:[self editingBarFrame]]); + self.editingBar = + [[BookmarkEditingBar alloc] initWithFrame:[self editingBarFrame]]; [self.editingBar setCancelTarget:self action:@selector(editingBarCancel)]; [self.editingBar setDeleteTarget:self action:@selector(editingBarDelete)]; [self.editingBar setMoveTarget:self action:@selector(editingBarMove)]; @@ -821,20 +813,20 @@ forCell:(BookmarkItemCell*)cell { DCHECK(!self.editViewController); DCHECK(!self.actionSheetCoordinator); - self.actionSheetCoordinator = [[[ActionSheetCoordinator alloc] + self.actionSheetCoordinator = [[ActionSheetCoordinator alloc] initWithBaseViewController:self.view.window.rootViewController title:nil message:nil rect:view.bounds - view:view] autorelease]; - base::WeakNSObject<BookmarkHomeTabletNTPController> weakSelf(self); + view:view]; + __weak BookmarkHomeTabletNTPController* weakSelf = self; // Select action. [self.actionSheetCoordinator addItemWithTitle:l10n_util::GetNSString(IDS_IOS_BOOKMARK_ACTION_SELECT) action:^{ [weakSelf selectFirstNode:node withCell:cell]; - weakSelf.get().actionSheetCoordinator = nil; + weakSelf.actionSheetCoordinator = nil; } style:UIAlertActionStyleDefault]; @@ -846,7 +838,7 @@ if ([cell isKindOfClass:[BookmarkItemCell class]]) itemCell = static_cast<BookmarkItemCell*>(cell); [weakSelf editNode:node withCell:itemCell]; - weakSelf.get().actionSheetCoordinator = nil; + weakSelf.actionSheetCoordinator = nil; } style:UIAlertActionStyleDefault]; @@ -857,7 +849,7 @@ std::set<const BookmarkNode*> nodes; nodes.insert(node); [weakSelf moveNodes:nodes]; - weakSelf.get().actionSheetCoordinator = nil; + weakSelf.actionSheetCoordinator = nil; } style:UIAlertActionStyleDefault]; @@ -868,7 +860,7 @@ std::set<const BookmarkNode*> nodes; nodes.insert(node); [weakSelf deleteNodes:nodes]; - weakSelf.get().actionSheetCoordinator = nil; + weakSelf.actionSheetCoordinator = nil; } style:UIAlertActionStyleDestructive]; @@ -876,7 +868,7 @@ [self.actionSheetCoordinator addItemWithTitle:l10n_util::GetNSString(IDS_CANCEL) action:^{ - weakSelf.get().actionSheetCoordinator = nil; + weakSelf.actionSheetCoordinator = nil; } style:UIAlertActionStyleCancel]; @@ -926,18 +918,17 @@ self.folderEditor = folderEditor; editorController = folderEditor; } else { - base::scoped_nsobject<BookmarkEditViewController> controller([ - [BookmarkEditViewController alloc] initWithBookmark:node - browserState:self.browserState]); + BookmarkEditViewController* controller = + [[BookmarkEditViewController alloc] initWithBookmark:node + browserState:self.browserState]; self.editViewController = controller; self.editViewController.delegate = self; editorController = self.editViewController; } DCHECK(editorController); - base::scoped_nsobject<UINavigationController> navController( - [[BookmarkNavigationController alloc] - initWithRootViewController:editorController]); - navController.get().modalPresentationStyle = UIModalPresentationFormSheet; + UINavigationController* navController = [[BookmarkNavigationController alloc] + initWithRootViewController:editorController]; + navController.modalPresentationStyle = UIModalPresentationFormSheet; [self.view.window.rootViewController presentViewController:navController animated:YES completion:NULL]; @@ -948,18 +939,16 @@ DCHECK(nodes.size() > 0); const BookmarkNode* editedNode = *(nodes.begin()); const BookmarkNode* selectedFolder = editedNode->parent(); - self.folderSelector = base::scoped_nsobject<BookmarkFolderViewController>( - [[BookmarkFolderViewController alloc] - initWithBookmarkModel:self.bookmarks - allowsNewFolders:YES - editedNodes:nodes - allowsCancel:YES - selectedFolder:selectedFolder]); + self.folderSelector = [[BookmarkFolderViewController alloc] + initWithBookmarkModel:self.bookmarks + allowsNewFolders:YES + editedNodes:nodes + allowsCancel:YES + selectedFolder:selectedFolder]; self.folderSelector.delegate = self; - base::scoped_nsobject<UINavigationController> controller( - [[BookmarkNavigationController alloc] - initWithRootViewController:self.folderSelector]); - controller.get().modalPresentationStyle = UIModalPresentationFormSheet; + UINavigationController* controller = [[BookmarkNavigationController alloc] + initWithRootViewController:self.folderSelector]; + controller.modalPresentationStyle = UIModalPresentationFormSheet; [self.view.window.rootViewController presentViewController:controller animated:YES completion:NULL]; @@ -1140,10 +1129,10 @@ folderEditor.delegate = self; self.folderEditor = folderEditor; - base::scoped_nsobject<BookmarkNavigationController> navController( + BookmarkNavigationController* navController = [[BookmarkNavigationController alloc] - initWithRootViewController:self.folderEditor]); - navController.get().modalPresentationStyle = UIModalPresentationFormSheet; + initWithRootViewController:self.folderEditor]; + navController.modalPresentationStyle = UIModalPresentationFormSheet; [self.view.window.rootViewController presentViewController:navController animated:YES completion:NULL]; @@ -1198,8 +1187,8 @@ _contentView.delegate = self; self.contentView.backgroundColor = bookmark_utils_ios::mainBackgroundColor(); - base::scoped_nsobject<BookmarkNavigationBar> bar( - [[BookmarkNavigationBar alloc] initWithFrame:CGRectZero]); + BookmarkNavigationBar* bar = + [[BookmarkNavigationBar alloc] initWithFrame:CGRectZero]; self.navigationBar = bar; self.navigationBar.autoresizingMask = UIViewAutoresizingFlexibleWidth; @@ -1232,20 +1221,19 @@ return; DCHECK(self.waitForModelView); - base::WeakNSObject<BookmarkHomeTabletNTPController> weakSelf(self); + __weak BookmarkHomeTabletNTPController* weakSelf = self; [self.waitForModelView stopWaitingWithCompletion:^{ - base::scoped_nsobject<BookmarkHomeTabletNTPController> strongSelf( - [weakSelf retain]); + BookmarkHomeTabletNTPController* strongSelf = weakSelf; // Early return if the controller has been deallocated. if (!strongSelf) return; [UIView animateWithDuration:0.2 animations:^{ - strongSelf.get().waitForModelView.alpha = 0.0; + strongSelf.waitForModelView.alpha = 0.0; } completion:^(BOOL finished) { - [strongSelf.get().waitForModelView removeFromSuperview]; - strongSelf.get().waitForModelView = nil; + [strongSelf.waitForModelView removeFromSuperview]; + strongSelf.waitForModelView = nil; }]; [strongSelf loadBookmarkViews]; }];
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_utils_ios.h b/ios/chrome/browser/ui/bookmarks/bookmark_utils_ios.h index 0ebdfc8..24880a1 100644 --- a/ios/chrome/browser/ui/bookmarks/bookmark_utils_ios.h +++ b/ios/chrome/browser/ui/bookmarks/bookmark_utils_ios.h
@@ -185,7 +185,7 @@ // |model| must be loaded. // |item| and |position| are out variables, only populated if the return is YES. BOOL GetPositionCache(bookmarks::BookmarkModel* model, - BookmarkMenuItem** item, + BookmarkMenuItem* __autoreleasing* item, CGFloat* position); // Method exists for testing. void ClearPositionCache();
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_utils_ios.mm b/ios/chrome/browser/ui/bookmarks/bookmark_utils_ios.mm index 55f9d34..d3ecf12 100644 --- a/ios/chrome/browser/ui/bookmarks/bookmark_utils_ios.mm +++ b/ios/chrome/browser/ui/bookmarks/bookmark_utils_ios.mm
@@ -12,8 +12,6 @@ #include "base/hash.h" #include "base/i18n/string_compare.h" #include "base/mac/bind_objc_block.h" -#include "base/mac/scoped_nsautorelease_pool.h" -#include "base/mac/scoped_nsobject.h" #include "base/memory/ptr_util.h" #include "base/metrics/user_metrics_action.h" #include "base/strings/sys_string_conversions.h" @@ -36,6 +34,10 @@ #include "ui/base/l10n/l10n_util_mac.h" #include "ui/base/models/tree_node_iterator.h" +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + using bookmarks::BookmarkNode; namespace bookmark_utils_ios { @@ -187,8 +189,7 @@ UIView* dropShadowWithWidth(CGFloat width) { UIImage* shadowImage = [UIImage imageNamed:@"bookmark_bar_shadow"]; - UIImageView* shadow = - [[[UIImageView alloc] initWithImage:shadowImage] autorelease]; + UIImageView* shadow = [[UIImageView alloc] initWithImage:shadowImage]; CGRect shadowFrame = CGRectMake(0, 0, width, 4); shadow.frame = shadowFrame; shadow.autoresizingMask = @@ -225,8 +226,8 @@ } // Secondly, create an Undo group for all undoable actions. - base::scoped_nsobject<UndoManagerWrapper> wrapper( - [[UndoManagerWrapper alloc] initWithBrowserState:browser_state]); + UndoManagerWrapper* wrapper = + [[UndoManagerWrapper alloc] initWithBrowserState:browser_state]; // Create or update the bookmark. [wrapper startGroupingActions]; @@ -260,8 +261,7 @@ void PresentUndoToastWithWrapper(UndoManagerWrapper* wrapper, NSString* text) { // Create the block that will be executed if the user taps the undo button. - MDCSnackbarMessageAction* action = - [[[MDCSnackbarMessageAction alloc] init] autorelease]; + MDCSnackbarMessageAction* action = [[MDCSnackbarMessageAction alloc] init]; action.handler = ^{ if (![wrapper hasUndoManagerChanged]) [wrapper undo]; @@ -302,8 +302,8 @@ size_t nodeCount = nodes.size(); DCHECK_GT(nodeCount, 0u); - base::scoped_nsobject<UndoManagerWrapper> wrapper( - [[UndoManagerWrapper alloc] initWithBrowserState:browser_state]); + UndoManagerWrapper* wrapper = + [[UndoManagerWrapper alloc] initWithBrowserState:browser_state]; // Delete the selected bookmarks. [wrapper startGroupingActions]; @@ -354,8 +354,8 @@ size_t nodeCount = nodes.size(); DCHECK_GT(nodeCount, 0u); - base::scoped_nsobject<UndoManagerWrapper> wrapper( - [[UndoManagerWrapper alloc] initWithBrowserState:browser_state]); + UndoManagerWrapper* wrapper = + [[UndoManagerWrapper alloc] initWithBrowserState:browser_state]; // Move the selected bookmarks. [wrapper startGroupingActions]; @@ -404,38 +404,39 @@ nodesSectionVector.clear(); // Make a localized date formatter. - base::scoped_nsobject<NSDateFormatter> formatter( - [[NSDateFormatter alloc] init]); + NSDateFormatter* formatter = [[NSDateFormatter alloc] init]; [formatter setDateFormat:@"MMMM yyyy"]; // Segregate nodes by creation date. // Nodes that were created in the same month are grouped together. for (auto* node : vector) { - base::mac::ScopedNSAutoreleasePool pool; - base::Time dateAdded = node->date_added(); - base::TimeDelta delta = dateAdded - base::Time::UnixEpoch(); - base::scoped_nsobject<NSDate> date( - [[NSDate alloc] initWithTimeIntervalSince1970:delta.InSeconds()]); - NSString* dateString = [formatter stringFromDate:date]; - const std::string timeRepresentation = base::SysNSStringToUTF8(dateString); + @autoreleasepool { + base::Time dateAdded = node->date_added(); + base::TimeDelta delta = dateAdded - base::Time::UnixEpoch(); + NSDate* date = + [[NSDate alloc] initWithTimeIntervalSince1970:delta.InSeconds()]; + NSString* dateString = [formatter stringFromDate:date]; + const std::string timeRepresentation = + base::SysNSStringToUTF8(dateString); - BOOL found = NO; - for (const auto& nodesSection : nodesSectionVector) { - if (nodesSection->timeRepresentation == timeRepresentation) { - nodesSection->vector.push_back(node); - found = YES; - break; + BOOL found = NO; + for (const auto& nodesSection : nodesSectionVector) { + if (nodesSection->timeRepresentation == timeRepresentation) { + nodesSection->vector.push_back(node); + found = YES; + break; + } } + + if (found) + continue; + + // No NodesSection found. + auto nodesSection = base::MakeUnique<NodesSection>(); + nodesSection->time = dateAdded; + nodesSection->timeRepresentation = timeRepresentation; + nodesSection->vector.push_back(node); + nodesSectionVector.push_back(std::move(nodesSection)); } - - if (found) - continue; - - // No NodesSection found. - auto nodesSection = base::MakeUnique<NodesSection>(); - nodesSection->time = dateAdded; - nodesSection->timeRepresentation = timeRepresentation; - nodesSection->vector.push_back(node); - nodesSectionVector.push_back(std::move(nodesSection)); } // Sort the NodesSections.
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_utils_ios_unittest.mm b/ios/chrome/browser/ui/bookmarks/bookmark_utils_ios_unittest.mm index d9ec4ef..7edfa44 100644 --- a/ios/chrome/browser/ui/bookmarks/bookmark_utils_ios_unittest.mm +++ b/ios/chrome/browser/ui/bookmarks/bookmark_utils_ios_unittest.mm
@@ -15,6 +15,10 @@ #import "ios/chrome/browser/ui/bookmarks/bookmark_utils_ios.h" #include "testing/gtest_mac.h" +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + using bookmarks::BookmarkNode; namespace {
diff --git a/ios/chrome/browser/ui/reading_list/BUILD.gn b/ios/chrome/browser/ui/reading_list/BUILD.gn index e513818..f2f1b10 100644 --- a/ios/chrome/browser/ui/reading_list/BUILD.gn +++ b/ios/chrome/browser/ui/reading_list/BUILD.gn
@@ -39,6 +39,7 @@ "reading_list_collection_view_controller.mm", "reading_list_collection_view_item.h", "reading_list_collection_view_item.mm", + "reading_list_collection_view_item_accessibility_delegate.h", "reading_list_coordinator.h", "reading_list_coordinator.mm", "reading_list_empty_collection_background.h",
diff --git a/ios/chrome/browser/ui/reading_list/reading_list_collection_view_controller.mm b/ios/chrome/browser/ui/reading_list/reading_list_collection_view_controller.mm index 627c577..45ddedc 100644 --- a/ios/chrome/browser/ui/reading_list/reading_list_collection_view_controller.mm +++ b/ios/chrome/browser/ui/reading_list/reading_list_collection_view_controller.mm
@@ -25,10 +25,12 @@ #import "ios/chrome/browser/ui/favicon_view.h" #import "ios/chrome/browser/ui/material_components/utils.h" #import "ios/chrome/browser/ui/reading_list/reading_list_collection_view_item.h" +#import "ios/chrome/browser/ui/reading_list/reading_list_collection_view_item_accessibility_delegate.h" #import "ios/chrome/browser/ui/reading_list/reading_list_empty_collection_background.h" #import "ios/chrome/browser/ui/reading_list/reading_list_toolbar.h" #import "ios/chrome/browser/ui/uikit_ui_util.h" #include "ios/chrome/browser/ui/url_loader.h" +#import "ios/chrome/browser/ui/util/pasteboard_util.h" #include "ios/chrome/grit/ios_strings.h" #import "ios/third_party/material_components_ios/src/components/AppBar/src/MaterialAppBar.h" #import "ios/third_party/material_components_ios/src/components/Palettes/src/MaterialPalettes.h" @@ -65,7 +67,8 @@ } @interface ReadingListCollectionViewController ()< - ReadingListModelBridgeObserver> { + ReadingListModelBridgeObserver, + ReadingListCollectionViewItemAccessibilityDelegate> { // Toolbar with the actions. ReadingListToolbar* _toolbar; // Action sheet presenting the subactions of the toolbar. @@ -116,6 +119,10 @@ - (void)handleLongPress:(UILongPressGestureRecognizer*)gestureRecognizer; // Stops observing the ReadingListModel. - (void)stopObservingReadingListModel; +// Returns the ReadingListEntry associated with the |item|. If there is not such +// an entry, returns nullptr and reloads the UI. +- (const ReadingListEntry*)readingListEntryForItem: + (ReadingListCollectionViewItem*)item; // Updates the toolbar state according to the selected items. - (void)updateToolbarState; // Displays an action sheet to let the user choose to mark all the elements as @@ -134,7 +141,7 @@ - (void)markItemsUnreadAtIndexPath:(NSArray*)indexPaths; // Deletes all the read items. - (void)deleteAllReadItems; -// Deletes all the items at |indexPaths|. +// Deletes all the items at |indexPath|. - (void)deleteItemsAtIndexPaths:(NSArray*)indexPaths; // Initializes |_actionSheet| with |self| as base view controller, and the // toolbar's mark button as anchor point. @@ -392,6 +399,100 @@ [_actionSheet stop]; } +#pragma mark - ReadingListCollectionViewItemAccessibilityDelegate + +- (BOOL)isEntryRead:(ReadingListCollectionViewItem*)entry { + const ReadingListEntry* readingListEntry = + [self readingListEntryForItem:entry]; + + if (!readingListEntry) { + return NO; + } + + return readingListEntry->IsRead(); +} + +- (void)deleteEntry:(ReadingListCollectionViewItem*)entry { + const ReadingListEntry* readingListEntry = + [self readingListEntryForItem:entry]; + + if (!readingListEntry) { + return; + } + + SectionIdentifier sectionIdentifier = SectionIdentifierUnread; + if (readingListEntry->IsRead()) { + sectionIdentifier = SectionIdentifierRead; + } + if (![self.collectionViewModel hasItem:entry + inSectionWithIdentifier:sectionIdentifier]) { + return; + } + + [self + deleteItemsAtIndexPaths:@[ [self.collectionViewModel + indexPathForItem:entry + inSectionWithIdentifier:sectionIdentifier] ]]; +} + +- (void)openEntryInNewTab:(ReadingListCollectionViewItem*)entry { + [self.delegate readingListCollectionViewController:self + openNewTabWithURL:entry.url + incognito:NO]; +} + +- (void)openEntryInNewIncognitoTab:(ReadingListCollectionViewItem*)entry { + [self.delegate readingListCollectionViewController:self + openNewTabWithURL:entry.url + incognito:YES]; +} + +- (void)copyEntryURL:(ReadingListCollectionViewItem*)entry { + StoreURLInPasteboard(entry.url); +} + +- (void)openEntryOffline:(ReadingListCollectionViewItem*)entry { + const ReadingListEntry* readingListEntry = + [self readingListEntryForItem:entry]; + + if (!readingListEntry) { + return; + } + + if (readingListEntry->DistilledState() == ReadingListEntry::PROCESSED) { + const GURL entryURL = readingListEntry->URL(); + GURL offlineURL = reading_list::OfflineURLForPath( + readingListEntry->DistilledPath(), entryURL, + readingListEntry->DistilledURL()); + + [self.delegate readingListCollectionViewController:self + openOfflineURL:offlineURL + correspondingEntryURL:entryURL]; + } +} + +- (void)markEntryRead:(ReadingListCollectionViewItem*)entry { + if (![self.collectionViewModel hasItem:entry + inSectionWithIdentifier:SectionIdentifierUnread]) { + return; + } + [self markItemsReadAtIndexPath:@[ + [self.collectionViewModel indexPathForItem:entry + inSectionWithIdentifier:SectionIdentifierUnread] + ]]; +} + +- (void)markEntryUnread:(ReadingListCollectionViewItem*)entry { + if (![self.collectionViewModel hasItem:entry + inSectionWithIdentifier:SectionIdentifierRead]) { + return; + } + [self markItemsUnreadAtIndexPath:@[ + [self.collectionViewModel indexPathForItem:entry + inSectionWithIdentifier:SectionIdentifierRead] + ]]; +} + #pragma mark - Private methods - (void)donePressed { @@ -451,6 +552,7 @@ const ReadingListEntry* entry = self.readingListModel->GetEntryByURL(url); ReadingListCollectionViewItem* item = [self cellItemForReadingListEntry:*entry]; + item.accessibilityDelegate = self; if (entry->IsRead()) { read_map.insert(std::make_pair(entry->UpdateTime(), item)); } else { @@ -588,6 +690,20 @@ _modelBridge.reset(); } +- (const ReadingListEntry*)readingListEntryForItem: + (ReadingListCollectionViewItem*)item { + const ReadingListEntry* readingListEntry = + self.readingListModel->GetEntryByURL(item.url); + + if (!readingListEntry) { + // The entry has been removed from the model, reload all data to synchronize + // the UI with the model. + [self reloadData]; + } + + return readingListEntry; +} + #pragma mark - ReadingListToolbarDelegate - (void)markPressed {
diff --git a/ios/chrome/browser/ui/reading_list/reading_list_collection_view_item.h b/ios/chrome/browser/ui/reading_list/reading_list_collection_view_item.h index 7adba7c..38e9434 100644 --- a/ios/chrome/browser/ui/reading_list/reading_list_collection_view_item.h +++ b/ios/chrome/browser/ui/reading_list/reading_list_collection_view_item.h
@@ -11,6 +11,7 @@ #import "ios/third_party/material_components_ios/src/components/CollectionCells/src/MaterialCollectionCells.h" class GURL; +@protocol ReadingListCollectionViewItemAccessibilityDelegate; // Collection view item for representing a ReadingListEntry. @interface ReadingListCollectionViewItem : CollectionViewItem @@ -26,6 +27,10 @@ // Status of the offline version. @property(nonatomic, assign) ReadingListEntry::DistillationState distillationState; +// Delegate for the accessibility actions. +@property(nonatomic, weak) + id<ReadingListCollectionViewItemAccessibilityDelegate> + accessibilityDelegate; // Designated initializer. The |provider| will be used for loading favicon // attributes. The |delegate| is used to inform about changes to this item. The
diff --git a/ios/chrome/browser/ui/reading_list/reading_list_collection_view_item.mm b/ios/chrome/browser/ui/reading_list/reading_list_collection_view_item.mm index 9618ce4..b488546 100644 --- a/ios/chrome/browser/ui/reading_list/reading_list_collection_view_item.mm +++ b/ios/chrome/browser/ui/reading_list/reading_list_collection_view_item.mm
@@ -7,6 +7,7 @@ #include "base/strings/sys_string_conversions.h" #import "ios/chrome/browser/ui/colors/MDCPalette+CrAdditions.h" #import "ios/chrome/browser/ui/favicon_view.h" +#import "ios/chrome/browser/ui/reading_list/reading_list_collection_view_item_accessibility_delegate.h" #import "ios/chrome/browser/ui/uikit_ui_util.h" #include "ios/chrome/grit/ios_strings.h" #import "ios/third_party/material_components_ios/src/components/Palettes/src/MaterialPalettes.h" @@ -59,6 +60,10 @@ // The cell that is displaying this item, if any. Used to reload favicon when // the cell is on screen. Backed by WeakNSObject. @property(nonatomic, weak) ReadingListCell* displayedCell; + +// Returns the accessibility custom actions associated with this item. +- (NSArray<UIAccessibilityCustomAction*>*)customActions; + @end @implementation ReadingListCollectionViewItem @@ -70,6 +75,7 @@ @synthesize faviconPageURL = _faviconPageURL; @synthesize displayedCell = _displayedCell; @synthesize distillationState = _distillationState; +@synthesize accessibilityDelegate = _accessibilityDelegate; - (instancetype)initWithType:(NSInteger)type attributesProvider:(FaviconAttributesProvider*)provider @@ -111,6 +117,7 @@ (ReadingListEntry::DistillationState)distillationState { self.displayedCell.distillationState = distillationState; self.displayedCell.accessibilityLabel = [self accessibilityLabel]; + self.displayedCell.accessibilityCustomActions = [self customActions]; _distillationState = distillationState; } @@ -128,6 +135,7 @@ cell.distillationState = _distillationState; cell.isAccessibilityElement = YES; cell.accessibilityLabel = [self accessibilityLabel]; + cell.accessibilityCustomActions = [self customActions]; } #pragma mark - ReadingListCellDelegate @@ -154,6 +162,102 @@ base::SysNSStringToUTF16(self.detailText)); } +#pragma mark - AccessibilityCustomAction + +- (NSArray<UIAccessibilityCustomAction*>*)customActions { + UIAccessibilityCustomAction* deleteAction = [ + [UIAccessibilityCustomAction alloc] + initWithName:l10n_util::GetNSString(IDS_IOS_READING_LIST_DELETE_BUTTON) + target:self + selector:@selector(deleteEntry)]; + UIAccessibilityCustomAction* toogleReadStatus = nil; + if ([self.accessibilityDelegate isEntryRead:self]) { + toogleReadStatus = [[UIAccessibilityCustomAction alloc] + initWithName:l10n_util::GetNSString( + IDS_IOS_READING_LIST_MARK_UNREAD_BUTTON) + target:self + selector:@selector(markUnread)]; + } else { + toogleReadStatus = [[UIAccessibilityCustomAction alloc] + initWithName:l10n_util::GetNSString( + IDS_IOS_READING_LIST_MARK_READ_BUTTON) + target:self + selector:@selector(markRead)]; + } + + UIAccessibilityCustomAction* openInNewTabAction = + [[UIAccessibilityCustomAction alloc] + initWithName:l10n_util::GetNSString( + IDS_IOS_CONTENT_CONTEXT_OPENLINKNEWTAB) + target:self + selector:@selector(openInNewTab)]; + UIAccessibilityCustomAction* openInNewIncognitoTabAction = + [[UIAccessibilityCustomAction alloc] + initWithName:l10n_util::GetNSString( + IDS_IOS_CONTENT_CONTEXT_OPENLINKNEWINCOGNITOTAB) + target:self + selector:@selector(openInNewIncognitoTab)]; + UIAccessibilityCustomAction* copyURLAction = + [[UIAccessibilityCustomAction alloc] + initWithName:l10n_util::GetNSString(IDS_IOS_CONTENT_CONTEXT_COPY) + target:self + selector:@selector(copyURL)]; + + NSMutableArray* customActions = [NSMutableArray + arrayWithObjects:deleteAction, toogleReadStatus, openInNewTabAction, + openInNewIncognitoTabAction, copyURLAction, nil]; + + if (self.distillationState == ReadingListEntry::PROCESSED) { + // Add the possibility to open offline version only if the entry is + // distilled. + UIAccessibilityCustomAction* openOfflineAction = + [[UIAccessibilityCustomAction alloc] + initWithName:l10n_util::GetNSString( + IDS_IOS_READING_LIST_CONTENT_CONTEXT_OFFLINE) + target:self + selector:@selector(openOffline)]; + + [customActions addObject:openOfflineAction]; + } + + return customActions; +} + +- (BOOL)deleteEntry { + [self.accessibilityDelegate deleteEntry:self]; + return YES; +} + +- (BOOL)markRead { + [self.accessibilityDelegate markEntryRead:self]; + return YES; +} + +- (BOOL)markUnread { + [self.accessibilityDelegate markEntryUnread:self]; + return YES; +} + +- (BOOL)openInNewTab { + [self.accessibilityDelegate openEntryInNewTab:self]; + return YES; +} + +- (BOOL)openInNewIncognitoTab { + [self.accessibilityDelegate openEntryInNewIncognitoTab:self]; + return YES; +} + +- (BOOL)copyURL { + [self.accessibilityDelegate copyEntryURL:self]; + return YES; +} + +- (BOOL)openOffline { + [self.accessibilityDelegate openEntryOffline:self]; + return YES; +} + #pragma mark - NSObject - (NSString*)description { @@ -281,6 +385,7 @@ self.textLabel.text = nil; self.detailTextLabel.text = nil; self.distillationState = ReadingListEntry::WAITING; + self.accessibilityCustomActions = nil; [super prepareForReuse]; }
diff --git a/ios/chrome/browser/ui/reading_list/reading_list_collection_view_item_accessibility_delegate.h b/ios/chrome/browser/ui/reading_list/reading_list_collection_view_item_accessibility_delegate.h new file mode 100644 index 0000000..a9e04a2e --- /dev/null +++ b/ios/chrome/browser/ui/reading_list/reading_list_collection_view_item_accessibility_delegate.h
@@ -0,0 +1,25 @@ +// 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 IOS_CHROME_BROWSER_UI_READING_LIST_READING_LIST_COLLECTION_VIEW_ITEM_ACCESSIBILITY_DELEGATE_H_ +#define IOS_CHROME_BROWSER_UI_READING_LIST_READING_LIST_COLLECTION_VIEW_ITEM_ACCESSIBILITY_DELEGATE_H_ + +@class ReadingListCollectionViewItem; + +@protocol ReadingListCollectionViewItemAccessibilityDelegate + +// Returns whether the entry is read. +- (BOOL)isEntryRead:(ReadingListCollectionViewItem*)entry; + +- (void)deleteEntry:(ReadingListCollectionViewItem*)entry; +- (void)openEntryInNewTab:(ReadingListCollectionViewItem*)entry; +- (void)openEntryInNewIncognitoTab:(ReadingListCollectionViewItem*)entry; +- (void)copyEntryURL:(ReadingListCollectionViewItem*)entry; +- (void)openEntryOffline:(ReadingListCollectionViewItem*)entry; +- (void)markEntryRead:(ReadingListCollectionViewItem*)entry; +- (void)markEntryUnread:(ReadingListCollectionViewItem*)entry; + +@end + +#endif // IOS_CHROME_BROWSER_UI_READING_LIST_READING_LIST_COLLECTION_VIEW_ITEM_ACCESSIBILITY_DELEGATE_H_
diff --git a/ios/chrome/browser/ui/webui/physical_web_ui.cc b/ios/chrome/browser/ui/webui/physical_web_ui.cc index 98a5ccef..6a8b7d4 100644 --- a/ios/chrome/browser/ui/webui/physical_web_ui.cc +++ b/ios/chrome/browser/ui/webui/physical_web_ui.cc
@@ -28,7 +28,8 @@ // Localized and data strings. html_source->AddLocalizedString(physical_web_ui::kTitle, IDS_PHYSICAL_WEB_UI_TITLE); - + html_source->AddLocalizedString(physical_web_ui::kEmptyMessage, + IDS_PHYSICAL_WEB_UI_EMPTY_MESSAGE); html_source->SetJsonPath("strings.js"); html_source->AddResourcePath(physical_web_ui::kPhysicalWebJS, IDR_PHYSICAL_WEB_UI_JS);
diff --git a/ios/clean/chrome/browser/browser_coordinator+internal.h b/ios/clean/chrome/browser/browser_coordinator+internal.h index 0fdec93..06315554a 100644 --- a/ios/clean/chrome/browser/browser_coordinator+internal.h +++ b/ios/clean/chrome/browser/browser_coordinator+internal.h
@@ -55,6 +55,16 @@ // |coordinator| isn't a child of the receiver, this method does nothing. - (void)removeChildCoordinator:(BrowserCoordinator*)coordinator; +// Called when a child coordinator did start. This is a blank template method. +// Subclasses can override this method when they need to know when their +// children start. +- (void)childCoordinatorDidStart:(BrowserCoordinator*)childCoordinator; + +// Called when a child coordinator will stop. This is a blank template method. +// Subclasses can override this method when they need to know when their +// children start. +- (void)childCoordinatorWillStop:(BrowserCoordinator*)childCoordinator; + // Methods for adding overlay coordinators. // Returns YES if the receiver will take |overlayCoordinator| as a child.
diff --git a/ios/clean/chrome/browser/browser_coordinator.h b/ios/clean/chrome/browser/browser_coordinator.h index 6b06543..0cb5aeea0 100644 --- a/ios/clean/chrome/browser/browser_coordinator.h +++ b/ios/clean/chrome/browser/browser_coordinator.h
@@ -30,15 +30,19 @@ @property(nonatomic, assign) Browser* browser; // The basic lifecycle methods for coordinators are -start and -stop. These -// are blank template methods; child classes are expected to implement them and -// do not need to invoke the superclass methods. +// implementations only notify the parent coordinator when this coordinator did +// start and will stop. Child classes are expected to override and call the +// superclass method at the end of -start and at the beginning of -stop. + // Starts the user interaction managed by the receiver. Typical implementations // will create a view controller and then use |baseViewController| to present -// it. -- (void)start; +// it. This method needs to be called at the end of the overriding +// implementation. +- (void)start NS_REQUIRES_SUPER; -// Stops the user interaction managed by the receiver. -- (void)stop; +// Stops the user interaction managed by the receiver. This method needs to be +// called at the beginning of the overriding implementation. +- (void)stop NS_REQUIRES_SUPER; @end
diff --git a/ios/clean/chrome/browser/browser_coordinator.mm b/ios/clean/chrome/browser/browser_coordinator.mm index 4c7af01..828ae8d 100644 --- a/ios/clean/chrome/browser/browser_coordinator.mm +++ b/ios/clean/chrome/browser/browser_coordinator.mm
@@ -43,11 +43,11 @@ #pragma mark - Public API - (void)start { - // Default implementation is a no-op. + [self.parentCoordinator childCoordinatorDidStart:self]; } - (void)stop { - // Default implementation is a no-op. + [self.parentCoordinator childCoordinatorWillStop:self]; } @end @@ -122,4 +122,12 @@ coordinator.parentCoordinator = nil; } +- (void)childCoordinatorDidStart:(BrowserCoordinator*)childCoordinator { + // Default implementation is a no-op. +} + +- (void)childCoordinatorWillStop:(BrowserCoordinator*)childCoordinator { + // Default implementation is a no-op. +} + @end
diff --git a/ios/clean/chrome/browser/browser_coordinator_unittest.mm b/ios/clean/chrome/browser/browser_coordinator_unittest.mm index 54fbd76..88f0186 100644 --- a/ios/clean/chrome/browser/browser_coordinator_unittest.mm +++ b/ios/clean/chrome/browser/browser_coordinator_unittest.mm
@@ -31,6 +31,7 @@ } - (void)stop { + [super stop]; if (self.stopHandler) self.stopHandler(); }
diff --git a/ios/clean/chrome/browser/ui/commands/BUILD.gn b/ios/clean/chrome/browser/ui/commands/BUILD.gn index 8b12cb4..6ad215d 100644 --- a/ios/clean/chrome/browser/ui/commands/BUILD.gn +++ b/ios/clean/chrome/browser/ui/commands/BUILD.gn
@@ -4,11 +4,30 @@ source_set("commands") { sources = [ + "command_dispatcher.h", + "command_dispatcher.mm", "settings_commands.h", "tab_commands.h", "tab_grid_commands.h", "toolbar_commands.h", ] + deps = [ + "//base", + ] + + configs += [ "//build/config/compiler:enable_arc" ] +} + +source_set("unit_tests") { + testonly = true + sources = [ + "command_dispatcher_unittest.mm", + ] + deps = [ + ":commands", + "//base", + "//testing/gtest", + ] configs += [ "//build/config/compiler:enable_arc" ] }
diff --git a/ios/clean/chrome/browser/ui/commands/command_dispatcher.h b/ios/clean/chrome/browser/ui/commands/command_dispatcher.h new file mode 100644 index 0000000..753542f --- /dev/null +++ b/ios/clean/chrome/browser/ui/commands/command_dispatcher.h
@@ -0,0 +1,24 @@ +// 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 IOS_CLEAN_CHROME_BROWSER_UI_COMMANDS_COMMAND_DISPATCHER_H_ +#define IOS_CLEAN_CHROME_BROWSER_UI_COMMANDS_COMMAND_DISPATCHER_H_ + +#import <Foundation/Foundation.h> + +// CommandDispatcher allows coordinators to register as command handlers for +// specific selectors. Other objects can call these methods on the dispatcher, +// which in turn will forward the call to the registered handler. +@interface CommandDispatcher : NSObject + +// Registers the given |target| to receive forwarded messages for the given +// |selector|. +- (void)registerTarget:(id)target forSelector:(SEL)selector; + +// Removes all forwarding registrations for the given |target|. +- (void)stopDispatchingForTarget:(id)target; + +@end + +#endif // IOS_CLEAN_CHROME_BROWSER_UI_COMMANDS_COMMAND_DISPATCHER_H_
diff --git a/ios/clean/chrome/browser/ui/commands/command_dispatcher.mm b/ios/clean/chrome/browser/ui/commands/command_dispatcher.mm new file mode 100644 index 0000000..23133a3 --- /dev/null +++ b/ios/clean/chrome/browser/ui/commands/command_dispatcher.mm
@@ -0,0 +1,55 @@ +// 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. + +#import "ios/clean/chrome/browser/ui/commands/command_dispatcher.h" + +#include <unordered_map> +#include <vector> + +#include "base/logging.h" +#include "base/strings/sys_string_conversions.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +@implementation CommandDispatcher { + // Stores which target to forward to for a given selector. + std::unordered_map<SEL, __weak id> _forwardingTargets; +} + +- (void)registerTarget:(id)target forSelector:(SEL)selector { + DCHECK(_forwardingTargets.find(selector) == _forwardingTargets.end()); + + _forwardingTargets[selector] = target; +} + +// |-stopDispatchingForTarget| should be called much less often than +// |-forwardingTargetForSelector|, so removal is intentionally O(n) in order +// to prioritize the speed of lookups. +- (void)stopDispatchingForTarget:(id)target { + std::vector<SEL> selectorsToErase; + for (auto& kv : _forwardingTargets) { + if (kv.second == target) { + selectorsToErase.push_back(kv.first); + } + } + + for (auto* selector : selectorsToErase) { + _forwardingTargets.erase(selector); + } +} + +#pragma mark - NSObject + +// Overridden to forward messages to registered handlers. +- (id)forwardingTargetForSelector:(SEL)selector { + auto target = _forwardingTargets.find(selector); + if (target != _forwardingTargets.end()) { + return target->second; + } + return [super forwardingTargetForSelector:selector]; +} + +@end
diff --git a/ios/clean/chrome/browser/ui/commands/command_dispatcher_unittest.mm b/ios/clean/chrome/browser/ui/commands/command_dispatcher_unittest.mm new file mode 100644 index 0000000..3154e53 --- /dev/null +++ b/ios/clean/chrome/browser/ui/commands/command_dispatcher_unittest.mm
@@ -0,0 +1,233 @@ +// 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. + +#import "ios/clean/chrome/browser/ui/commands/command_dispatcher.h" + +#import <Foundation/Foundation.h> + +#include "base/macros.h" +#include "testing/gtest/include/gtest/gtest.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +#pragma mark - Test handlers + +// A handler with methods that take no arguments. +@interface CommandDispatcherTestSimpleTarget : NSObject + +// Will be set to YES when the |-show| method is called. +@property(nonatomic, assign) BOOL showCalled; + +// Will be set to YES when the |-hide| method is called. +@property(nonatomic, assign) BOOL hideCalled; + +// Resets the above properties to NO. +- (void)resetProperties; + +// Handler methods. +- (void)show; +- (void)hide; + +@end + +@implementation CommandDispatcherTestSimpleTarget + +@synthesize showCalled = _showCalled; +@synthesize hideCalled = _hideCalled; + +- (void)resetProperties { + self.showCalled = NO; + self.hideCalled = NO; +} + +- (void)show { + self.showCalled = YES; +} + +- (void)hide { + self.hideCalled = YES; +} + +@end + +// A handler with methods that take various types of arguments. +@interface CommandDispatcherTestTargetWithArguments : NSObject + +// Set to YES when |-methodWithInt:| is called. +@property(nonatomic, assign) BOOL intMethodCalled; + +// The argument passed to the most recent call of |-methodWithInt:|. +@property(nonatomic, assign) int intArgument; + +// Set to YES when |-methodWithObject:| is called. +@property(nonatomic, assign) BOOL objectMethodCalled; + +// The argument passed to the most recent call of |-methodWithObject:|. +@property(nonatomic, strong) NSObject* objectArgument; + +// Resets the above properties to NO or nil. +- (void)resetProperties; + +// Handler methods. +- (void)methodWithInt:(int)arg; +- (void)methodWithObject:(NSObject*)arg; +- (int)methodToAddFirstArgument:(int)first toSecond:(int)second; + +@end + +@implementation CommandDispatcherTestTargetWithArguments + +@synthesize intMethodCalled = _intMethodCalled; +@synthesize intArgument = _intArgument; +@synthesize objectMethodCalled = _objectMethodCalled; +@synthesize objectArgument = _objectArgument; + +- (void)resetProperties { + self.intMethodCalled = NO; + self.intArgument = 0; + self.objectMethodCalled = NO; + self.objectArgument = nil; +} + +- (void)methodWithInt:(int)arg { + self.intMethodCalled = YES; + self.intArgument = arg; +} + +- (void)methodWithObject:(NSObject*)arg { + self.objectMethodCalled = YES; + self.objectArgument = arg; +} + +- (int)methodToAddFirstArgument:(int)first toSecond:(int)second { + return first + second; +} + +@end + +#pragma mark - Tests + +// Tests handler methods with no arguments. +TEST(CommandDispatcherTest, SimpleTarget) { + id dispatcher = [[CommandDispatcher alloc] init]; + CommandDispatcherTestSimpleTarget* target = + [[CommandDispatcherTestSimpleTarget alloc] init]; + + [dispatcher registerTarget:target forSelector:@selector(show)]; + [dispatcher registerTarget:target forSelector:@selector(hide)]; + + [dispatcher show]; + EXPECT_TRUE(target.showCalled); + EXPECT_FALSE(target.hideCalled); + + [target resetProperties]; + [dispatcher hide]; + EXPECT_FALSE(target.showCalled); + EXPECT_TRUE(target.hideCalled); +} + +// Tests handler methods that take arguments. +TEST(CommandDispatcherTest, TargetWithArguments) { + id dispatcher = [[CommandDispatcher alloc] init]; + CommandDispatcherTestTargetWithArguments* target = + [[CommandDispatcherTestTargetWithArguments alloc] init]; + + [dispatcher registerTarget:target forSelector:@selector(methodWithInt:)]; + [dispatcher registerTarget:target forSelector:@selector(methodWithObject:)]; + [dispatcher registerTarget:target + forSelector:@selector(methodToAddFirstArgument:toSecond:)]; + + const int int_argument = 4; + [dispatcher methodWithInt:int_argument]; + EXPECT_TRUE(target.intMethodCalled); + EXPECT_FALSE(target.objectMethodCalled); + EXPECT_EQ(int_argument, target.intArgument); + + [target resetProperties]; + NSObject* object_argument = [[NSObject alloc] init]; + [dispatcher methodWithObject:object_argument]; + EXPECT_FALSE(target.intMethodCalled); + EXPECT_TRUE(target.objectMethodCalled); + EXPECT_EQ(object_argument, target.objectArgument); + + [target resetProperties]; + EXPECT_EQ(13, [dispatcher methodToAddFirstArgument:7 toSecond:6]); + EXPECT_FALSE(target.intMethodCalled); + EXPECT_FALSE(target.objectMethodCalled); + EXPECT_EQ(42, [dispatcher methodToAddFirstArgument:34 toSecond:8]); +} + +// Tests that messages are routed to the proper handler when multiple targets +// are registered. +TEST(CommandDispatcherTest, MultipleTargets) { + id dispatcher = [[CommandDispatcher alloc] init]; + CommandDispatcherTestSimpleTarget* showTarget = + [[CommandDispatcherTestSimpleTarget alloc] init]; + CommandDispatcherTestSimpleTarget* hideTarget = + [[CommandDispatcherTestSimpleTarget alloc] init]; + + [dispatcher registerTarget:showTarget forSelector:@selector(show)]; + [dispatcher registerTarget:hideTarget forSelector:@selector(hide)]; + + [dispatcher show]; + EXPECT_TRUE(showTarget.showCalled); + EXPECT_FALSE(hideTarget.showCalled); + + [showTarget resetProperties]; + [dispatcher hide]; + EXPECT_FALSE(showTarget.hideCalled); + EXPECT_TRUE(hideTarget.hideCalled); +} + +// Tests that handlers are no longer forwarded messages after deregistration. +TEST(CommandDispatcherTest, Deregistration) { + id dispatcher = [[CommandDispatcher alloc] init]; + CommandDispatcherTestSimpleTarget* showTarget = + [[CommandDispatcherTestSimpleTarget alloc] init]; + CommandDispatcherTestSimpleTarget* hideTarget = + [[CommandDispatcherTestSimpleTarget alloc] init]; + + [dispatcher registerTarget:showTarget forSelector:@selector(show)]; + [dispatcher registerTarget:hideTarget forSelector:@selector(hide)]; + + [dispatcher show]; + EXPECT_TRUE(showTarget.showCalled); + EXPECT_FALSE(hideTarget.showCalled); + + [dispatcher stopDispatchingForTarget:showTarget]; + bool exception_caught = false; + @try { + [dispatcher show]; + } @catch (NSException* exception) { + EXPECT_EQ(NSInvalidArgumentException, [exception name]); + exception_caught = true; + } + EXPECT_TRUE(exception_caught); + + [dispatcher hide]; + EXPECT_FALSE(showTarget.hideCalled); + EXPECT_TRUE(hideTarget.hideCalled); +} + +// Tests that an exception is thrown when there is no registered handler for a +// given selector. +TEST(CommandDispatcherTest, NoTargetRegisteredForSelector) { + id dispatcher = [[CommandDispatcher alloc] init]; + CommandDispatcherTestSimpleTarget* target = + [[CommandDispatcherTestSimpleTarget alloc] init]; + + [dispatcher registerTarget:target forSelector:@selector(show)]; + + bool exception_caught = false; + @try { + [dispatcher hide]; + } @catch (NSException* exception) { + EXPECT_EQ(NSInvalidArgumentException, [exception name]); + exception_caught = true; + } + + EXPECT_TRUE(exception_caught); +}
diff --git a/ios/clean/chrome/browser/ui/ntp/new_tab_page_coordinator.mm b/ios/clean/chrome/browser/ui/ntp/new_tab_page_coordinator.mm index 4e61776..3be9962 100644 --- a/ios/clean/chrome/browser/ui/ntp/new_tab_page_coordinator.mm +++ b/ios/clean/chrome/browser/ui/ntp/new_tab_page_coordinator.mm
@@ -23,6 +23,7 @@ [self.context.baseViewController presentViewController:self.viewController animated:self.context.animated completion:nil]; + [super start]; } @end
diff --git a/ios/clean/chrome/browser/ui/settings/settings_coordinator.mm b/ios/clean/chrome/browser/ui/settings/settings_coordinator.mm index 536bebce..46a0fc98 100644 --- a/ios/clean/chrome/browser/ui/settings/settings_coordinator.mm +++ b/ios/clean/chrome/browser/ui/settings/settings_coordinator.mm
@@ -38,9 +38,11 @@ [self.context.baseViewController presentViewController:self.viewController animated:self.context.animated completion:nil]; + [super start]; } - (void)stop { + [super stop]; [self.viewController.presentingViewController dismissViewControllerAnimated:self.context.animated completion:nil];
diff --git a/ios/clean/chrome/browser/ui/tab/tab_coordinator.mm b/ios/clean/chrome/browser/ui/tab/tab_coordinator.mm index 3ccbaa6..a8219710 100644 --- a/ios/clean/chrome/browser/ui/tab/tab_coordinator.mm +++ b/ios/clean/chrome/browser/ui/tab/tab_coordinator.mm
@@ -71,9 +71,6 @@ toolbarCoordinator.context.baseViewController = nil; [toolbarCoordinator start]; - self.viewController.toolbarViewController = toolbarCoordinator.viewController; - self.viewController.contentViewController = webCoordinator.viewController; - // PLACEHOLDER: Replace this placeholder with an actual tab strip view // controller. UIButton* button = [UIButton buttonWithType:UIButtonTypeCustom]; @@ -91,15 +88,25 @@ [self.context.baseViewController presentViewController:self.viewController animated:self.context.animated completion:nil]; + [super start]; } - (void)stop { + [super stop]; [self.viewController.presentingViewController dismissViewControllerAnimated:self.context.animated completion:nil]; _webStateObserver.reset(); } +- (void)childCoordinatorDidStart:(BrowserCoordinator*)coordinator { + if ([coordinator isKindOfClass:[ToolbarCoordinator class]]) { + self.viewController.toolbarViewController = coordinator.viewController; + } else if ([coordinator isKindOfClass:[WebCoordinator class]]) { + self.viewController.contentViewController = coordinator.viewController; + } +} + - (BOOL)canAddOverlayCoordinator:(BrowserCoordinator*)overlayCoordinator { // This coordinator will always accept overlay coordinators. return YES;
diff --git a/ios/clean/chrome/browser/ui/tab_grid/tab_grid_coordinator.mm b/ios/clean/chrome/browser/ui/tab_grid/tab_grid_coordinator.mm index d36633a..1b620951 100644 --- a/ios/clean/chrome/browser/ui/tab_grid/tab_grid_coordinator.mm +++ b/ios/clean/chrome/browser/ui/tab_grid/tab_grid_coordinator.mm
@@ -75,6 +75,7 @@ [self.context.baseViewController presentViewController:self.viewController animated:self.context.animated completion:nil]; + [super start]; } #pragma mark - TabGridDataSource
diff --git a/ios/clean/chrome/browser/ui/tab_strip/tab_strip_container_coordinator.mm b/ios/clean/chrome/browser/ui/tab_strip/tab_strip_container_coordinator.mm index cec30fa..932ed19 100644 --- a/ios/clean/chrome/browser/ui/tab_strip/tab_strip_container_coordinator.mm +++ b/ios/clean/chrome/browser/ui/tab_strip/tab_strip_container_coordinator.mm
@@ -64,9 +64,11 @@ [self.context.baseViewController presentViewController:self.viewController animated:self.context.animated completion:nil]; + [super start]; } - (void)stop { + [super stop]; [self.viewController.presentingViewController dismissViewControllerAnimated:self.context.animated completion:nil];
diff --git a/ios/clean/chrome/browser/ui/toolbar/toolbar_coordinator.mm b/ios/clean/chrome/browser/ui/toolbar/toolbar_coordinator.mm index 8bda941..41a3fec8 100644 --- a/ios/clean/chrome/browser/ui/toolbar/toolbar_coordinator.mm +++ b/ios/clean/chrome/browser/ui/toolbar/toolbar_coordinator.mm
@@ -51,6 +51,7 @@ [self.context.baseViewController presentViewController:self.viewController animated:self.context.animated completion:nil]; + [super start]; } #pragma mark - ToolbarCommands
diff --git a/ios/clean/chrome/browser/ui/tools/tools_coordinator.mm b/ios/clean/chrome/browser/ui/tools/tools_coordinator.mm index d80614ef..aaec5a47 100644 --- a/ios/clean/chrome/browser/ui/tools/tools_coordinator.mm +++ b/ios/clean/chrome/browser/ui/tools/tools_coordinator.mm
@@ -35,9 +35,11 @@ [self.context.baseViewController presentViewController:self.menuViewController animated:self.context.animated completion:nil]; + [super start]; } - (void)stop { + [super stop]; [self.menuViewController.presentingViewController dismissViewControllerAnimated:self.context.animated completion:nil];
diff --git a/ios/clean/chrome/browser/ui/web_contents/web_coordinator.mm b/ios/clean/chrome/browser/ui/web_contents/web_coordinator.mm index f736feb..0248d70 100644 --- a/ios/clean/chrome/browser/ui/web_contents/web_coordinator.mm +++ b/ios/clean/chrome/browser/ui/web_contents/web_coordinator.mm
@@ -50,9 +50,11 @@ [self.context.baseViewController presentViewController:self.viewController animated:self.context.animated completion:nil]; + [super start]; } - (void)stop { + [super stop]; // PLACEHOLDER: This is how the webUsageEnabled is set to false. Find a // better way in the future. self.mediator.webState = nullptr;
diff --git a/ios/clean/chrome/test/BUILD.gn b/ios/clean/chrome/test/BUILD.gn index 758c428..88d9e82 100644 --- a/ios/clean/chrome/test/BUILD.gn +++ b/ios/clean/chrome/test/BUILD.gn
@@ -21,6 +21,7 @@ # Add unit_tests target here. "//ios/clean/chrome/browser:unit_tests", "//ios/clean/chrome/browser/model:unit_tests", + "//ios/clean/chrome/browser/ui/commands:unit_tests", "//ios/clean/chrome/browser/ui/web_contents:unit_tests", ] }
diff --git a/net/interfaces/BUILD.gn b/net/interfaces/BUILD.gn index ba7b53f..65910368 100644 --- a/net/interfaces/BUILD.gn +++ b/net/interfaces/BUILD.gn
@@ -7,6 +7,7 @@ mojom("interfaces") { sources = [ "host_resolver_service.mojom", + "ip_address.mojom", "proxy_resolver_service.mojom", ] public_deps = [
diff --git a/net/interfaces/OWNERS b/net/interfaces/OWNERS index 08850f4..2c44a46 100644 --- a/net/interfaces/OWNERS +++ b/net/interfaces/OWNERS
@@ -1,2 +1,6 @@ per-file *.mojom=set noparent per-file *.mojom=file://ipc/SECURITY_OWNERS +per-file *_struct_traits*.*=set noparent +per-file *_struct_traits*.*=file://ipc/SECURITY_OWNERS +per-file *.typemap=set noparent +per-file *.typemap=file://ipc/SECURITY_OWNERS
diff --git a/net/interfaces/ip_address.mojom b/net/interfaces/ip_address.mojom new file mode 100644 index 0000000..012b81c --- /dev/null +++ b/net/interfaces/ip_address.mojom
@@ -0,0 +1,12 @@ +// 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. + +module net.interfaces; + +// Mirror of net::IPAddress. +struct IPAddress { + // IP address as a numeric value from most to least significant byte. + // Will be of length 4 for IPv4 addresses and 16 for IPv6. + array<uint8> address; +};
diff --git a/net/interfaces/ip_address.typemap b/net/interfaces/ip_address.typemap new file mode 100644 index 0000000..64488d6 --- /dev/null +++ b/net/interfaces/ip_address.typemap
@@ -0,0 +1,14 @@ +# 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. + +mojom = "//net/interfaces/ip_address.mojom" +public_headers = [ "//net/base/ip_address.h" ] +traits_headers = [ "//net/interfaces/ip_address_struct_traits.h" ] +sources = [ + "//net/interfaces/ip_address_struct_traits.cc", +] +type_mappings = [ "net.interfaces.IPAddress=net::IPAddress" ] +public_deps = [ + "//net", +]
diff --git a/net/interfaces/ip_address_struct_traits.cc b/net/interfaces/ip_address_struct_traits.cc new file mode 100644 index 0000000..b23ac88 --- /dev/null +++ b/net/interfaces/ip_address_struct_traits.cc
@@ -0,0 +1,20 @@ +// 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 "net/interfaces/ip_address_struct_traits.h" + +namespace mojo { +// static +bool StructTraits<net::interfaces::IPAddressDataView, net::IPAddress>::Read( + net::interfaces::IPAddressDataView data, + net::IPAddress* out) { + std::vector<uint8_t> bytes; + if (!data.ReadAddress(&bytes)) + return false; + + *out = net::IPAddress(bytes); + return out->IsValid(); +} + +} // namespace mojo
diff --git a/net/interfaces/ip_address_struct_traits.h b/net/interfaces/ip_address_struct_traits.h new file mode 100644 index 0000000..9c97baf --- /dev/null +++ b/net/interfaces/ip_address_struct_traits.h
@@ -0,0 +1,24 @@ +// 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 NET_INTERFACES_IP_ADDRESS_STRUCT_TRAITS_H_ +#define NET_INTERFACES_IP_ADDRESS_STRUCT_TRAITS_H_ + +#include "mojo/public/cpp/bindings/struct_traits.h" +#include "net/base/ip_address.h" +#include "net/interfaces/ip_address.mojom.h" + +namespace mojo { +template <> +struct StructTraits<net::interfaces::IPAddressDataView, net::IPAddress> { + static const std::vector<uint8_t>& address(const net::IPAddress& ip_address) { + return ip_address.bytes(); + } + + static bool Read(net::interfaces::IPAddressDataView obj, net::IPAddress* out); +}; + +} // namespace mojo + +#endif // NET_INTERFACES_IP_ADDRESS_STRUCT_TRAITS_H_
diff --git a/net/interfaces/typemaps.gni b/net/interfaces/typemaps.gni index 57a75bf..7d8ec79 100644 --- a/net/interfaces/typemaps.gni +++ b/net/interfaces/typemaps.gni
@@ -4,5 +4,6 @@ typemaps = [ "//net/interfaces/host_resolver.typemap", + "//net/interfaces/ip_address.typemap", "//net/interfaces/proxy_resolver.typemap", ]
diff --git a/services/ui/ws/event_dispatcher_unittest.cc b/services/ui/ws/event_dispatcher_unittest.cc index d7192a2d..7a3ef422 100644 --- a/services/ui/ws/event_dispatcher_unittest.cc +++ b/services/ui/ws/event_dispatcher_unittest.cc
@@ -1563,6 +1563,55 @@ EXPECT_EQ(gfx::Point(35, 5), dispatched_event->location()); } +// Tests events on a sub-window of system modal window target the window itself. +TEST_F(EventDispatcherTest, ModalWindowEventSubWindowSystemModal) { + std::unique_ptr<ServerWindow> w1 = CreateChildWindow(WindowId(1, 3)); + w1->SetModalType(MODAL_TYPE_SYSTEM); + event_dispatcher()->AddSystemModalWindow(w1.get()); + + std::unique_ptr<ServerWindow> w2 = + CreateChildWindowWithParent(WindowId(1, 4), w1.get()); + std::unique_ptr<ServerWindow> w3 = CreateChildWindow(WindowId(1, 5)); + + root_window()->SetBounds(gfx::Rect(0, 0, 100, 100)); + w1->SetBounds(gfx::Rect(10, 10, 30, 30)); + w2->SetBounds(gfx::Rect(10, 10, 10, 10)); + w3->SetBounds(gfx::Rect(50, 10, 10, 10)); + + struct { + gfx::Point location; + ServerWindow* expected_target; + } kTouchData[] = { + // Touch on |w1| should go to |w1|. + {gfx::Point(11, 11), w1.get()}, + // Touch on |w2| should go to |w2|. + {gfx::Point(25, 25), w2.get()}, + // Touch on |w3| should go to |w1|. + {gfx::Point(11, 31), w1.get()}, + }; + + for (size_t i = 0; i < arraysize(kTouchData); i++) { + // Send touch press and check that the expected target receives it. + event_dispatcher()->ProcessEvent( + ui::PointerEvent(ui::TouchEvent(ui::ET_TOUCH_PRESSED, + kTouchData[i].location, 0, + base::TimeTicks())), + EventDispatcher::AcceleratorMatchPhase::ANY); + std::unique_ptr<DispatchedEventDetails> details = + test_event_dispatcher_delegate()->GetAndAdvanceDispatchedEventDetails(); + ASSERT_TRUE(details) << " details is nullptr " << i; + EXPECT_EQ(kTouchData[i].expected_target, details->window); + + // Release touch. + event_dispatcher()->ProcessEvent( + ui::PointerEvent(ui::TouchEvent(ui::ET_TOUCH_RELEASED, + kTouchData[i].location, 0, + base::TimeTicks())), + EventDispatcher::AcceleratorMatchPhase::ANY); + test_event_dispatcher_delegate()->GetAndAdvanceDispatchedEventDetails(); + } +} + // Tests that setting capture to a descendant of a modal parent fails. TEST_F(EventDispatcherTest, ModalWindowSetCaptureDescendantOfModalParent) { std::unique_ptr<ServerWindow> w1 = CreateChildWindow(WindowId(1, 3));
diff --git a/services/ui/ws/modal_window_controller.cc b/services/ui/ws/modal_window_controller.cc index bb1c0bf..9ac70b9 100644 --- a/services/ui/ws/modal_window_controller.cc +++ b/services/ui/ws/modal_window_controller.cc
@@ -78,16 +78,16 @@ bool ModalWindowController::IsWindowBlocked(const ServerWindow* window) const { DCHECK(window); - return GetActiveSystemModalWindow() || GetModalChildForWindowAncestor(window); + return GetTargetForWindow(window) != window; } const ServerWindow* ModalWindowController::GetTargetForWindow( const ServerWindow* window) const { - // TODO(moshayedi): crbug.com/697127. Handle windows which are modal to - // children of their transient parent. + // TODO(moshayedi): crbug.com/697127. Handle MODAL_TYPE_CHILD. ServerWindow* system_modal_window = GetActiveSystemModalWindow(); if (system_modal_window) - return system_modal_window; + return system_modal_window->Contains(window) ? window : system_modal_window; + return window ? GetWindowModalTargetForWindow(window) : nullptr; }
diff --git a/testing/buildbot/chromium.android.json b/testing/buildbot/chromium.android.json index bfca386..ddf9de8 100644 --- a/testing/buildbot/chromium.android.json +++ b/testing/buildbot/chromium.android.json
@@ -1183,7 +1183,8 @@ { "args": [ "--browser=android-chromium", - "--device=android" + "--device=android", + "--skip=benchmarks.system_health_smoke_test.SystemHealthBenchmarkSmokeTest.*" ], "isolate_name": "telemetry_perf_unittests", "name": "telemetry_perf_unittests", @@ -1205,6 +1206,18 @@ } ] }, + "Android arm Builder (dbg)": { + "additional_compile_targets": [ + "dump_syms", + "microdump_stackwalk" + ] + }, + "Android arm64 Builder (dbg)": { + "additional_compile_targets": [ + "dump_syms", + "microdump_stackwalk" + ] + }, "KitKat Tablet Tester": { "gtest_tests": [ { @@ -2786,6 +2799,41 @@ "test": "components_browsertests" }, { + "args": [ + "--test-arguments=--enable-browser-side-navigation" + ], + "name": "browser_side_navigation_components_browsertests", + "override_isolate_target": "components_browsertests", + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6" + } + ], + "dimension_sets": [ + { + "device_os": "MMB29Q", + "device_type": "bullhead" + } + ], + "hard_timeout": 960, + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ] + }, + "test": "components_browsertests" + }, + { "override_isolate_target": "components_unittests", "swarming": { "can_use_on_swarming_builders": true, @@ -2817,6 +2865,76 @@ "test": "components_unittests" }, { + "args": [ + "--test-arguments=--enable-browser-side-navigation" + ], + "name": "browser_side_navigation_components_unittests", + "override_isolate_target": "components_unittests", + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6" + } + ], + "dimension_sets": [ + { + "device_os": "MMB29Q", + "device_type": "bullhead" + } + ], + "hard_timeout": 960, + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ] + }, + "test": "components_unittests" + }, + { + "override_isolate_target": "content_browsertests", + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6" + } + ], + "dimension_sets": [ + { + "device_os": "MMB29Q", + "device_type": "bullhead" + } + ], + "hard_timeout": 960, + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ] + }, + "test": "content_browsertests" + }, + { + "args": [ + "--test-arguments=--enable-browser-side-navigation" + ], + "name": "browser_side_navigation_content_browsertests", "override_isolate_target": "content_browsertests", "swarming": { "can_use_on_swarming_builders": true, @@ -2913,6 +3031,41 @@ "test": "content_unittests" }, { + "args": [ + "--test-arguments=--enable-browser-side-navigation" + ], + "name": "browser_side_navigation_content_unittests", + "override_isolate_target": "content_unittests", + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6" + } + ], + "dimension_sets": [ + { + "device_os": "MMB29Q", + "device_type": "bullhead" + } + ], + "hard_timeout": 960, + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ] + }, + "test": "content_unittests" + }, + { "override_isolate_target": "device_unittests", "swarming": { "can_use_on_swarming_builders": true, @@ -3443,6 +3596,41 @@ "test": "unit_tests" }, { + "args": [ + "--test-arguments=--enable-browser-side-navigation" + ], + "name": "browser_side_navigation_unit_tests", + "override_isolate_target": "unit_tests", + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:dec8cc6fd715753846d0aca1693dc63844ea55d6" + } + ], + "dimension_sets": [ + { + "device_os": "MMB29Q", + "device_type": "bullhead" + } + ], + "hard_timeout": 960, + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ] + }, + "test": "unit_tests" + }, + { "override_isolate_target": "vr_shell_unittests", "swarming": { "can_use_on_swarming_builders": true,
diff --git a/testing/buildbot/gn_isolate_map.pyl b/testing/buildbot/gn_isolate_map.pyl index dc42690..55813f1f 100644 --- a/testing/buildbot/gn_isolate_map.pyl +++ b/testing/buildbot/gn_isolate_map.pyl
@@ -421,6 +421,10 @@ "label": "//services/ui/display:display_service_unittests", "type": "console_test_launcher", }, + "dump_syms" : { + "label": "//breakpad:dump_syms", + "type": "additional_compile_target", + }, "events_unittests": { "label": "//ui/events:events_unittests", "type": "windowed_test_launcher",
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations index 72744530..02a06a68 100644 --- a/third_party/WebKit/LayoutTests/TestExpectations +++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -35,7 +35,6 @@ # existing tests. We have skipped the entire spv2 directory and are adding [ Pass ] lines # as we go. Please remove [ Pass ] lines instead of rebaselining these tests. crbug.com/537409 virtual/spv2/ [ Skip ] -crbug.com/563667 virtual/spv2/fast/block/basic/001.html [ Pass ] # Begin whitlelisted paint invalidation tests crbug.com/647831 virtual/spv2/paint/invalidation/margin.html [ Pass ] # End whitlelisted paint invalidation tests @@ -101,7 +100,7 @@ crbug.com/632000 [ Win ] images/paint-subrect-grid.html [ Pass Failure ] # Very slight (~2 pixel) differences. -crbug.com/699573 [ Win ] virtual/gpu-rasterization/images/cross-fade-background-size.html [ Failure ] +crbug.com/699573 [ Win ] virtual/gpu-rasterization/images/cross-fade-background-size.html [ Pass Failure ] crbug.com/639147 svg/wicd/test-rightsizing-b.xhtml [ Failure Pass ] @@ -2227,6 +2226,603 @@ crbug.com/658997 external/wpt/service-workers/service-worker/invalid-header.https.html [ Skip ] crbug.com/658997 external/wpt/service-workers/service-worker/referer.https.html [ Skip ] +# The Mac10.12 builder was just added, and proper baselines or expectations +# are not yet added for the below tests. +crbug.com/697971 [ Mac10.12 ] compositing/overflow/border-radius-styles-with-composited-child.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] compositing/overflow/do-not-paint-outline-into-composited-scrolling-contents.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] compositing/overflow/theme-affects-visual-overflow.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] compositing/overflow/update-widget-positions-on-nested-frames-and-scrollers.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] css2.1/t1202-counter-04-b.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] css2.1/t1202-counters-04-b.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] css3/flexbox/button.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] css3/selectors3/html/css3-modsel-161.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] css3/selectors3/html/css3-modsel-19b.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] css3/selectors3/html/css3-modsel-23.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] css3/selectors3/html/css3-modsel-24.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] css3/selectors3/html/css3-modsel-64.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] css3/selectors3/html/css3-modsel-68.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] css3/selectors3/html/css3-modsel-69.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] css3/selectors3/xhtml/css3-modsel-161.xml [ Failure ] +crbug.com/697971 [ Mac10.12 ] css3/selectors3/xhtml/css3-modsel-19b.xml [ Failure ] +crbug.com/697971 [ Mac10.12 ] css3/selectors3/xhtml/css3-modsel-23.xml [ Failure ] +crbug.com/697971 [ Mac10.12 ] css3/selectors3/xhtml/css3-modsel-24.xml [ Failure ] +crbug.com/697971 [ Mac10.12 ] css3/selectors3/xhtml/css3-modsel-64.xml [ Failure ] +crbug.com/697971 [ Mac10.12 ] css3/selectors3/xhtml/css3-modsel-68.xml [ Failure ] +crbug.com/697971 [ Mac10.12 ] css3/selectors3/xhtml/css3-modsel-69.xml [ Failure ] +crbug.com/697971 [ Mac10.12 ] css3/selectors3/xml/css3-modsel-161.xml [ Failure ] +crbug.com/697971 [ Mac10.12 ] css3/selectors3/xml/css3-modsel-19b.xml [ Failure ] +crbug.com/697971 [ Mac10.12 ] css3/selectors3/xml/css3-modsel-23.xml [ Failure ] +crbug.com/697971 [ Mac10.12 ] css3/selectors3/xml/css3-modsel-24.xml [ Failure ] +crbug.com/697971 [ Mac10.12 ] css3/selectors3/xml/css3-modsel-64.xml [ Failure ] +crbug.com/697971 [ Mac10.12 ] css3/selectors3/xml/css3-modsel-68.xml [ Failure ] +crbug.com/697971 [ Mac10.12 ] css3/selectors3/xml/css3-modsel-69.xml [ Failure ] +crbug.com/697971 [ Mac10.12 ] editing/caret/caret-color.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] editing/deleting/delete-at-paragraph-boundaries-011.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] editing/deleting/delete-line-001.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] editing/deleting/delete-line-002.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] editing/deleting/delete-line-004.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] editing/deleting/delete-line-005.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] editing/deleting/delete-line-006.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] editing/deleting/delete-line-007.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] editing/deleting/delete-line-008.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] editing/deleting/delete-line-009.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] editing/deleting/delete-line-010.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] editing/deleting/delete-line-011.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] editing/deleting/delete-line-012.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] editing/input/caret-at-the-edge-of-input.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] editing/input/reveal-caret-of-multiline-input.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] editing/inserting/insert-br-quoted-001.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] editing/inserting/insert-br-quoted-002.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] editing/inserting/insert-br-quoted-003.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] editing/inserting/insert-br-quoted-004.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] editing/inserting/insert-br-quoted-005.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] editing/inserting/insert-br-quoted-006.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] editing/pasteboard/drop-text-without-selection.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] editing/pasteboard/emacs-ctrl-k-y-001.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] editing/pasteboard/paste-line-endings-001.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] editing/pasteboard/paste-line-endings-002.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] editing/pasteboard/paste-line-endings-003.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] editing/pasteboard/paste-line-endings-004.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] editing/pasteboard/paste-line-endings-005.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] editing/pasteboard/paste-text-016.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] editing/pasteboard/pasting-tabs.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] editing/selection/3690719.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] editing/selection/4975120.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] editing/selection/move-3875618-fix.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] editing/selection/move-3875641-fix.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] editing/selection/move-by-sentence-001.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] editing/selection/replaced-boundaries-3.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] editing/selection/select-across-readonly-input-1.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] editing/selection/select-across-readonly-input-2.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] editing/selection/select-across-readonly-input-3.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] editing/selection/select-across-readonly-input-4.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] editing/selection/select-across-readonly-input-5.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] editing/selection/select-element-paragraph-boundary.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] editing/selection/select-missing-image.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] editing/selection/selection-button-text.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] editing/style/block-style-001.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] editing/style/block-style-002.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] editing/style/block-style-003.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] editing/style/block-styles-007.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] external/wpt/css-typed-om/CSSMatrixComponent-DOMMatrix-mutable.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] external/wpt/css-typed-om/styleMap-update-function.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] external/wpt/dom/events/CustomEvent.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] external/wpt/dom/events/Event-initEvent.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] external/wpt/dom/interfaces.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] external/wpt/dom/lists/DOMTokenList-coverage-for-attributes.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] external/wpt/dom/nodes/Element-matches.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] external/wpt/dom/nodes/Element-webkitMatchesSelector.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] external/wpt/editing/run/inserthorizontalrule.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] external/wpt/editing/run/italic.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] external/wpt/editing/run/multitest.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] external/wpt/editing/run/removeformat.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] external/wpt/editing/run/strikethrough.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] external/wpt/editing/run/subscript.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] external/wpt/editing/run/superscript.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] external/wpt/editing/run/underline.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] external/wpt/html/semantics/document-metadata/the-meta-element/pragma-directives/attr-meta-http-equiv-refresh/dynamic-append.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] external/wpt/html/semantics/scripting-1/the-script-element/script-charset-01.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] external/wpt/html/semantics/scripting-1/the-script-element/script-charset-02.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] external/wpt/html/webappapis/scripting/events/messageevent-constructor.https.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] external/wpt/pointerevents/extension/idlharness.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] external/wpt/selection/addRange-00.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] external/wpt/selection/addRange-04.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] external/wpt/selection/addRange-12.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] external/wpt/selection/addRange-16.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] external/wpt/selection/addRange-20.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] external/wpt/selection/addRange-24.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] external/wpt/selection/addRange-28.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] external/wpt/selection/addRange-32.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] external/wpt/selection/addRange-36.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] external/wpt/service-workers/service-worker/fetch-event-within-sw-manual.https.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] external/wpt/web-animations/interfaces/Animatable/animate.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] external/wpt/web-animations/interfaces/KeyframeEffect/constructor.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] external/wpt/web-animations/interfaces/KeyframeEffect/setKeyframes.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] external/wpt/webrtc/rtcpeerconnection/setRemoteDescription.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] external/wpt/webvtt/api/VTTCue/align.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] external/wpt/webvtt/api/VTTCue/lineAlign.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] external/wpt/webvtt/api/VTTCue/positionAlign.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] external/wpt/webvtt/api/VTTCue/text.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] external/wpt/webvtt/api/VTTCue/vertical.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] external/wpt/webvtt/parsing/cue-text-parsing/tests/entities.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] external/wpt/webvtt/parsing/cue-text-parsing/tests/tags.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] external/wpt/webvtt/parsing/cue-text-parsing/tests/timestamps.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] external/wpt/webvtt/parsing/cue-text-parsing/tests/tree-building.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] external/wpt/webvtt/parsing/file-parsing/signature-invalid.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] external/wpt/webvtt/parsing/file-parsing/tests/regions-id.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] external/wpt/webvtt/parsing/file-parsing/tests/regions-lines.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] external/wpt/webvtt/parsing/file-parsing/tests/regions-old.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] external/wpt/webvtt/parsing/file-parsing/tests/regions-regionanchor.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] external/wpt/webvtt/parsing/file-parsing/tests/regions-scroll.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] external/wpt/webvtt/parsing/file-parsing/tests/regions-viewportanchor.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] external/wpt/webvtt/parsing/file-parsing/tests/settings-line.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] external/wpt/webvtt/parsing/file-parsing/tests/settings-position.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] external/wpt/webvtt/parsing/file-parsing/tests/settings-region.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] external/wpt/workers/semantics/encodings/001.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] external/wpt/workers/semantics/encodings/002.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/block/basic/001.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/block/float/float-avoidance.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/block/float/intruding-painted-twice.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/block/margin-collapse/103.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/block/positioning/047.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/block/positioning/inline-block-relposition.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/borders/borderRadiusAllStylesAllCorners.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/borders/borderRadiusDashed01.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/borders/borderRadiusDashed02.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/borders/borderRadiusDashed03.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/borders/borderRadiusDashed04.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/borders/borderRadiusDashed05.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/borders/borderRadiusDashed06.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/borders/borderRadiusDotted01.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/borders/borderRadiusDotted04.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/borders/inline-mask-overlay-image-outset.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/box-shadow/inset-subpixel.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/box-shadow/inset.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/css-generated-content/012.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/css-generated-content/014.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/css/acid2-pixel.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/css/clip-zooming.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/css/continuationCrash.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/css/h1-in-section-elements.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/css/input-search-padding.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/css/line-height.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/css/margin-top-bottom-dynamic.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/css/rem-calc-dynamic-scaling.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/css/rem-dynamic-scaling.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/css/text-overflow-input.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/dnd/link-dragging-draggable-div-with-dragged-link.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/dnd/link-dragging-non-draggable-link.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/dom/HTMLInputElement/input-image-alt-text.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/dom/HTMLMeterElement/meter-optimums.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/dom/HTMLTableColElement/resize-table-using-col-width.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/dynamic/008.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/dynamic/012.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/dynamic/positioned-movement-with-positioned-children.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/encoding/denormalised-voiced-japanese-chars.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/events/autoscroll.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/events/context-no-deselect.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/files/file-in-input-display.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/basic-buttons.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/basic-inputs.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/blankbuttons.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/button-default-title.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/button-positioned.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/button-sizes.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/button-style-color.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/button-table-styles.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/button-text-transform.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/button/button-align.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/button/button-cannot-be-nested.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/button/button-inner-block-reuse.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/button/button-white-space.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/calendar-picker/calendar-picker-appearance-ar.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/calendar-picker/calendar-picker-appearance-minimum-date.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/calendar-picker/calendar-picker-appearance-required-ar.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/calendar-picker/calendar-picker-appearance-required.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/calendar-picker/calendar-picker-appearance-ru.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/calendar-picker/calendar-picker-appearance-step.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/calendar-picker/calendar-picker-appearance-zoom125.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/calendar-picker/calendar-picker-appearance-zoom200.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/calendar-picker/calendar-picker-appearance.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/calendar-picker/month-picker-appearance-step.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/calendar-picker/month-picker-appearance.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/calendar-picker/week-picker-appearance-step.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/calendar-picker/week-picker-appearance.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/color/color-suggestion-picker-appearance-zoom125.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/color/color-suggestion-picker-appearance-zoom200.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/color/color-suggestion-picker-appearance.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/color/color-suggestion-picker-one-row-appearance.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/color/color-suggestion-picker-two-row-appearance.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/control-clip-overflow.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/control-clip.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/control-restrict-line-height.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/datetimelocal/datetimelocal-appearance-l10n.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/file/file-input-direction.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/file/file-input-disabled.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/file/file-input-pressed-state.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/file/input-file-re-render.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/floating-textfield-relayout.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/form-element-geometry.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/formmove3.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/image/002.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/image/005.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/input-align.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/input-appearance-height.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/input-button-sizes.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/input-first-letter.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/input-type-text-min-width.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/input-value.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/minWidthPercent.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/month/month-appearance-l10n.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/number/number-appearance-rtl.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/number/number-appearance-spinbutton-disabled-readonly.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/number/number-appearance-spinbutton-layer.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/placeholder-position.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/plaintext-mode-2.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/search/search-appearance-basic.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/search/search-cancel-button-style-sharing.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/search/search-display-none-cancel-button.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/search/search-rtl.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/search/search-vertical-alignment.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/search/searchfield-heights.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/select/003.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/select/004.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/select/HTMLOptionElement_label01.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/select/HTMLOptionElement_label02.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/select/HTMLOptionElement_label03.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/select/HTMLOptionElement_label04.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/select/HTMLOptionElement_label05.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/select/basic-selects.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/select/disabled-select-change-index.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/select/hidden-listbox.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/select/listbox-appearance-basic.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/select/listbox-appearance-separator.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/select/listbox-bidi-align.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/select/listbox-scrollbar-incremental-load.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/select/listbox-width-change.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/select/listbox-with-display-none-option.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/select/menulist-appearance-none.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/select/menulist-appearance-rtl.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/select/menulist-clip.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/select/menulist-deselect-update.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/select/menulist-no-overflow.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/select/menulist-option-wrap.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/select/menulist-restrict-line-height.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/select/menulist-style-color.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/select/menulist-width-change.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/select/optgroup-rendering.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/select/option-script.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/select/option-strip-whitespace.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/select/option-text-clip.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/select/select-align.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/select/select-autofilled.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/select/select-background-none.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/select/select-baseline.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/select/select-block-background.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/select/select-change-listbox-size.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/select/select-change-listbox-to-popup.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/select/select-change-popup-to-listbox.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/select/select-dirty-parent-pref-widths.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/select/select-disabled-appearance.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/select/select-initial-position.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/select/select-item-background-clip.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/select/select-list-box-with-height.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/select/select-listbox-multiple-no-focusring.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/select/select-multiple-rtl.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/select/select-overflow-scroll-inherited.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/select/select-overflow-scroll.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/select/select-selected.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/select/select-size-invalid.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/select/select-style.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/select/select-writing-direction-natural.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/stuff-on-my-optgroup.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/submit/submit-appearance-basic.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/suggestion-picker/date-suggestion-picker-appearance-rtl.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/suggestion-picker/date-suggestion-picker-appearance-with-scroll-bar.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/suggestion-picker/date-suggestion-picker-appearance.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/suggestion-picker/datetimelocal-suggestion-picker-appearance-locale-hebrew.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/suggestion-picker/datetimelocal-suggestion-picker-appearance-rtl.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/suggestion-picker/datetimelocal-suggestion-picker-appearance-with-scroll-bar.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/suggestion-picker/datetimelocal-suggestion-picker-appearance.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/suggestion-picker/month-suggestion-picker-appearance-rtl.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/suggestion-picker/month-suggestion-picker-appearance-with-scroll-bar.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/suggestion-picker/month-suggestion-picker-appearance.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/suggestion-picker/time-suggestion-picker-appearance-locale-hebrew.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/suggestion-picker/time-suggestion-picker-appearance-rtl.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/suggestion-picker/time-suggestion-picker-appearance-with-scroll-bar.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/suggestion-picker/time-suggestion-picker-appearance.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/suggestion-picker/week-suggestion-picker-appearance-rtl.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/suggestion-picker/week-suggestion-picker-appearance-with-scroll-bar.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/suggestion-picker/week-suggestion-picker-appearance.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/tabbing-input-iframe.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/targeted-frame-submission.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/text-style-color.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/text/input-appearance-bkcolor.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/text/input-appearance-default-bkcolor.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/text/input-appearance-disabled.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/text/input-appearance-focus.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/text/input-appearance-preventDefault.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/text/input-appearance-readonly.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/text/input-appearance-selection.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/text/input-appearance-visibility.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/text/input-appearance-width.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/text/input-disabled-color.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/text/input-double-click-selection-gap-bug.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/text/input-field-text-truncated.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/text/input-placeholder-paint-order.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/text/input-placeholder-visibility-1.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/text/input-placeholder-visibility-3.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/text/input-readonly-autoscroll.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/text/input-readonly-dimmed.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/text/input-spaces.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/text/input-table.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/text/input-text-double-click.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/text/input-text-drag-down.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/text/input-text-option-delete.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/text/input-text-word-wrap.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/text/text-appearance-basic.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/text/text-font-height-mismatch.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/text/textfield-outline.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/text/textfield-overflow-by-value-update.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/textarea/basic-textareas-quirks.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/textarea/basic-textareas.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/textarea/placeholder-appearance-textarea.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/textarea/reset-textarea.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/textarea/textarea-align.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/textarea/textarea-appearance-basic.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/textarea/textarea-placeholder-paint-order.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/textarea/textarea-placeholder-visibility-1.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/textarea/textarea-placeholder-visibility-2.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/textarea/textarea-scroll-height.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/textarea/textarea-scrollbar.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/textarea/textarea-scrolled-focus-ring.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/textarea/textarea-scrolled-mask.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/textarea/textarea-scrolled-type.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/forms/textarea/textarea-setinnerhtml.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/inline/absolute-positioned-inline-in-centred-block.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/inline/left-right-center-inline-alignment-in-ltr-and-rtl-blocks.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/invalid/014.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/lists/dynamic-marker-crash.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/lists/ordered-list-with-no-ol-tag.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/multicol/multicol-with-child-renderLayer-for-input.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/overflow/overflow-x-y.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/overflow/scroll-nested-positioned-layer-in-overflow.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/overflow/scrollRevealButton.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/parser/document-write-option.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/parser/entity-comment-in-textarea.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/parser/open-comment-in-textarea.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/replaced/border-radius-clip-content-edge.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/replaced/replaced-breaking-mixture.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/replaced/replaced-breaking.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/replaced/width100percent-button.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/selectors/064.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/selectors/166.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/spatial-navigation/snav-multiple-select-focusring.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/table/append-cells2.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/table/backgr_border-table-cell-collapsed-border.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/table/backgr_border-table-cell.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/table/backgr_border-table-collapsed-border.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/table/backgr_border-table-column-collapsed-border.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/table/backgr_border-table-column-group-collapsed-border.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/table/backgr_border-table-column-group.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/table/backgr_border-table-column.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/table/backgr_border-table-quirks-collapsed-border.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/table/backgr_border-table-quirks.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/table/backgr_border-table-row-collapsed-border.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/table/backgr_border-table-row-group-collapsed-border.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/table/backgr_border-table-row-group.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/table/backgr_border-table-row.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/table/backgr_border-table.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/table/backgr_layers-hide-collapsed-border.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/table/backgr_layers-hide.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/table/backgr_position-table-cell-collapsed-border.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/table/backgr_position-table-cell.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/table/backgr_position-table-collapsed-border.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/table/backgr_position-table-column-collapsed-border.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/table/backgr_position-table-column-group-collapsed-border.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/table/backgr_position-table-column-group.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/table/backgr_position-table-column.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/table/backgr_position-table-row-collapsed-border.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/table/backgr_position-table-row-group-collapsed-border.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/table/backgr_position-table-row-group.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/table/backgr_position-table-row.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/table/backgr_position-table.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/table/backgr_simple-table-cell-collapsed-border.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/table/backgr_simple-table-cell.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/table/backgr_simple-table-collapsed-border.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/table/backgr_simple-table-column-collapsed-border.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/table/backgr_simple-table-column-group-collapsed-border.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/table/backgr_simple-table-column-group.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/table/backgr_simple-table-column.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/table/backgr_simple-table-row-collapsed-border.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/table/backgr_simple-table-row-group-collapsed-border.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/table/backgr_simple-table-row-group.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/table/backgr_simple-table-row.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/table/backgr_simple-table.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/table/remove-td-display-none.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/table/spanOverlapRepaint.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/table/text-field-baseline.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/text/color-emoji.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/text/complex-preferred-logical-widths.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/text/drawBidiText.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/text/emoticons.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/text/emphasis-complex.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/text/fallback-traits-fixup.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/text/font-fallback.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/text/font-ligature-letter-spacing.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/text/international/bidi-listbox-atsui.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/text/international/bidi-listbox.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/text/international/khmer-selection.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/text/international/lang-glyph-cache-separation.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/text/international/mixed-directionality-selection.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/text/international/unicode-bidi-plaintext-in-textarea.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/text/justify-ideograph-complex.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/text/justify-ideograph-simple.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/text/justify-ideograph-vertical.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/text/midword-break-before-surrogate-pair.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/text/textIteratorNilRenderer.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/text/unicode-fallback-font.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/text/updateNewFont.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/writing-mode/text-combine-various-fonts.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fonts/sans-serif.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] html/details_summary/details-marker-style.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] html/details_summary/details-replace-summary-child.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] html/details_summary/details-replace-text.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] http/tests/filesystem/input-display.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] http/tests/inspector-protocol/network-data-length.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] http/tests/media/media-source/mediasource-is-type-supported.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] http/tests/media/video-buffered-range-contains-currentTime.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] http/tests/misc/acid2-pixel.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] http/tests/misc/bad-charset-alias.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] http/tests/streams/readable-streams/count-queuing-strategy-integration.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] http/tests/webfont/popup-menu-load-webfont-after-open.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] ietestcenter/css3/bordersbackgrounds/border-radius-style-001.htm [ Failure ] +crbug.com/697971 [ Mac10.12 ] ietestcenter/css3/bordersbackgrounds/border-radius-style-002.htm [ Failure ] +crbug.com/697971 [ Mac10.12 ] images/12-55.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] images/182.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] images/2-dht.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] images/23-55.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] images/55.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] inspector-protocol/layout-fonts/ogham.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] inspector-protocol/layout-fonts/tifinagh.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] media/track/track-cue-rendering-vertical.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] media/video-zoom-controls.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] paint/invalidation/button-checkbox-click-method-repaint.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] paint/invalidation/caret-invalidation-in-overflow-scroll.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] paint/invalidation/forms/button-reset-focus-by-mouse-then-keydown.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] paint/invalidation/forms/submit-focus-by-mouse-then-keydown.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] paint/invalidation/resize-iframe-text.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] paint/invalidation/subtree-root-skipped.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] paint/invalidation/textarea-caret.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] paint/selection/text-selection-inline-block-rtl.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] paint/selection/text-selection-inline-block.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] paint/spellmarkers/document-markers-zoom-150.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] plugins/embed-attributes-style.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] plugins/mouse-click-plugin-clears-selection.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] scrollbars/custom-scrollbar-with-incomplete-style.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] svg/W3C-SVG-1.1-SE/coords-units-03-b.svg [ Failure ] +crbug.com/697971 [ Mac10.12 ] svg/W3C-SVG-1.1-SE/painting-marker-06-f.svg [ Failure ] +crbug.com/697971 [ Mac10.12 ] svg/W3C-SVG-1.1-SE/styling-pres-02-f.svg [ Failure ] +crbug.com/697971 [ Mac10.12 ] svg/W3C-SVG-1.1-SE/svgdom-over-01-f.svg [ Failure ] +crbug.com/697971 [ Mac10.12 ] svg/W3C-SVG-1.1-SE/text-intro-02-b.svg [ Failure ] +crbug.com/697971 [ Mac10.12 ] svg/W3C-SVG-1.1-SE/text-intro-09-b.svg [ Failure ] +crbug.com/697971 [ Mac10.12 ] svg/W3C-SVG-1.1-SE/types-dom-01-b.svg [ Failure ] +crbug.com/697971 [ Mac10.12 ] svg/W3C-SVG-1.1-SE/types-dom-05-b.svg [ Failure ] +crbug.com/697971 [ Mac10.12 ] svg/W3C-SVG-1.1/script-handle-02-b.svg [ Failure ] +crbug.com/697971 [ Mac10.12 ] svg/W3C-SVG-1.1/script-handle-03-b.svg [ Failure ] +crbug.com/697971 [ Mac10.12 ] svg/W3C-SVG-1.1/script-handle-04-b.svg [ Failure ] +crbug.com/697971 [ Mac10.12 ] svg/W3C-SVG-1.1/struct-use-05-b.svg [ Failure ] +crbug.com/697971 [ Mac10.12 ] svg/W3C-SVG-1.1/text-fonts-01-t.svg [ Failure ] +crbug.com/697971 [ Mac10.12 ] svg/as-border-image/svg-as-border-image-2.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] svg/as-border-image/svg-as-border-image.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] svg/batik/text/textLayout.svg [ Failure ] +crbug.com/697971 [ Mac10.12 ] svg/custom/focus-ring-text.svg [ Failure ] +crbug.com/697971 [ Mac10.12 ] svg/custom/inline-svg-in-xhtml.xml [ Failure ] +crbug.com/697971 [ Mac10.12 ] svg/hixie/mixed/003.xml [ Failure ] +crbug.com/697971 [ Mac10.12 ] svg/text/surrogate-pair-queries.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] svg/text/text-path-middle-align.svg [ Failure ] +crbug.com/697971 [ Mac10.12 ] svg/text/text-selection-fonts-01-t.svg [ Failure ] +crbug.com/697971 [ Mac10.12 ] svg/transforms/svg-css-transforms-clip-path.xhtml [ Failure ] +crbug.com/697971 [ Mac10.12 ] svg/transforms/svg-css-transforms.xhtml [ Failure ] +crbug.com/697971 [ Mac10.12 ] svg/zoom/page/zoom-background-images.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] tables/mozilla/bugs/bug1188.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] tables/mozilla/bugs/bug1318.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] tables/mozilla/bugs/bug138725.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] tables/mozilla/bugs/bug18359.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] tables/mozilla/bugs/bug194024.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] tables/mozilla/bugs/bug2479-2.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] tables/mozilla/bugs/bug2479-3.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] tables/mozilla/bugs/bug2479-4.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] tables/mozilla/bugs/bug26178.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] tables/mozilla/bugs/bug28928.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] tables/mozilla/bugs/bug29326.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] tables/mozilla/bugs/bug30559.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] tables/mozilla/bugs/bug30692.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] tables/mozilla/bugs/bug33855.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] tables/mozilla/bugs/bug39209.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] tables/mozilla/bugs/bug4382.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] tables/mozilla/bugs/bug4429.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] tables/mozilla/bugs/bug44505.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] tables/mozilla/bugs/bug46368-1.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] tables/mozilla/bugs/bug46368-2.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] tables/mozilla/bugs/bug46480-1.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] tables/mozilla/bugs/bug46480-2.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] tables/mozilla/bugs/bug51037.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] tables/mozilla/bugs/bug51727.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] tables/mozilla/bugs/bug52505.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] tables/mozilla/bugs/bug52506.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] tables/mozilla/bugs/bug59354.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] tables/mozilla/bugs/bug60749.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] tables/mozilla/bugs/bug68912.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] tables/mozilla/bugs/bug7342.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] tables/mozilla/bugs/bug8032-1.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] tables/mozilla/bugs/bug8858.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] tables/mozilla/bugs/bug96334.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] tables/mozilla/collapsing_borders/bug41262-4.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] tables/mozilla/core/bloomberg.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] tables/mozilla/core/margins.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] tables/mozilla/dom/tableDom.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] tables/mozilla/other/move_row.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] tables/mozilla/other/test3.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] tables/mozilla/other/test6.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] tables/mozilla/other/wa_table_thtd_rowspan.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] tables/mozilla/other/wa_table_tr_align.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] tables/mozilla_expected_failures/bugs/bug1128.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] tables/mozilla_expected_failures/bugs/bug1725.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] tables/mozilla_expected_failures/bugs/bug2479-5.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] tables/mozilla_expected_failures/bugs/bug58402-2.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] tables/mozilla_expected_failures/bugs/bug91057.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] tables/mozilla_expected_failures/collapsing_borders/bug41262-5.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] tables/mozilla_expected_failures/collapsing_borders/bug41262-6.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] tables/mozilla_expected_failures/marvin/backgr_fixed-bg.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] transforms/2d/zoom-menulist.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] transforms/svg-vs-css.xhtml [ Failure ] +crbug.com/697971 [ Mac10.12 ] virtual/disable-spinvalidation/paint/invalidation/button-checkbox-click-method-repaint.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] virtual/disable-spinvalidation/paint/invalidation/caret-invalidation-in-overflow-scroll.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] virtual/disable-spinvalidation/paint/invalidation/forms/button-reset-focus-by-mouse-then-keydown.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] virtual/disable-spinvalidation/paint/invalidation/forms/submit-focus-by-mouse-then-keydown.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] virtual/disable-spinvalidation/paint/invalidation/resize-iframe-text.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] virtual/disable-spinvalidation/paint/invalidation/search-field-cancel.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] virtual/disable-spinvalidation/paint/invalidation/subtree-root-skipped.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] virtual/disable-spinvalidation/paint/invalidation/textarea-caret.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] virtual/gpu-rasterization/images/12-55.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] virtual/gpu-rasterization/images/182.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] virtual/gpu-rasterization/images/2-dht.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] virtual/gpu-rasterization/images/23-55.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] virtual/gpu-rasterization/images/55.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] virtual/gpu-rasterization/images/color-profile-background-image-cross-fade-png.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] virtual/gpu-rasterization/images/color-profile-background-image-cross-fade.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] virtual/gpu-rasterization/images/color-profile-mask-image-svg.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] virtual/gpu/fast/canvas/canvas-arc-circumference-fill.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] virtual/gpu/fast/canvas/canvas-arc-circumference.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] virtual/gpu/fast/canvas/canvas-ellipse-circumference-fill.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] virtual/gpu/fast/canvas/canvas-ellipse-circumference.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] virtual/gpu/fast/canvas/canvas-incremental-repaint.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] virtual/mojo-loading/http/tests/filesystem/input-display.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] virtual/mojo-loading/http/tests/inspector-protocol/network-data-length.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] virtual/mojo-loading/http/tests/media/media-source/mediasource-is-type-supported.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] virtual/mojo-loading/http/tests/media/video-buffered-range-contains-currentTime.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] virtual/mojo-loading/http/tests/misc/acid2-pixel.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] virtual/mojo-loading/http/tests/misc/bad-charset-alias.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] virtual/mojo-loading/http/tests/streams/readable-streams/count-queuing-strategy-integration.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] virtual/mojo-loading/http/tests/webfont/popup-menu-load-webfont-after-open.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] virtual/prefer_compositing_to_lcd_text/compositing/overflow/border-radius-styles-with-composited-child.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] virtual/prefer_compositing_to_lcd_text/compositing/overflow/do-not-paint-outline-into-composited-scrolling-contents.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] virtual/prefer_compositing_to_lcd_text/compositing/overflow/theme-affects-visual-overflow.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] virtual/prefer_compositing_to_lcd_text/compositing/overflow/update-widget-positions-on-nested-frames-and-scrollers.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] virtual/prefer_compositing_to_lcd_text/scrollbars/custom-scrollbar-with-incomplete-style.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] virtual/rootlayerscrolls/scrollbars/custom-scrollbar-with-incomplete-style.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] virtual/scalefactor200/fast/hidpi/static/calendar-picker-appearance.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] virtual/scalefactor200/fast/hidpi/static/data-suggestion-picker-appearance.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] virtual/scalefactor200/fast/hidpi/static/popup-menu-appearance.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] virtual/scalefactor200/fast/hidpi/static/popup-menu-with-scrollbar-appearance.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] webaudio/dom-exceptions.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] webaudio/unit-tests/audit.html [ Failure ] +crbug.com/697971 [ Mac10.12 ] fast/text/flexbox-selection-nested.html [ Skip ] +crbug.com/697971 [ Mac10.12 ] fast/text/flexbox-selection.html [ Skip ] +crbug.com/697971 [ Mac10.12 ] http/tests/inspector/appcache/appcache-manifest-with-non-existing-file.html [ Timeout ] +crbug.com/697971 [ Mac10.12 ] virtual/mojo-loading/http/tests/inspector/appcache/appcache-iframe-manifests.html [ Timeout ] + # mojo-loading: This is an experimental feature. failing virtual tests are # listed below. @@ -2483,3 +3079,6 @@ # Sheriff failures 2017-03-10 crbug.com/402805 [ Mac10.10 Mac10.11 ] inspector-protocol/input/emulateTouchFromMouseEvent.html [ Timeout ] +crbug.com/700374 [ Win ] virtual/mojo-loading/http/tests/inspector/workers-on-navigation.html [ Failure Pass ] +crbug.com/700374 [ Win ] http/tests/inspector/workers-on-navigation.html [ Failure Pass ] +crbug.com/700387 [ Win7 ] external/wpt/fullscreen/api/document-exit-fullscreen-nested-in-iframe-manual.html [ Timeout Pass ]
diff --git a/third_party/WebKit/LayoutTests/bindings/record-type.html b/third_party/WebKit/LayoutTests/bindings/record-type.html new file mode 100644 index 0000000..190c21bd --- /dev/null +++ b/third_party/WebKit/LayoutTests/bindings/record-type.html
@@ -0,0 +1,142 @@ +<!DOCTYPE html> +<script src="../resources/testharness.js"></script> +<script src="../resources/testharnessreport.js"></script> +<script> + /* assert_array_equals() uses same_value() to compare each item, but + * Object.entries() returns an array of arrays, so we need to compare + * each item with assert_array_equals instead. */ + function assert_record_equals(actual, expected, description) { + for (let i = 0; i < expected.length; ++i) { + assert_array_equals(Object.entries(actual)[i], expected[i], description); + } + } + + test(() => { + let recordTest = internals.recordTest(); + + assert_throws(new TypeError(), () => { + recordTest.setStringLongRecord(null); + }, "Converting null to record should be rejected."); + assert_throws(new TypeError(), () => { + recordTest.setStringLongRecord(undefined); + }, "Converting undefined to record should be rejected."); + recordTest.setNullableStringLongRecord(null); + assert_equals(recordTest.getNullableStringLongRecord(), + null, "Passing null to a nullable record works"); + recordTest.setNullableStringLongRecord(undefined); + assert_equals(recordTest.getNullableStringLongRecord(), + null, "Passing undefined to a nullable record works"); + }, "Test handling of null and undefined records"); + + test(() => { + let recordTest = internals.recordTest(); + + recordTest.setStringLongRecord({a: true, false: null, c: "foo"}); + assert_record_equals(recordTest.getStringLongRecord(), + [['a', 1], ['false', 0], ['c', 0]], + "Types are properly coerced to the record's types"); + }, "Test type conversion"); + + test(() => { + let recordTest = internals.recordTest(); + + recordTest.setStringLongRecord({false: 1, [false]: 42}); + assert_record_equals(recordTest.getStringLongRecord(), [['false', 42]], + "Key types are coerced and never repeated"); + }, "Test duplicate keys"); + + test(() => { + let recordTest = internals.recordTest(); + + recordTest.setStringLongRecord({z: 42, foo: -5, ABC: 0}); + assert_record_equals(recordTest.getStringLongRecord(), + [['z', 42], ['foo', -5], ['ABC', 0]], + "Keys are not sorted"); + }, "Test mapping order"); + + test(() => { + let recordTest = internals.recordTest(); + + assert_throws(new TypeError(), () => { + recordTest.setByteStringByteStringRecord({'a': 'bc', '\uFFFF': 'foo'}); + }, "Invalid ByteString key must throw a TypeError"); + assert_throws(new TypeError(), () => { + recordTest.setByteStringByteStringRecord({'xy': 'z', 'foo': '\uFFFF'}); + }, "Invalid ByteString value must throw a TypeError"); + }, "Test ByteString validation"); + + test(() => { + let recordTest = internals.recordTest(); + + recordTest.setStringLongRecord({'foo': 0}); + let record = recordTest.getStringLongRecord(); + assert_record_equals(record, [['foo', 0]]); + + record.baz = 'quux'; + assert_equals(Object.keys(recordTest.getStringLongRecord()).length, 1, + "Changing a returned record does not change the record"); + assert_record_equals(recordTest.getStringLongRecord(), [['foo', 0]], + "Changing a returned record does not change the record"); + + assert_record_equals(recordTest.getStringLongRecord(), + Object.entries(recordTest.getStringLongRecord()), + "Record getters always return the same elements"); + assert_not_equals(recordTest.getStringLongRecord(), recordTest.getStringLongRecord(), + "Record getters always return a new copy"); + }, "Test records are passed by value"); + + test(() => { + let recordTest = internals.recordTest(); + + assert_false(recordTest.unionReceivedARecord(true), + "Passing 'true' should convert the union to boolean"); + assert_false(recordTest.unionReceivedARecord(false), + "Passing 'false' should convert the union to boolean"); + assert_false(recordTest.unionReceivedARecord(42), + "Passing a number should convert the union to boolean"); + assert_true(recordTest.unionReceivedARecord([1, 2, 3]), + "Passing an array should convert the union to a record"); + assert_true(recordTest.unionReceivedARecord({}), + "Passing an object should conver the union to a record"); + }, "Test unions resolve records"); + + test(() => { + let recordTest = internals.recordTest(); + + let elem = document.createElement('p'); + recordTest.setStringElementRecord({'elem': elem}); + assert_equals(recordTest.getStringElementRecord().elem, elem, + "The same DOM object was stored in the record"); + assert_not_equals(recordTest.getStringElementRecord().elem, + document.createElement('p'), + "The same DOM object was stored in the record"); + + elem = document.createElement('br'); + assert_not_equals(recordTest.getStringElementRecord().elem, elem, + "Changing the original value does not change the record value"); + }, "Test DOM object types"); + + test(() => { + let recordTest = internals.recordTest(); + let getterAlias = recordTest.getUSVStringUSVStringBooleanRecordRecord; + + recordTest.setUSVStringUSVStringBooleanRecordRecord({'foo': {'bar': true}, 'quux': {'baz': false}}); + let records = recordTest.getUSVStringUSVStringBooleanRecordRecord(); + assert_array_equals(Object.keys(records), ['foo', 'quux'], + "Nested record types have the correct keys"); + assert_record_equals(records.foo, [['bar', true]]); + assert_record_equals(records.quux, [['baz', false]]); + }, "Test nested record types"); + + test(() => { + let recordTest = internals.recordTest(); + + let record = recordTest.returnStringByteStringSequenceRecord(); + assert_array_equals(Object.keys(record), ['foo', 'bar']); + assert_array_equals(record.foo, ['hello, world', 'hi, mom']); + assert_array_equals(record.bar, ['goodbye, mom']); + + let other_record = recordTest.returnStringByteStringSequenceRecord(); + assert_not_equals(record, other_record, "A new object is returned each time"); + }, "Test sequences in records"); +</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/background_fetch/getTags.html b/third_party/WebKit/LayoutTests/http/tests/background_fetch/getTags.html new file mode 100644 index 0000000..b6d1e9c --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/background_fetch/getTags.html
@@ -0,0 +1,41 @@ +<!doctype html> +<html> + <head> + <title>Background Fetch: BackgroundFetchManager.getTags() behaviour.</title> + <script src="../resources/testharness.js"></script> + <script src="../resources/testharnessreport.js"></script> + <script src="../serviceworker/resources/test-helpers.js"></script> + </head> + <body> + <script> + // TODO(peter): Remove this test when the IDL harness test has landed as + // part of web platform tests. + test(function() { + assert_own_property(self, 'BackgroundFetchManager', 'BackgroundFetchManager needs to be exposed as a global.'); + // TODO(peter): Test for the `fetch` method. + // TODO(peter): Test for the `get` method. + + assert_own_property(BackgroundFetchManager.prototype, 'getTags'); + + }, 'BackgroundFetchManager should be exposed and have the expected interface in a Document.'); + + // TODO(peter): Move this to a WPT test when the getTags() function is able + // to reflect in-progress background fetches. + promise_test(async function(test) { + const workerUrl = 'resources/empty-worker.js'; + const scope = 'resources/scope/' + location.pathname; + + const registration = await service_worker_unregister_and_register(test, workerUrl, scope); + await wait_for_state(test, registration.installing, 'activated'); + + try { + await registration.backgroundFetch.getTags(); + assert_unreached('getTags() is expected to throw.'); + } catch (exception) { + assert_equals(exception.name, 'NotSupportedError'); + assert_equals(exception.message, 'Not implemented yet.'); + } + }, 'Change-detector test for the getTags() function.'); + </script> + </body> +</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/background_fetch/resources/empty-worker.js b/third_party/WebKit/LayoutTests/http/tests/background_fetch/resources/empty-worker.js new file mode 100644 index 0000000..49ceb264 --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/background_fetch/resources/empty-worker.js
@@ -0,0 +1 @@ +// Do nothing.
diff --git a/third_party/WebKit/LayoutTests/http/tests/serviceworker/chromium/navigation-preload-origin-trial-interfaces-expected.txt b/third_party/WebKit/LayoutTests/http/tests/serviceworker/chromium/navigation-preload-origin-trial-interfaces-expected.txt index 46f223b8..bd27af16 100644 --- a/third_party/WebKit/LayoutTests/http/tests/serviceworker/chromium/navigation-preload-origin-trial-interfaces-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/serviceworker/chromium/navigation-preload-origin-trial-interfaces-expected.txt
@@ -8,6 +8,7 @@ method setHeaderValue interface ServiceWorkerRegistration getter active + getter backgroundFetch getter installing getter navigationPreload getter onupdatefound @@ -31,6 +32,7 @@ method respondWith interface ServiceWorkerRegistration getter active + getter backgroundFetch getter installing getter onupdatefound getter paymentAppManager @@ -60,6 +62,7 @@ method setHeaderValue interface ServiceWorkerRegistration getter active + getter backgroundFetch getter installing getter navigationPreload getter onupdatefound
diff --git a/third_party/WebKit/LayoutTests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt b/third_party/WebKit/LayoutTests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt index a8a5d7bf..376463a 100644 --- a/third_party/WebKit/LayoutTests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
@@ -1,3 +1,6 @@ +interface BackgroundFetchManager + method constructor + method getTags interface BarcodeDetector method constructor method detect @@ -820,6 +823,7 @@ method constructor interface ServiceWorkerRegistration : EventTarget getter active + getter backgroundFetch getter installing getter onupdatefound getter paymentAppManager
diff --git a/third_party/WebKit/LayoutTests/virtual/service-worker-navigation-preload-disabled/http/tests/serviceworker/chromium/navigation-preload-origin-trial-interfaces-expected.txt b/third_party/WebKit/LayoutTests/virtual/service-worker-navigation-preload-disabled/http/tests/serviceworker/chromium/navigation-preload-origin-trial-interfaces-expected.txt index 46f223b8..bd27af16 100644 --- a/third_party/WebKit/LayoutTests/virtual/service-worker-navigation-preload-disabled/http/tests/serviceworker/chromium/navigation-preload-origin-trial-interfaces-expected.txt +++ b/third_party/WebKit/LayoutTests/virtual/service-worker-navigation-preload-disabled/http/tests/serviceworker/chromium/navigation-preload-origin-trial-interfaces-expected.txt
@@ -8,6 +8,7 @@ method setHeaderValue interface ServiceWorkerRegistration getter active + getter backgroundFetch getter installing getter navigationPreload getter onupdatefound @@ -31,6 +32,7 @@ method respondWith interface ServiceWorkerRegistration getter active + getter backgroundFetch getter installing getter onupdatefound getter paymentAppManager @@ -60,6 +62,7 @@ method setHeaderValue interface ServiceWorkerRegistration getter active + getter backgroundFetch getter installing getter navigationPreload getter onupdatefound
diff --git a/third_party/WebKit/LayoutTests/virtual/service-worker-navigation-preload/http/tests/serviceworker/chromium/navigation-preload-origin-trial-interfaces-expected.txt b/third_party/WebKit/LayoutTests/virtual/service-worker-navigation-preload/http/tests/serviceworker/chromium/navigation-preload-origin-trial-interfaces-expected.txt index d1ddd9d0..e8ca128e 100644 --- a/third_party/WebKit/LayoutTests/virtual/service-worker-navigation-preload/http/tests/serviceworker/chromium/navigation-preload-origin-trial-interfaces-expected.txt +++ b/third_party/WebKit/LayoutTests/virtual/service-worker-navigation-preload/http/tests/serviceworker/chromium/navigation-preload-origin-trial-interfaces-expected.txt
@@ -8,6 +8,7 @@ method setHeaderValue interface ServiceWorkerRegistration getter active + getter backgroundFetch getter installing getter navigationPreload getter onupdatefound @@ -38,6 +39,7 @@ method setHeaderValue interface ServiceWorkerRegistration getter active + getter backgroundFetch getter installing getter navigationPreload getter onupdatefound @@ -68,6 +70,7 @@ method setHeaderValue interface ServiceWorkerRegistration getter active + getter backgroundFetch getter installing getter navigationPreload getter onupdatefound
diff --git a/third_party/WebKit/LayoutTests/virtual/service-worker-navigation-preload/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt b/third_party/WebKit/LayoutTests/virtual/service-worker-navigation-preload/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt index ef85d30..b2fe4c88 100644 --- a/third_party/WebKit/LayoutTests/virtual/service-worker-navigation-preload/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt +++ b/third_party/WebKit/LayoutTests/virtual/service-worker-navigation-preload/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
@@ -1,3 +1,6 @@ +interface BackgroundFetchManager + method constructor + method getTags interface BarcodeDetector method constructor method detect @@ -827,6 +830,7 @@ method constructor interface ServiceWorkerRegistration : EventTarget getter active + getter backgroundFetch getter installing getter navigationPreload getter onupdatefound
diff --git a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-dedicated-worker-expected.txt b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-dedicated-worker-expected.txt index 9660576c..3a405602 100644 --- a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-dedicated-worker-expected.txt +++ b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-dedicated-worker-expected.txt
@@ -5,6 +5,10 @@ Starting worker: resources/global-interface-listing.js [Worker] [INTERFACES] +[Worker] interface BackgroundFetchManager +[Worker] attribute @@toStringTag +[Worker] method constructor +[Worker] method getTags [Worker] interface BarcodeDetector [Worker] attribute @@toStringTag [Worker] method constructor @@ -833,6 +837,7 @@ [Worker] interface ServiceWorkerRegistration : EventTarget [Worker] attribute @@toStringTag [Worker] getter active +[Worker] getter backgroundFetch [Worker] getter installing [Worker] getter onupdatefound [Worker] getter paymentAppManager
diff --git a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt index 43318d6..4c9b8b2 100644 --- a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt +++ b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt
@@ -258,6 +258,10 @@ getter credential getter signature method constructor +interface BackgroundFetchManager + attribute @@toStringTag + method constructor + method getTags interface BarProp attribute @@toStringTag getter visible @@ -6395,6 +6399,7 @@ interface ServiceWorkerRegistration : EventTarget attribute @@toStringTag getter active + getter backgroundFetch getter installing getter onupdatefound getter paymentAppManager
diff --git a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-shared-worker-expected.txt b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-shared-worker-expected.txt index 9d8c96f3..9d81b6c 100644 --- a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-shared-worker-expected.txt +++ b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-shared-worker-expected.txt
@@ -5,6 +5,10 @@ Starting worker: resources/global-interface-listing.js [Worker] [INTERFACES] +[Worker] interface BackgroundFetchManager +[Worker] attribute @@toStringTag +[Worker] method constructor +[Worker] method getTags [Worker] interface BarcodeDetector [Worker] attribute @@toStringTag [Worker] method constructor @@ -828,6 +832,7 @@ [Worker] interface ServiceWorkerRegistration : EventTarget [Worker] attribute @@toStringTag [Worker] getter active +[Worker] getter backgroundFetch [Worker] getter installing [Worker] getter onupdatefound [Worker] getter paymentAppManager
diff --git a/third_party/WebKit/Source/bindings/bindings.gni b/third_party/WebKit/Source/bindings/bindings.gni index 19b58f8..057f211 100644 --- a/third_party/WebKit/Source/bindings/bindings.gni +++ b/third_party/WebKit/Source/bindings/bindings.gni
@@ -233,6 +233,7 @@ get_path_info([ "core/v8/DocumentWriteEvaluatorTest.cpp", "core/v8/IDLTypesTest.cpp", + "core/v8/NativeValueTraitsImplTest.cpp", "core/v8/NativeValueTraitsTest.cpp", "core/v8/ScriptPromisePropertyTest.cpp", "core/v8/ScriptPromiseResolverTest.cpp",
diff --git a/third_party/WebKit/Source/bindings/core/v8/BUILD.gn b/third_party/WebKit/Source/bindings/core/v8/BUILD.gn index f40694d3..3219d73 100644 --- a/third_party/WebKit/Source/bindings/core/v8/BUILD.gn +++ b/third_party/WebKit/Source/bindings/core/v8/BUILD.gn
@@ -174,6 +174,8 @@ "$bindings_core_v8_output_dir/ArrayBufferOrArrayBufferViewOrBlobOrDocumentOrStringOrFormDataOrURLSearchParams.h", "$bindings_core_v8_output_dir/ArrayBufferOrArrayBufferViewOrBlobOrUSVString.cpp", "$bindings_core_v8_output_dir/ArrayBufferOrArrayBufferViewOrBlobOrUSVString.h", + "$bindings_core_v8_output_dir/BooleanOrByteStringByteStringRecord.cpp", + "$bindings_core_v8_output_dir/BooleanOrByteStringByteStringRecord.h", "$bindings_core_v8_output_dir/CSSStyleValueOrCSSStyleValueSequence.cpp", "$bindings_core_v8_output_dir/CSSStyleValueOrCSSStyleValueSequence.h", "$bindings_core_v8_output_dir/CSSStyleValueOrCSSStyleValueSequenceOrString.cpp", @@ -196,6 +198,8 @@ "$bindings_core_v8_output_dir/EventListenerOptionsOrBoolean.h", "$bindings_core_v8_output_dir/FileOrUSVString.cpp", "$bindings_core_v8_output_dir/FileOrUSVString.h", + "$bindings_core_v8_output_dir/FloatOrStringElementRecord.cpp", + "$bindings_core_v8_output_dir/FloatOrStringElementRecord.h", "$bindings_core_v8_output_dir/HTMLElementOrLong.cpp", "$bindings_core_v8_output_dir/HTMLElementOrLong.h", "$bindings_core_v8_output_dir/HTMLImageElementOrHTMLVideoElementOrHTMLCanvasElementOrBlobOrImageDataOrImageBitmapOrOffscreenCanvas.cpp",
diff --git a/third_party/WebKit/Source/bindings/core/v8/IDLTypes.h b/third_party/WebKit/Source/bindings/core/v8/IDLTypes.h index ac9546e..1dfff49c 100644 --- a/third_party/WebKit/Source/bindings/core/v8/IDLTypes.h +++ b/third_party/WebKit/Source/bindings/core/v8/IDLTypes.h
@@ -54,7 +54,7 @@ struct IDLSequence final : public IDLBase { private: using CppType = typename NativeValueTraits<T>::ImplType; - using MaybeWrappedCppType = + using MaybeMemberCppType = typename std::conditional<WTF::IsGarbageCollectedType<CppType>::value, Member<CppType>, CppType>::type; @@ -67,12 +67,42 @@ // contain Oilpan members. They both also happen to specialize V8TypeOf, // which we use to recognize them. using ImplType = typename std::conditional< - std::is_same<MaybeWrappedCppType, Member<CppType>>::value || + std::is_same<MaybeMemberCppType, Member<CppType>>::value || std::is_class<typename V8TypeOf<CppType>::Type>::value, - HeapVector<MaybeWrappedCppType>, + HeapVector<MaybeMemberCppType>, Vector<CppType>>::type; }; +// Record +template <typename Key, typename Value> +struct IDLRecord final : public IDLBase { + static_assert(std::is_same<Key, IDLByteString>::value || + std::is_same<Key, IDLString>::value || + std::is_same<Key, IDLUSVString>::value, + "IDLRecord keys must be of a WebIDL string type"); + + private: + // Record keys are always strings, so we do not need to introspect them. + using ValueCppType = typename NativeValueTraits<Value>::ImplType; + using MaybeMemberValueCppType = typename std::conditional< + WTF::IsGarbageCollectedType<ValueCppType>::value, + Member<ValueCppType>, + ValueCppType>::type; + + public: + // Two kinds of types need HeapVector: + // 1. Oilpan types, which are wrapped by Member<>. + // 2. IDL unions and dictionaries, which are not Oilpan types themselves (and + // are thus not wrapped by Member<>) but have a trace() method and can + // contain Oilpan members. They both also happen to specialize V8TypeOf, + // which we use to recognize them. + using ImplType = typename std::conditional< + std::is_same<MaybeMemberValueCppType, Member<ValueCppType>>::value || + std::is_class<typename V8TypeOf<ValueCppType>::Type>::value, + HeapVector<std::pair<String, MaybeMemberValueCppType>>, + Vector<std::pair<String, ValueCppType>>>::type; +}; + } // namespace blink #endif // IDLTypes_h
diff --git a/third_party/WebKit/Source/bindings/core/v8/IDLTypesTest.cpp b/third_party/WebKit/Source/bindings/core/v8/IDLTypesTest.cpp index 7115652f..a2ef41302 100644 --- a/third_party/WebKit/Source/bindings/core/v8/IDLTypesTest.cpp +++ b/third_party/WebKit/Source/bindings/core/v8/IDLTypesTest.cpp
@@ -117,6 +117,28 @@ HeapVector<DictionarySequenceOrDictionary>>::value, "IDLSequence<union type> produces a HeapVector"); +static_assert(std::is_base_of<IDLBase, IDLRecord<IDLString, IDLShort>>::value, + "IDLRecord inherits from IDLBase"); +static_assert(std::is_base_of<IDLBase, IDLRecord<IDLString, Element>>::value, + "IDLRecord inherits from IDLBase"); +static_assert(std::is_same<IDLRecord<IDLByteString, IDLLong>::ImplType, + Vector<std::pair<String, int32_t>>>::value, + "IDLRecord<IDLByteString, IDLLong> produces a Vector"); +static_assert( + std::is_same<IDLRecord<IDLByteString, Element>::ImplType, + HeapVector<std::pair<String, Member<Element>>>>::value, + "IDLRecord<IDLByteString, GC-type>> produces a HeapVector with Member<>"); +static_assert( + std::is_same<IDLRecord<IDLUSVString, InternalDictionary>::ImplType, + HeapVector<std::pair<String, InternalDictionary>>>::value, + "IDLRecord<IDLUSVString, dictionary type> produces a HeapVector with no " + "Member<>"); +static_assert( + std::is_same< + IDLRecord<IDLString, DictionarySequenceOrDictionary>::ImplType, + HeapVector<std::pair<String, DictionarySequenceOrDictionary>>>::value, + "IDLRecord<IDLString, union type> produces a HeapVector with no Member<>"); + } // namespace } // namespace blink
diff --git a/third_party/WebKit/Source/bindings/core/v8/NativeValueTraitsImpl.h b/third_party/WebKit/Source/bindings/core/v8/NativeValueTraitsImpl.h index 7dfb3fb..3fc5b6d6 100644 --- a/third_party/WebKit/Source/bindings/core/v8/NativeValueTraitsImpl.h +++ b/third_party/WebKit/Source/bindings/core/v8/NativeValueTraitsImpl.h
@@ -17,9 +17,9 @@ template <> struct CORE_EXPORT NativeValueTraits<IDLBoolean> : public NativeValueTraitsBase<IDLBoolean> { - static inline bool nativeValue(v8::Isolate* isolate, - v8::Local<v8::Value> value, - ExceptionState& exceptionState) { + static bool nativeValue(v8::Isolate* isolate, + v8::Local<v8::Value> value, + ExceptionState& exceptionState) { return toBoolean(isolate, value, exceptionState); } }; @@ -33,17 +33,16 @@ template <> struct CORE_EXPORT NativeValueTraits<IDLByte> : public NativeValueTraitsBase<IDLByte> { - static inline int8_t nativeValue(v8::Isolate* isolate, - v8::Local<v8::Value> value, - ExceptionState& exceptionState) { + static int8_t nativeValue(v8::Isolate* isolate, + v8::Local<v8::Value> value, + ExceptionState& exceptionState) { return nativeValue(isolate, value, exceptionState, NormalConversion); } - static inline int8_t nativeValue( - v8::Isolate* isolate, - v8::Local<v8::Value> value, - ExceptionState& exceptionState, - IntegerConversionConfiguration conversionMode) { + static int8_t nativeValue(v8::Isolate* isolate, + v8::Local<v8::Value> value, + ExceptionState& exceptionState, + IntegerConversionConfiguration conversionMode) { return toInt8(isolate, value, conversionMode, exceptionState); } }; @@ -51,17 +50,16 @@ template <> struct CORE_EXPORT NativeValueTraits<IDLOctet> : public NativeValueTraitsBase<IDLOctet> { - static inline uint8_t nativeValue(v8::Isolate* isolate, - v8::Local<v8::Value> value, - ExceptionState& exceptionState) { + static uint8_t nativeValue(v8::Isolate* isolate, + v8::Local<v8::Value> value, + ExceptionState& exceptionState) { return nativeValue(isolate, value, exceptionState, NormalConversion); } - static inline uint8_t nativeValue( - v8::Isolate* isolate, - v8::Local<v8::Value> value, - ExceptionState& exceptionState, - IntegerConversionConfiguration conversionMode) { + static uint8_t nativeValue(v8::Isolate* isolate, + v8::Local<v8::Value> value, + ExceptionState& exceptionState, + IntegerConversionConfiguration conversionMode) { return toUInt8(isolate, value, conversionMode, exceptionState); } }; @@ -69,17 +67,16 @@ template <> struct CORE_EXPORT NativeValueTraits<IDLShort> : public NativeValueTraitsBase<IDLShort> { - static inline int16_t nativeValue(v8::Isolate* isolate, - v8::Local<v8::Value> value, - ExceptionState& exceptionState) { + static int16_t nativeValue(v8::Isolate* isolate, + v8::Local<v8::Value> value, + ExceptionState& exceptionState) { return nativeValue(isolate, value, exceptionState, NormalConversion); } - static inline int16_t nativeValue( - v8::Isolate* isolate, - v8::Local<v8::Value> value, - ExceptionState& exceptionState, - IntegerConversionConfiguration conversionMode) { + static int16_t nativeValue(v8::Isolate* isolate, + v8::Local<v8::Value> value, + ExceptionState& exceptionState, + IntegerConversionConfiguration conversionMode) { return toInt16(isolate, value, conversionMode, exceptionState); } }; @@ -87,17 +84,16 @@ template <> struct CORE_EXPORT NativeValueTraits<IDLUnsignedShort> : public NativeValueTraitsBase<IDLUnsignedShort> { - static inline uint16_t nativeValue(v8::Isolate* isolate, - v8::Local<v8::Value> value, - ExceptionState& exceptionState) { + static uint16_t nativeValue(v8::Isolate* isolate, + v8::Local<v8::Value> value, + ExceptionState& exceptionState) { return nativeValue(isolate, value, exceptionState, NormalConversion); } - static inline uint16_t nativeValue( - v8::Isolate* isolate, - v8::Local<v8::Value> value, - ExceptionState& exceptionState, - IntegerConversionConfiguration conversionMode) { + static uint16_t nativeValue(v8::Isolate* isolate, + v8::Local<v8::Value> value, + ExceptionState& exceptionState, + IntegerConversionConfiguration conversionMode) { return toUInt16(isolate, value, conversionMode, exceptionState); } }; @@ -105,17 +101,16 @@ template <> struct CORE_EXPORT NativeValueTraits<IDLLong> : public NativeValueTraitsBase<IDLLong> { - static inline int32_t nativeValue(v8::Isolate* isolate, - v8::Local<v8::Value> value, - ExceptionState& exceptionState) { + static int32_t nativeValue(v8::Isolate* isolate, + v8::Local<v8::Value> value, + ExceptionState& exceptionState) { return nativeValue(isolate, value, exceptionState, NormalConversion); } - static inline int32_t nativeValue( - v8::Isolate* isolate, - v8::Local<v8::Value> value, - ExceptionState& exceptionState, - IntegerConversionConfiguration conversionMode) { + static int32_t nativeValue(v8::Isolate* isolate, + v8::Local<v8::Value> value, + ExceptionState& exceptionState, + IntegerConversionConfiguration conversionMode) { return toInt32(isolate, value, conversionMode, exceptionState); } }; @@ -123,17 +118,16 @@ template <> struct CORE_EXPORT NativeValueTraits<IDLUnsignedLong> : public NativeValueTraitsBase<IDLUnsignedLong> { - static inline uint32_t nativeValue(v8::Isolate* isolate, - v8::Local<v8::Value> value, - ExceptionState& exceptionState) { + static uint32_t nativeValue(v8::Isolate* isolate, + v8::Local<v8::Value> value, + ExceptionState& exceptionState) { return nativeValue(isolate, value, exceptionState, NormalConversion); } - static inline uint32_t nativeValue( - v8::Isolate* isolate, - v8::Local<v8::Value> value, - ExceptionState& exceptionState, - IntegerConversionConfiguration conversionMode) { + static uint32_t nativeValue(v8::Isolate* isolate, + v8::Local<v8::Value> value, + ExceptionState& exceptionState, + IntegerConversionConfiguration conversionMode) { return toUInt32(isolate, value, conversionMode, exceptionState); } }; @@ -141,17 +135,16 @@ template <> struct CORE_EXPORT NativeValueTraits<IDLLongLong> : public NativeValueTraitsBase<IDLLongLong> { - static inline int64_t nativeValue(v8::Isolate* isolate, - v8::Local<v8::Value> value, - ExceptionState& exceptionState) { + static int64_t nativeValue(v8::Isolate* isolate, + v8::Local<v8::Value> value, + ExceptionState& exceptionState) { return nativeValue(isolate, value, exceptionState, NormalConversion); } - static inline int64_t nativeValue( - v8::Isolate* isolate, - v8::Local<v8::Value> value, - ExceptionState& exceptionState, - IntegerConversionConfiguration conversionMode) { + static int64_t nativeValue(v8::Isolate* isolate, + v8::Local<v8::Value> value, + ExceptionState& exceptionState, + IntegerConversionConfiguration conversionMode) { return toInt64(isolate, value, conversionMode, exceptionState); } }; @@ -159,17 +152,16 @@ template <> struct CORE_EXPORT NativeValueTraits<IDLUnsignedLongLong> : public NativeValueTraitsBase<IDLUnsignedLongLong> { - static inline uint64_t nativeValue(v8::Isolate* isolate, - v8::Local<v8::Value> value, - ExceptionState& exceptionState) { + static uint64_t nativeValue(v8::Isolate* isolate, + v8::Local<v8::Value> value, + ExceptionState& exceptionState) { return nativeValue(isolate, value, exceptionState, NormalConversion); } - static inline uint64_t nativeValue( - v8::Isolate* isolate, - v8::Local<v8::Value> value, - ExceptionState& exceptionState, - IntegerConversionConfiguration conversionMode) { + static uint64_t nativeValue(v8::Isolate* isolate, + v8::Local<v8::Value> value, + ExceptionState& exceptionState, + IntegerConversionConfiguration conversionMode) { return toUInt64(isolate, value, conversionMode, exceptionState); } }; @@ -178,9 +170,9 @@ template <> struct CORE_EXPORT NativeValueTraits<IDLByteString> : public NativeValueTraitsBase<IDLByteString> { - static inline String nativeValue(v8::Isolate* isolate, - v8::Local<v8::Value> value, - ExceptionState& exceptionState) { + static String nativeValue(v8::Isolate* isolate, + v8::Local<v8::Value> value, + ExceptionState& exceptionState) { return toByteString(isolate, value, exceptionState); } }; @@ -188,17 +180,17 @@ template <> struct CORE_EXPORT NativeValueTraits<IDLString> : public NativeValueTraitsBase<IDLString> { - static inline String nativeValue(v8::Isolate* isolate, - v8::Local<v8::Value> value, - ExceptionState& exceptionState) { + static String nativeValue(v8::Isolate* isolate, + v8::Local<v8::Value> value, + ExceptionState& exceptionState) { return nativeValue<V8StringResourceMode::DefaultMode>(isolate, value, exceptionState); } template <V8StringResourceMode Mode = DefaultMode> - static inline String nativeValue(v8::Isolate* isolate, - v8::Local<v8::Value> value, - ExceptionState& exceptionState) { + static String nativeValue(v8::Isolate* isolate, + v8::Local<v8::Value> value, + ExceptionState& exceptionState) { V8StringResource<Mode> string(value); if (!string.prepare(isolate, exceptionState)) return String(); @@ -209,9 +201,9 @@ template <> struct CORE_EXPORT NativeValueTraits<IDLUSVString> : public NativeValueTraitsBase<IDLUSVString> { - static inline String nativeValue(v8::Isolate* isolate, - v8::Local<v8::Value> value, - ExceptionState& exceptionState) { + static String nativeValue(v8::Isolate* isolate, + v8::Local<v8::Value> value, + ExceptionState& exceptionState) { return toUSVString(isolate, value, exceptionState); } }; @@ -220,9 +212,9 @@ template <> struct CORE_EXPORT NativeValueTraits<IDLDouble> : public NativeValueTraitsBase<IDLDouble> { - static inline double nativeValue(v8::Isolate* isolate, - v8::Local<v8::Value> value, - ExceptionState& exceptionState) { + static double nativeValue(v8::Isolate* isolate, + v8::Local<v8::Value> value, + ExceptionState& exceptionState) { return toRestrictedDouble(isolate, value, exceptionState); } }; @@ -230,9 +222,9 @@ template <> struct CORE_EXPORT NativeValueTraits<IDLUnrestrictedDouble> : public NativeValueTraitsBase<IDLUnrestrictedDouble> { - static inline double nativeValue(v8::Isolate* isolate, - v8::Local<v8::Value> value, - ExceptionState& exceptionState) { + static double nativeValue(v8::Isolate* isolate, + v8::Local<v8::Value> value, + ExceptionState& exceptionState) { return toDouble(isolate, value, exceptionState); } }; @@ -240,9 +232,9 @@ template <> struct CORE_EXPORT NativeValueTraits<IDLFloat> : public NativeValueTraitsBase<IDLFloat> { - static inline float nativeValue(v8::Isolate* isolate, - v8::Local<v8::Value> value, - ExceptionState& exceptionState) { + static float nativeValue(v8::Isolate* isolate, + v8::Local<v8::Value> value, + ExceptionState& exceptionState) { return toRestrictedFloat(isolate, value, exceptionState); } }; @@ -250,9 +242,9 @@ template <> struct CORE_EXPORT NativeValueTraits<IDLUnrestrictedFloat> : public NativeValueTraitsBase<IDLUnrestrictedFloat> { - static inline float nativeValue(v8::Isolate* isolate, - v8::Local<v8::Value> value, - ExceptionState& exceptionState) { + static float nativeValue(v8::Isolate* isolate, + v8::Local<v8::Value> value, + ExceptionState& exceptionState) { return toFloat(isolate, value, exceptionState); } }; @@ -261,14 +253,14 @@ template <> struct CORE_EXPORT NativeValueTraits<IDLPromise> : public NativeValueTraitsBase<IDLPromise> { - static inline ScriptPromise nativeValue(v8::Isolate* isolate, - v8::Local<v8::Value> value, - ExceptionState& exceptionState) { + static ScriptPromise nativeValue(v8::Isolate* isolate, + v8::Local<v8::Value> value, + ExceptionState& exceptionState) { return nativeValue(isolate, value); } - static inline ScriptPromise nativeValue(v8::Isolate* isolate, - v8::Local<v8::Value> value) { + static ScriptPromise nativeValue(v8::Isolate* isolate, + v8::Local<v8::Value> value) { return ScriptPromise::cast(ScriptState::current(isolate), value); } }; @@ -277,9 +269,9 @@ template <> struct CORE_EXPORT NativeValueTraits<IDLDate> : public NativeValueTraitsBase<IDLDate> { - static inline double nativeValue(v8::Isolate* isolate, - v8::Local<v8::Value> value, - ExceptionState& exceptionState) { + static double nativeValue(v8::Isolate* isolate, + v8::Local<v8::Value> value, + ExceptionState& exceptionState) { return toCoreDate(isolate, value, exceptionState); } }; @@ -291,20 +283,145 @@ // Nondependent types need to be explicitly qualified to be accessible. using typename NativeValueTraitsBase<IDLSequence<T>>::ImplType; - static inline ImplType nativeValue(v8::Isolate* isolate, - v8::Local<v8::Value> value, - ExceptionState& exceptionState) { + static ImplType nativeValue(v8::Isolate* isolate, + v8::Local<v8::Value> value, + ExceptionState& exceptionState) { return nativeValue(isolate, value, exceptionState, 0); } - static inline ImplType nativeValue(v8::Isolate* isolate, - v8::Local<v8::Value> value, - ExceptionState& exceptionState, - int index) { + static ImplType nativeValue(v8::Isolate* isolate, + v8::Local<v8::Value> value, + ExceptionState& exceptionState, + int index) { return toImplArray<ImplType, T>(value, index, isolate, exceptionState); } }; +// Records +template <typename K, typename V> +struct NativeValueTraits<IDLRecord<K, V>> + : public NativeValueTraitsBase<IDLRecord<K, V>> { + // Nondependent types need to be explicitly qualified to be accessible. + using typename NativeValueTraitsBase<IDLRecord<K, V>>::ImplType; + + // Converts a JavaScript value |O| to an IDL record<K, V> value. In C++, a + // record is represented as a Vector<std::pair<k, v>> (or a HeapVector if + // necessary). See https://heycam.github.io/webidl/#es-record. + static ImplType nativeValue(v8::Isolate* isolate, + v8::Local<v8::Value> v8Value, + ExceptionState& exceptionState) { + v8::Local<v8::Context> context = isolate->GetCurrentContext(); + + // "1. If Type(O) is not Object, throw a TypeError." + if (!v8Value->IsObject()) { + exceptionState.throwTypeError( + "Only objects can be converted to record<K,V> types"); + return ImplType(); + } + v8::Local<v8::Object> v8Object = v8::Local<v8::Object>::Cast(v8Value); + v8::TryCatch block(isolate); + + // "3. Let keys be ? O.[[OwnPropertyKeys]]()." + v8::Local<v8::Array> keys; + // While we could pass v8::ONLY_ENUMERABLE below, doing so breaks + // web-platform-tests' headers-record.html and deviates from the spec + // algorithm. + // Symbols are being skipped due to + // https://github.com/heycam/webidl/issues/294. + if (!v8Object + ->GetOwnPropertyNames(context, + static_cast<v8::PropertyFilter>( + v8::PropertyFilter::ALL_PROPERTIES | + v8::PropertyFilter::SKIP_SYMBOLS)) + .ToLocal(&keys)) { + exceptionState.rethrowV8Exception(block.Exception()); + return ImplType(); + } + if (keys->Length() > ImplType::maxCapacity()) { + exceptionState.throwRangeError("Array length exceeds supported limit."); + return ImplType(); + } + + // "2. Let result be a new empty instance of record<K, V>." + ImplType result; + result.reserveInitialCapacity(keys->Length()); + + // The conversion algorithm needs a data structure with fast insertion at + // the end while at the same time requiring fast checks for previous insert + // of a given key. |seenKeys| is a key/position in |result| map that aids in + // the latter part. + HashMap<String, size_t> seenKeys; + + for (uint32_t i = 0; i < keys->Length(); ++i) { + // "4. Repeat, for each element key of keys in List order:" + v8::Local<v8::Value> key; + if (!keys->Get(context, i).ToLocal(&key)) { + exceptionState.rethrowV8Exception(block.Exception()); + return ImplType(); + } + + // "4.1. Let desc be ? O.[[GetOwnProperty]](key)." + v8::Local<v8::Value> desc; + if (!v8Object + ->GetOwnPropertyDescriptor( + context, key->ToString(context).ToLocalChecked()) + .ToLocal(&desc)) { + exceptionState.rethrowV8Exception(block.Exception()); + return ImplType(); + } + + // "4.2. If desc is not undefined and desc.[[Enumerable]] is true:" + // We can call ToLocalChecked() and ToChecked() here because + // GetOwnPropertyDescriptor is responsible for catching any exceptions + // and failures, and if we got to this point of the code we have a proper + // object that was not created by a user. + DCHECK(desc->IsObject()); + v8::Local<v8::Value> enumerable = + v8::Local<v8::Object>::Cast(desc) + ->Get(context, v8String(isolate, "enumerable")) + .ToLocalChecked(); + if (!enumerable->BooleanValue(context).ToChecked()) + continue; + + // "4.2.1. Let typedKey be key converted to an IDL value of type K." + String typedKey = + NativeValueTraits<K>::nativeValue(isolate, key, exceptionState); + if (exceptionState.hadException()) + return ImplType(); + + // "4.2.2. Let value be ? Get(O, key)." + v8::Local<v8::Value> value; + if (!v8Object->Get(context, key).ToLocal(&value)) { + exceptionState.rethrowV8Exception(block.Exception()); + return ImplType(); + } + + // "4.2.3. Let typedValue be value converted to an IDL value of type V." + typename ImplType::ValueType::second_type typedValue = + NativeValueTraits<V>::nativeValue(isolate, value, exceptionState); + if (exceptionState.hadException()) + return ImplType(); + + if (seenKeys.contains(typedKey)) { + // "4.2.4. If typedKey is already a key in result, set its value to + // typedValue. + // Note: This can happen when O is a proxy object." + const size_t pos = seenKeys.at(typedKey); + result[pos] = std::make_pair(typedKey, typedValue); + } else { + // "4.2.5. Otherwise, append to result a mapping (typedKey, + // typedValue)." + // Note we can take this shortcut because we are always appending. + const size_t pos = result.size(); + seenKeys.set(typedKey, pos); + result.uncheckedAppend(std::make_pair(typedKey, typedValue)); + } + } + // "5. Return result." + return result; + } +}; + } // namespace blink #endif // NativeValueTraitsImpl_h
diff --git a/third_party/WebKit/Source/bindings/core/v8/NativeValueTraitsImplTest.cpp b/third_party/WebKit/Source/bindings/core/v8/NativeValueTraitsImplTest.cpp new file mode 100644 index 0000000..5c3b2e4a7 --- /dev/null +++ b/third_party/WebKit/Source/bindings/core/v8/NativeValueTraitsImplTest.cpp
@@ -0,0 +1,245 @@ +// 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 "bindings/core/v8/NativeValueTraitsImpl.h" + +#include <utility> +#include "bindings/core/v8/ExceptionState.h" +#include "bindings/core/v8/IDLTypes.h" +#include "bindings/core/v8/ToV8.h" +#include "bindings/core/v8/V8BindingForTesting.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "wtf/Vector.h" + +namespace blink { + +namespace { + +template <typename T> +v8::Local<v8::Value> ToV8(V8TestingScope* scope, T value) { + return blink::ToV8(value, scope->context()->Global(), scope->isolate()); +} + +void ThrowException(v8::Local<v8::Name>, + const v8::PropertyCallbackInfo<v8::Value>& info) { + info.GetIsolate()->ThrowException(v8String(info.GetIsolate(), "bogus!")); +} + +void ReturnBogusObjectDescriptor( + const v8::FunctionCallbackInfo<v8::Value>& info) { + v8::Isolate* isolate = info.GetIsolate(); + auto context = isolate->GetCurrentContext(); + + v8::Local<v8::Object> descriptor = v8::Object::New(isolate); + EXPECT_TRUE( + v8CallBoolean(descriptor->Set(context, v8String(isolate, "configurable"), + v8::Boolean::New(isolate, true)))); + EXPECT_TRUE(v8CallBoolean(descriptor->SetAccessor( + context, v8String(isolate, "enumerable"), ThrowException))); + info.GetReturnValue().Set(descriptor); +} + +TEST(NativeValueTraitsImplTest, IDLRecord) { + V8TestingScope scope; + { + v8::Local<v8::Object> v8Object = v8::Object::New(scope.isolate()); + NonThrowableExceptionState exceptionState; + const auto& record = + NativeValueTraits<IDLRecord<IDLString, IDLOctet>>::nativeValue( + scope.isolate(), v8Object, exceptionState); + EXPECT_TRUE(record.isEmpty()); + } + { + v8::Local<v8::Object> v8Object = v8::Object::New(scope.isolate()); + EXPECT_TRUE(v8CallBoolean( + v8Object->Set(scope.context(), ToV8(&scope, "foo"), ToV8(&scope, 34)))); + EXPECT_TRUE(v8CallBoolean(v8Object->Set( + scope.context(), ToV8(&scope, "bar"), ToV8(&scope, -1024)))); + EXPECT_TRUE(v8CallBoolean( + v8Object->Set(scope.context(), ToV8(&scope, "foo"), ToV8(&scope, 42)))); + + NonThrowableExceptionState exceptionState; + const auto& record = + NativeValueTraits<IDLRecord<IDLByteString, IDLLong>>::nativeValue( + scope.isolate(), v8Object, exceptionState); + EXPECT_EQ(2U, record.size()); + EXPECT_EQ(std::make_pair(String("foo"), int32_t(42)), record[0]); + EXPECT_EQ(std::make_pair(String("bar"), int32_t(-1024)), record[1]); + } + { + v8::Local<v8::Object> v8Object = v8::Object::New(scope.isolate()); + EXPECT_TRUE(v8CallBoolean( + v8Object->Set(scope.context(), ToV8(&scope, "foo"), ToV8(&scope, 34)))); + EXPECT_TRUE(v8CallBoolean(v8Object->DefineOwnProperty( + scope.context(), v8String(scope.isolate(), "bar"), ToV8(&scope, -1024), + v8::PropertyAttribute::DontEnum))); + EXPECT_TRUE(v8CallBoolean( + v8Object->Set(scope.context(), ToV8(&scope, "baz"), ToV8(&scope, 42)))); + + NonThrowableExceptionState exceptionState; + const auto& record = + NativeValueTraits<IDLRecord<IDLByteString, IDLLong>>::nativeValue( + scope.isolate(), v8Object, exceptionState); + EXPECT_EQ(2U, record.size()); + EXPECT_EQ(std::make_pair(String("foo"), int32_t(34)), record[0]); + EXPECT_EQ(std::make_pair(String("baz"), int32_t(42)), record[1]); + } + { + // Exceptions are being thrown in this test, so we need another scope. + V8TestingScope scope; + v8::Local<v8::Object> originalObject = v8::Object::New(scope.isolate()); + EXPECT_TRUE(v8CallBoolean(originalObject->Set( + scope.context(), ToV8(&scope, "foo"), ToV8(&scope, 34)))); + EXPECT_TRUE(v8CallBoolean(originalObject->Set( + scope.context(), ToV8(&scope, "bar"), ToV8(&scope, 42)))); + + NonThrowableExceptionState exceptionState; + const auto& record = + NativeValueTraits<IDLRecord<IDLString, IDLLong>>::nativeValue( + scope.isolate(), originalObject, exceptionState); + EXPECT_EQ(2U, record.size()); + + v8::Local<v8::Object> handler = v8::Object::New(scope.isolate()); + EXPECT_TRUE(v8CallBoolean(handler->Set( + scope.context(), ToV8(&scope, "getOwnPropertyDescriptor"), + v8::Function::New(scope.context(), ReturnBogusObjectDescriptor) + .ToLocalChecked()))); + v8::Local<v8::Proxy> proxy = + v8::Proxy::New(scope.context(), originalObject, handler) + .ToLocalChecked(); + ExceptionState exceptionStateFromProxy( + scope.isolate(), ExceptionState::ExecutionContext, + "NativeValueTraitsImplTest", "IDLRecordTest"); + const auto& recordFromProxy = + NativeValueTraits<IDLRecord<IDLString, IDLLong>>::nativeValue( + scope.isolate(), proxy, exceptionStateFromProxy); + EXPECT_EQ(0U, recordFromProxy.size()); + EXPECT_TRUE(exceptionStateFromProxy.hadException()); + EXPECT_TRUE(exceptionStateFromProxy.message().isEmpty()); + v8::Local<v8::Value> v8Exception = exceptionStateFromProxy.getException(); + EXPECT_TRUE(v8Exception->IsString()); + EXPECT_TRUE( + v8String(scope.isolate(), "bogus!") + ->Equals(v8Exception->ToString(scope.context()).ToLocalChecked())); + } + { + v8::Local<v8::Object> v8Object = v8::Object::New(scope.isolate()); + EXPECT_TRUE(v8CallBoolean( + v8Object->Set(scope.context(), ToV8(&scope, "foo"), ToV8(&scope, 42)))); + EXPECT_TRUE(v8CallBoolean( + v8Object->Set(scope.context(), ToV8(&scope, "bar"), ToV8(&scope, 0)))); + EXPECT_TRUE(v8CallBoolean(v8Object->Set(scope.context(), ToV8(&scope, "xx"), + ToV8(&scope, true)))); + EXPECT_TRUE(v8CallBoolean(v8Object->Set( + scope.context(), ToV8(&scope, "abcd"), ToV8(&scope, false)))); + + NonThrowableExceptionState exceptionState; + const auto& record = + NativeValueTraits<IDLRecord<IDLByteString, IDLBoolean>>::nativeValue( + scope.isolate(), v8Object, exceptionState); + EXPECT_EQ(4U, record.size()); + EXPECT_EQ(std::make_pair(String("foo"), true), record[0]); + EXPECT_EQ(std::make_pair(String("bar"), false), record[1]); + EXPECT_EQ(std::make_pair(String("xx"), true), record[2]); + EXPECT_EQ(std::make_pair(String("abcd"), false), record[3]); + } + { + v8::Local<v8::Array> v8StringArray = v8::Array::New(scope.isolate(), 2); + EXPECT_TRUE(v8CallBoolean(v8StringArray->Set( + scope.context(), ToV8(&scope, 0), ToV8(&scope, "Hello, World!")))); + EXPECT_TRUE(v8CallBoolean(v8StringArray->Set( + scope.context(), ToV8(&scope, 1), ToV8(&scope, "Hi, Mom!")))); + EXPECT_TRUE(v8CallBoolean(v8StringArray->Set( + scope.context(), ToV8(&scope, "foo"), ToV8(&scope, "Ohai")))); + + NonThrowableExceptionState exceptionState; + const auto& record = + NativeValueTraits<IDLRecord<IDLUSVString, IDLString>>::nativeValue( + scope.isolate(), v8StringArray, exceptionState); + EXPECT_EQ(3U, record.size()); + EXPECT_EQ(std::make_pair(String("0"), String("Hello, World!")), record[0]); + EXPECT_EQ(std::make_pair(String("1"), String("Hi, Mom!")), record[1]); + EXPECT_EQ(std::make_pair(String("foo"), String("Ohai")), record[2]); + } + { + v8::Local<v8::Object> v8Object = v8::Object::New(scope.isolate()); + EXPECT_TRUE(v8CallBoolean(v8Object->Set( + scope.context(), v8::Symbol::GetToStringTag(scope.isolate()), + ToV8(&scope, 34)))); + EXPECT_TRUE(v8CallBoolean( + v8Object->Set(scope.context(), ToV8(&scope, "foo"), ToV8(&scope, 42)))); + + NonThrowableExceptionState exceptionState; + const auto& record = + NativeValueTraits<IDLRecord<IDLString, IDLShort>>::nativeValue( + scope.isolate(), v8Object, exceptionState); + EXPECT_EQ(1U, record.size()); + EXPECT_EQ(std::make_pair(String("foo"), int16_t(42)), record[0]); + } + { + v8::Local<v8::Object> v8Object = v8::Object::New(scope.isolate()); + EXPECT_TRUE(v8CallBoolean(v8Object->Set( + scope.context(), v8::Symbol::GetToStringTag(scope.isolate()), + ToV8(&scope, 34)))); + EXPECT_TRUE(v8CallBoolean( + v8Object->Set(scope.context(), ToV8(&scope, "foo"), ToV8(&scope, 42)))); + + NonThrowableExceptionState exceptionState; + const auto& record = + NativeValueTraits<IDLRecord<IDLString, IDLShort>>::nativeValue( + scope.isolate(), v8Object, exceptionState); + EXPECT_EQ(1U, record.size()); + EXPECT_EQ(std::make_pair(String("foo"), int16_t(42)), record[0]); + } + { + v8::Local<v8::Object> v8ParentObject = v8::Object::New(scope.isolate()); + EXPECT_TRUE(v8CallBoolean(v8ParentObject->Set( + scope.context(), ToV8(&scope, "foo"), ToV8(&scope, 34)))); + EXPECT_TRUE(v8CallBoolean(v8ParentObject->Set( + scope.context(), ToV8(&scope, "bar"), ToV8(&scope, 512)))); + v8::Local<v8::Object> v8Object = v8::Object::New(scope.isolate()); + EXPECT_TRUE( + v8CallBoolean(v8Object->SetPrototype(scope.context(), v8ParentObject))); + + NonThrowableExceptionState exceptionState; + auto record = + NativeValueTraits<IDLRecord<IDLString, IDLUnsignedLong>>::nativeValue( + scope.isolate(), v8Object, exceptionState); + EXPECT_TRUE(record.isEmpty()); + + EXPECT_TRUE(v8CallBoolean(v8Object->Set( + scope.context(), ToV8(&scope, "quux"), ToV8(&scope, 42)))); + EXPECT_TRUE(v8CallBoolean(v8Object->Set( + scope.context(), ToV8(&scope, "foo"), ToV8(&scope, 1024)))); + record = + NativeValueTraits<IDLRecord<IDLString, IDLUnsignedLong>>::nativeValue( + scope.isolate(), v8Object, exceptionState); + EXPECT_EQ(2U, record.size()); + EXPECT_EQ(std::make_pair(String("quux"), uint32_t(42)), record[0]); + EXPECT_EQ(std::make_pair(String("foo"), uint32_t(1024)), record[1]); + } + { + v8::Local<v8::Array> v8StringArray = v8::Array::New(scope.isolate(), 2); + EXPECT_TRUE(v8CallBoolean(v8StringArray->Set( + scope.context(), ToV8(&scope, 0), ToV8(&scope, "Hello, World!")))); + EXPECT_TRUE(v8CallBoolean(v8StringArray->Set( + scope.context(), ToV8(&scope, 1), ToV8(&scope, "Hi, Mom!")))); + v8::Local<v8::Object> v8Object = v8::Object::New(scope.isolate()); + EXPECT_TRUE(v8CallBoolean(v8Object->Set( + scope.context(), ToV8(&scope, "foo"), ToV8(&scope, v8StringArray)))); + + NonThrowableExceptionState exceptionState; + const auto& record = + NativeValueTraits<IDLRecord<IDLString, IDLSequence<IDLString>>>:: + nativeValue(scope.isolate(), v8Object, exceptionState); + EXPECT_EQ(1U, record.size()); + EXPECT_EQ("foo", record[0].first); + EXPECT_EQ("Hello, World!", record[0].second[0]); + EXPECT_EQ("Hi, Mom!", record[0].second[1]); + } +} + +} // namespace + +} // namespace blink
diff --git a/third_party/WebKit/Source/bindings/core/v8/ToV8.h b/third_party/WebKit/Source/bindings/core/v8/ToV8.h index 0121859..b1982916 100644 --- a/third_party/WebKit/Source/bindings/core/v8/ToV8.h +++ b/third_party/WebKit/Source/bindings/core/v8/ToV8.h
@@ -231,6 +231,8 @@ return toV8SequenceInternal(value, creationContext, isolate); } +// The following two overloads are also used to convert record<K,V> IDL types +// back into ECMAScript Objects. template <typename T> inline v8::Local<v8::Value> ToV8(const Vector<std::pair<String, T>>& value, v8::Local<v8::Object> creationContext,
diff --git a/third_party/WebKit/Source/bindings/scripts/v8_interface.py b/third_party/WebKit/Source/bindings/scripts/v8_interface.py index c405fb8..a2fd8a7 100644 --- a/third_party/WebKit/Source/bindings/scripts/v8_interface.py +++ b/third_party/WebKit/Source/bindings/scripts/v8_interface.py
@@ -1101,7 +1101,8 @@ # Array in overloaded method: http://crbug.com/262383 yield '%s->IsArray()' % cpp_value, method for idl_type, method in idl_types_methods: - if idl_type.is_dictionary or idl_type.name == 'Dictionary' or idl_type.is_callback_interface: + if idl_type.is_dictionary or idl_type.name == 'Dictionary' or \ + idl_type.is_callback_interface or idl_type.is_record_type: # FIXME: should be '{1}->IsObject() && !{1}->IsRegExp()'.format(cpp_value) # FIXME: the IsRegExp checks can be skipped if we've # already generated tests for them.
diff --git a/third_party/WebKit/Source/bindings/scripts/v8_types.py b/third_party/WebKit/Source/bindings/scripts/v8_types.py index 536e1d6..304f56b8 100644 --- a/third_party/WebKit/Source/bindings/scripts/v8_types.py +++ b/third_party/WebKit/Source/bindings/scripts/v8_types.py
@@ -41,7 +41,12 @@ import posixpath -from idl_types import IdlTypeBase, IdlType, IdlUnionType, IdlArrayOrSequenceType, IdlNullableType +from idl_types import IdlArrayOrSequenceType +from idl_types import IdlNullableType +from idl_types import IdlRecordType +from idl_types import IdlType +from idl_types import IdlTypeBase +from idl_types import IdlUnionType import v8_attributes # for IdlType.constructor_type_name from v8_globals import includes from v8_utilities import extended_attribute_value_contains @@ -140,7 +145,7 @@ bool, True if the C++ type is used as a variadic argument of a method. used_in_cpp_sequence: bool, True if the C++ type is used as an element of a container. - Containers can be an array, a sequence or a dictionary. + Containers can be an array, a sequence, a dictionary or a record. """ def string_mode(): if idl_type.is_nullable: @@ -166,6 +171,16 @@ return 'const %s&' % vector_template_type return vector_template_type + # Record types. + if idl_type.is_record_type: + vector_type = cpp_ptr_type('Vector', 'HeapVector', idl_type.value_type.is_gc_type) + value_type = idl_type.value_type.cpp_type_args(used_in_cpp_sequence=True) + vector_template_type = cpp_template_type(vector_type, + 'std::pair<String, %s>' % value_type) + if used_as_rvalue_type: + return 'const %s&' % vector_template_type + return vector_template_type + # Simple types base_idl_type = idl_type.base_type @@ -317,6 +332,8 @@ IdlUnionType.is_traceable = property(lambda self: True) IdlArrayOrSequenceType.is_traceable = property( lambda self: self.element_type.is_traceable) +IdlRecordType.is_traceable = property( + lambda self: self.value_type.is_traceable) ################################################################################ @@ -403,6 +420,13 @@ IdlArrayOrSequenceType.includes_for_type = includes_for_array_or_sequence_type +def includes_for_record_type(idl_type, extended_attributes=None): + return set.union(idl_type.key_type.includes_for_type(extended_attributes), + idl_type.value_type.includes_for_type(extended_attributes)) + +IdlRecordType.includes_for_type = includes_for_record_type + + def add_includes_for_type(idl_type, extended_attributes=None): includes.update(idl_type.includes_for_type(extended_attributes)) @@ -499,6 +523,7 @@ IdlType.v8_conversion_needs_exception_state = property(v8_conversion_needs_exception_state) IdlArrayOrSequenceType.v8_conversion_needs_exception_state = True +IdlRecordType.v8_conversion_needs_exception_state = True IdlUnionType.v8_conversion_needs_exception_state = True @@ -522,6 +547,24 @@ IdlType.v8_conversion_is_trivial = property(v8_conversion_is_trivial) +def native_value_traits_type_name(idl_type): + if idl_type.is_nullable: + idl_type = idl_type.inner_type + + if idl_type.native_array_element_type: + name = 'IDLSequence<%s>' % native_value_traits_type_name(idl_type.native_array_element_type) + elif idl_type.is_record_type: + name = 'IDLRecord<%s, %s>' % (native_value_traits_type_name(idl_type.key_type), + native_value_traits_type_name(idl_type.value_type)) + elif idl_type.is_basic_type or idl_type.name == 'Promise': + name = 'IDL%s' % idl_type.name + elif idl_type.implemented_as is not None: + name = idl_type.implemented_as + else: + name = idl_type.name + return name + + def v8_value_to_cpp_value(idl_type, extended_attributes, v8_value, variable_name, index, isolate): if idl_type.name == 'void': return '' @@ -569,14 +612,9 @@ elif idl_type.v8_conversion_needs_exception_state: # Effectively, this if branch means everything with v8_conversion_needs_exception_state == True # except for unions, sequences and dictionary interfaces. - if idl_type.is_nullable: - idl_type = idl_type.inner_type - if idl_type.is_primitive_type or idl_type.name in ('ByteString', 'Date', 'Promise', 'USVString'): - trait_type = 'IDL%s' % idl_type.name - else: - trait_type = idl_type.name + base_idl_type = native_value_traits_type_name(idl_type) cpp_expression_format = ( - 'NativeValueTraits<%s>::nativeValue({isolate}, {arguments})' % trait_type) + 'NativeValueTraits<{idl_type}>::nativeValue({isolate}, {arguments})') else: cpp_expression_format = ( 'V8{idl_type}::toImplWithTypeCheck({isolate}, {v8_value})') @@ -748,6 +786,10 @@ if native_array_element_type: return 'FrozenArray' if idl_type.is_frozen_array else 'array' + # Record types. + if idl_type.is_record_type: + return 'Record' + # Simple types base_idl_type = idl_type.base_type # Basic types, without additional includes @@ -802,6 +844,8 @@ 'EventHandler': 'v8SetReturnValue(info, {cpp_value})', 'ScriptValue': 'v8SetReturnValue(info, {cpp_value})', 'SerializedScriptValue': 'v8SetReturnValue(info, {cpp_value})', + # Records. + 'Record': 'v8SetReturnValue(info, ToV8({cpp_value}, info.Holder(), info.GetIsolate()))', # DOMWrapper 'DOMWrapperForMainWorld': 'v8SetReturnValueForMainWorld(info, {cpp_value})', 'DOMWrapperFast': 'v8SetReturnValueFast(info, {cpp_value}, {script_wrappable})', @@ -903,6 +947,7 @@ 'V8AbstractEventListener::cast({cpp_value})->getListenerOrNull(' + '{isolate}, impl->getExecutionContext()) : ' + 'v8::Null({isolate}).As<v8::Value>()'), + 'Record': 'ToV8({cpp_value}, {creation_context}, {isolate})', 'ScriptValue': '{cpp_value}.v8Value()', 'SerializedScriptValue': 'v8Deserialize({isolate}, {cpp_value})', # General
diff --git a/third_party/WebKit/Source/bindings/scripts/v8_union.py b/third_party/WebKit/Source/bindings/scripts/v8_union.py index 9131264..bed82625 100644 --- a/third_party/WebKit/Source/bindings/scripts/v8_union.py +++ b/third_party/WebKit/Source/bindings/scripts/v8_union.py
@@ -52,6 +52,7 @@ interface_types = [] numeric_type = None object_type = None + record_type = None string_type = None for member in union_type.member_types: context = member_context(member, interfaces_info) @@ -74,9 +75,13 @@ array_or_sequence_type = context # "Dictionary" is an object, rather than an IDL dictionary. elif member.base_type == 'Dictionary': - if object_type: + if object_type or record_type: raise Exception('%s is ambiguous.' % union_type.name) object_type = context + elif member.is_record_type: + if object_type or record_type: + raise Exception('%s is ambiguous.' % union_type.name) + record_type = context elif member.is_interface_type: interface_types.append(context) elif member is union_type.boolean_member_type: @@ -111,6 +116,7 @@ 'members': members, 'numeric_type': numeric_type, 'object_type': object_type, + 'record_type': record_type, 'string_type': string_type, 'type_string': str(union_type), 'v8_class': v8_types.v8_type(cpp_class), @@ -128,7 +134,12 @@ cpp_includes.update(member.includes_for_type()) header_forward_decls.add(member.implemented_as) else: - cpp_includes.update(member.includes_for_type()) + if member.is_record_type: + # The headers for both T and U must be present when + # Vector<std::pair<T, U>> is declared. + header_includes.update(member.includes_for_type()) + else: + cpp_includes.update(member.includes_for_type()) def member_context(member, interfaces_info):
diff --git a/third_party/WebKit/Source/bindings/templates/union_container.cpp.tmpl b/third_party/WebKit/Source/bindings/templates/union_container.cpp.tmpl index ac99c69c..ff2eca5 100644 --- a/third_party/WebKit/Source/bindings/templates/union_container.cpp.tmpl +++ b/third_party/WebKit/Source/bindings/templates/union_container.cpp.tmpl
@@ -98,7 +98,7 @@ {% endif %} {% if array_or_sequence_type %} - {# 12.1, 12.2. Arrays and Sequences #} + {# 11.1, 11.2. Arrays and Sequences #} {# FIXME: This should also check "object but not RegExp". Add checks when we implement conversions for Date and RegExp. #} {# TODO(bashi): Should check @@iterator symbol instead. #} @@ -110,7 +110,7 @@ {% endif %} {% if dictionary_type %} - {# 12.3. Dictionaries #} + {# 11.3. Dictionaries #} if (v8Value->IsObject()) { {{v8_value_to_local_cpp_value(dictionary_type) | indent}} impl.set{{dictionary_type.type_name}}(cppValue); @@ -118,8 +118,17 @@ } {% endif %} - {# TODO(bashi): Support 12.4 Callback interface when we need it #} - {# 12.5. Objects #} + {# 11.4. Records #} + {% if record_type %} + if (v8Value->IsObject()) { + {{v8_value_to_local_cpp_value(record_type) | indent}} + impl.set{{record_type.type_name}}(cppValue); + return; + } + + {% endif %} + {# TODO(bashi): Support 11.5 Callback interface when we need it #} + {# 11.6. Objects #} {% if object_type %} if (isUndefinedOrNull(v8Value) || v8Value->IsObject()) { {{v8_value_to_local_cpp_value(object_type) | indent}} @@ -131,7 +140,7 @@ {# FIXME: In some cases, we can omit boolean and numeric type checks because we have fallback conversions. (step 16 and 17) #} {% if boolean_type %} - {# 13. Boolean #} + {# 12. Boolean #} if (v8Value->IsBoolean()) { impl.setBoolean(v8Value.As<v8::Boolean>()->Value()); return; @@ -139,7 +148,7 @@ {% endif %} {% if numeric_type %} - {# 14. Number #} + {# 13. Number #} if (v8Value->IsNumber()) { {{v8_value_to_local_cpp_value(numeric_type) | indent}} impl.set{{numeric_type.type_name}}(cppValue); @@ -148,7 +157,7 @@ {% endif %} {% if string_type %} - {# 15. String #} + {# 14. String #} { {{v8_value_to_local_cpp_value(string_type) | indent}} {% if string_type.enum_values %} @@ -160,7 +169,7 @@ return; } - {# 16. Number (fallback) #} + {# 15. Number (fallback) #} {% elif numeric_type %} { {{v8_value_to_local_cpp_value(numeric_type) | indent}} @@ -168,7 +177,7 @@ return; } - {# 17. Boolean (fallback) #} + {# 16. Boolean (fallback) #} {% elif boolean_type %} { impl.setBoolean(v8Value->BooleanValue()); @@ -176,7 +185,7 @@ } {% else %} - {# 18. TypeError #} + {# 17. TypeError #} exceptionState.throwTypeError("The provided value is not of type '{{type_string}}'"); {% endif %} }
diff --git a/third_party/WebKit/Source/bindings/tests/idls/core/TestDictionary.idl b/third_party/WebKit/Source/bindings/tests/idls/core/TestDictionary.idl index 18d113f..0a188884 100644 --- a/third_party/WebKit/Source/bindings/tests/idls/core/TestDictionary.idl +++ b/third_party/WebKit/Source/bindings/tests/idls/core/TestDictionary.idl
@@ -37,4 +37,6 @@ Dictionary dictionaryMember; [RuntimeEnabled=runtimeFeature] boolean runtimeMember; [PrefixGet] object prefixGetMember; + record<ByteString, byte> recordMember; + record<USVString, TestObject> garbageCollectedRecordMember; };
diff --git a/third_party/WebKit/Source/bindings/tests/idls/core/TestTypedefs.idl b/third_party/WebKit/Source/bindings/tests/idls/core/TestTypedefs.idl index 9f3006e..aa57e1b 100644 --- a/third_party/WebKit/Source/bindings/tests/idls/core/TestTypedefs.idl +++ b/third_party/WebKit/Source/bindings/tests/idls/core/TestTypedefs.idl
@@ -42,6 +42,9 @@ typedef TestInterfaceConstructor T; typedef (TestInterface or TestInterfaceEmpty) TestInterfaceOrTestInterfaceEmpty; typedef (DOMString or double) DOMStringOrDouble; +typedef record<ByteString, long> SomeRecordType; +typedef record<USVString, TestObject> RecordWithOilpanValueType; +typedef (sequence<sequence<ByteString>> or record<ByteString, ByteString>) UnionWithRecord; [ Constructor(String stringArg), @@ -61,4 +64,9 @@ ArrayOfStrings arrayOfStringsMethodArrayOfStringsArg(ArrayOfStrings arrayOfStringsArg); String[] stringArrayMethodStringArrayArg(String[] stringArrayArg); + + void methodTakingRecord(SomeRecordType arg); + void methodTakingOilpanValueRecord(RecordWithOilpanValueType arg); + double unionWithRecordMethod(UnionWithRecord arg); + record<DOMString, boolean> methodThatReturnsRecord(); };
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/ByteStringSequenceSequenceOrByteStringByteStringRecord.cpp b/third_party/WebKit/Source/bindings/tests/results/core/ByteStringSequenceSequenceOrByteStringByteStringRecord.cpp new file mode 100644 index 0000000..e44c4e3 --- /dev/null +++ b/third_party/WebKit/Source/bindings/tests/results/core/ByteStringSequenceSequenceOrByteStringByteStringRecord.cpp
@@ -0,0 +1,109 @@ +// Copyright 2014 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. + +// This file has been auto-generated by code_generator_v8.py. +// DO NOT MODIFY! + +// This file has been generated from the Jinja2 template in +// third_party/WebKit/Source/bindings/templates/union_container.cpp.tmpl + +// clang-format off +#include "ByteStringSequenceSequenceOrByteStringByteStringRecord.h" + +#include "bindings/core/v8/IDLTypes.h" +#include "bindings/core/v8/NativeValueTraitsImpl.h" +#include "bindings/core/v8/ToV8.h" + +namespace blink { + +ByteStringSequenceSequenceOrByteStringByteStringRecord::ByteStringSequenceSequenceOrByteStringByteStringRecord() : m_type(SpecificTypeNone) {} + +const Vector<Vector<String>>& ByteStringSequenceSequenceOrByteStringByteStringRecord::getAsByteStringSequenceSequence() const { + DCHECK(isByteStringSequenceSequence()); + return m_byteStringSequenceSequence; +} + +void ByteStringSequenceSequenceOrByteStringByteStringRecord::setByteStringSequenceSequence(const Vector<Vector<String>>& value) { + DCHECK(isNull()); + m_byteStringSequenceSequence = value; + m_type = SpecificTypeByteStringSequenceSequence; +} + +ByteStringSequenceSequenceOrByteStringByteStringRecord ByteStringSequenceSequenceOrByteStringByteStringRecord::fromByteStringSequenceSequence(const Vector<Vector<String>>& value) { + ByteStringSequenceSequenceOrByteStringByteStringRecord container; + container.setByteStringSequenceSequence(value); + return container; +} + +const Vector<std::pair<String, String>>& ByteStringSequenceSequenceOrByteStringByteStringRecord::getAsByteStringByteStringRecord() const { + DCHECK(isByteStringByteStringRecord()); + return m_byteStringByteStringRecord; +} + +void ByteStringSequenceSequenceOrByteStringByteStringRecord::setByteStringByteStringRecord(const Vector<std::pair<String, String>>& value) { + DCHECK(isNull()); + m_byteStringByteStringRecord = value; + m_type = SpecificTypeByteStringByteStringRecord; +} + +ByteStringSequenceSequenceOrByteStringByteStringRecord ByteStringSequenceSequenceOrByteStringByteStringRecord::fromByteStringByteStringRecord(const Vector<std::pair<String, String>>& value) { + ByteStringSequenceSequenceOrByteStringByteStringRecord container; + container.setByteStringByteStringRecord(value); + return container; +} + +ByteStringSequenceSequenceOrByteStringByteStringRecord::ByteStringSequenceSequenceOrByteStringByteStringRecord(const ByteStringSequenceSequenceOrByteStringByteStringRecord&) = default; +ByteStringSequenceSequenceOrByteStringByteStringRecord::~ByteStringSequenceSequenceOrByteStringByteStringRecord() = default; +ByteStringSequenceSequenceOrByteStringByteStringRecord& ByteStringSequenceSequenceOrByteStringByteStringRecord::operator=(const ByteStringSequenceSequenceOrByteStringByteStringRecord&) = default; + +DEFINE_TRACE(ByteStringSequenceSequenceOrByteStringByteStringRecord) { +} + +void V8ByteStringSequenceSequenceOrByteStringByteStringRecord::toImpl(v8::Isolate* isolate, v8::Local<v8::Value> v8Value, ByteStringSequenceSequenceOrByteStringByteStringRecord& impl, UnionTypeConversionMode conversionMode, ExceptionState& exceptionState) { + if (v8Value.IsEmpty()) + return; + + if (conversionMode == UnionTypeConversionMode::Nullable && isUndefinedOrNull(v8Value)) + return; + + if (v8Value->IsArray()) { + Vector<Vector<String>> cppValue = toImplArray<Vector<Vector<String>>>(v8Value, 0, isolate, exceptionState); + if (exceptionState.hadException()) + return; + impl.setByteStringSequenceSequence(cppValue); + return; + } + + if (v8Value->IsObject()) { + Vector<std::pair<String, String>> cppValue = NativeValueTraits<IDLRecord<IDLByteString, IDLByteString>>::nativeValue(isolate, v8Value, exceptionState); + if (exceptionState.hadException()) + return; + impl.setByteStringByteStringRecord(cppValue); + return; + } + + exceptionState.throwTypeError("The provided value is not of type '(sequence<sequence<ByteString>> or record<ByteString, ByteString>)'"); +} + +v8::Local<v8::Value> ToV8(const ByteStringSequenceSequenceOrByteStringByteStringRecord& impl, v8::Local<v8::Object> creationContext, v8::Isolate* isolate) { + switch (impl.m_type) { + case ByteStringSequenceSequenceOrByteStringByteStringRecord::SpecificTypeNone: + return v8::Null(isolate); + case ByteStringSequenceSequenceOrByteStringByteStringRecord::SpecificTypeByteStringSequenceSequence: + return ToV8(impl.getAsByteStringSequenceSequence(), creationContext, isolate); + case ByteStringSequenceSequenceOrByteStringByteStringRecord::SpecificTypeByteStringByteStringRecord: + return ToV8(impl.getAsByteStringByteStringRecord(), creationContext, isolate); + default: + NOTREACHED(); + } + return v8::Local<v8::Value>(); +} + +ByteStringSequenceSequenceOrByteStringByteStringRecord NativeValueTraits<ByteStringSequenceSequenceOrByteStringByteStringRecord>::nativeValue(v8::Isolate* isolate, v8::Local<v8::Value> value, ExceptionState& exceptionState) { + ByteStringSequenceSequenceOrByteStringByteStringRecord impl; + V8ByteStringSequenceSequenceOrByteStringByteStringRecord::toImpl(isolate, value, impl, UnionTypeConversionMode::NotNullable, exceptionState); + return impl; +} + +} // namespace blink
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/ByteStringSequenceSequenceOrByteStringByteStringRecord.h b/third_party/WebKit/Source/bindings/tests/results/core/ByteStringSequenceSequenceOrByteStringByteStringRecord.h new file mode 100644 index 0000000..a2e89d84 --- /dev/null +++ b/third_party/WebKit/Source/bindings/tests/results/core/ByteStringSequenceSequenceOrByteStringByteStringRecord.h
@@ -0,0 +1,96 @@ +// Copyright 2014 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. + +// This file has been auto-generated by code_generator_v8.py. +// DO NOT MODIFY! + +// This file has been generated from the Jinja2 template in +// third_party/WebKit/Source/bindings/templates/union_container.h.tmpl + +// clang-format off +#ifndef ByteStringSequenceSequenceOrByteStringByteStringRecord_h +#define ByteStringSequenceSequenceOrByteStringByteStringRecord_h + +#include "bindings/core/v8/Dictionary.h" +#include "bindings/core/v8/ExceptionState.h" +#include "bindings/core/v8/IDLTypes.h" +#include "bindings/core/v8/NativeValueTraits.h" +#include "bindings/core/v8/NativeValueTraitsImpl.h" +#include "bindings/core/v8/V8Binding.h" +#include "core/CoreExport.h" +#include "platform/heap/Handle.h" + +namespace blink { + +class CORE_EXPORT ByteStringSequenceSequenceOrByteStringByteStringRecord final { + DISALLOW_NEW_EXCEPT_PLACEMENT_NEW(); + public: + ByteStringSequenceSequenceOrByteStringByteStringRecord(); + bool isNull() const { return m_type == SpecificTypeNone; } + + bool isByteStringSequenceSequence() const { return m_type == SpecificTypeByteStringSequenceSequence; } + const Vector<Vector<String>>& getAsByteStringSequenceSequence() const; + void setByteStringSequenceSequence(const Vector<Vector<String>>&); + static ByteStringSequenceSequenceOrByteStringByteStringRecord fromByteStringSequenceSequence(const Vector<Vector<String>>&); + + bool isByteStringByteStringRecord() const { return m_type == SpecificTypeByteStringByteStringRecord; } + const Vector<std::pair<String, String>>& getAsByteStringByteStringRecord() const; + void setByteStringByteStringRecord(const Vector<std::pair<String, String>>&); + static ByteStringSequenceSequenceOrByteStringByteStringRecord fromByteStringByteStringRecord(const Vector<std::pair<String, String>>&); + + ByteStringSequenceSequenceOrByteStringByteStringRecord(const ByteStringSequenceSequenceOrByteStringByteStringRecord&); + ~ByteStringSequenceSequenceOrByteStringByteStringRecord(); + ByteStringSequenceSequenceOrByteStringByteStringRecord& operator=(const ByteStringSequenceSequenceOrByteStringByteStringRecord&); + DECLARE_TRACE(); + + private: + enum SpecificTypes { + SpecificTypeNone, + SpecificTypeByteStringSequenceSequence, + SpecificTypeByteStringByteStringRecord, + }; + SpecificTypes m_type; + + Vector<Vector<String>> m_byteStringSequenceSequence; + Vector<std::pair<String, String>> m_byteStringByteStringRecord; + + friend CORE_EXPORT v8::Local<v8::Value> ToV8(const ByteStringSequenceSequenceOrByteStringByteStringRecord&, v8::Local<v8::Object>, v8::Isolate*); +}; + +class V8ByteStringSequenceSequenceOrByteStringByteStringRecord final { + public: + CORE_EXPORT static void toImpl(v8::Isolate*, v8::Local<v8::Value>, ByteStringSequenceSequenceOrByteStringByteStringRecord&, UnionTypeConversionMode, ExceptionState&); +}; + +CORE_EXPORT v8::Local<v8::Value> ToV8(const ByteStringSequenceSequenceOrByteStringByteStringRecord&, v8::Local<v8::Object>, v8::Isolate*); + +template <class CallbackInfo> +inline void v8SetReturnValue(const CallbackInfo& callbackInfo, ByteStringSequenceSequenceOrByteStringByteStringRecord& impl) { + v8SetReturnValue(callbackInfo, ToV8(impl, callbackInfo.Holder(), callbackInfo.GetIsolate())); +} + +template <class CallbackInfo> +inline void v8SetReturnValue(const CallbackInfo& callbackInfo, ByteStringSequenceSequenceOrByteStringByteStringRecord& impl, v8::Local<v8::Object> creationContext) { + v8SetReturnValue(callbackInfo, ToV8(impl, creationContext, callbackInfo.GetIsolate())); +} + +template <> +struct NativeValueTraits<ByteStringSequenceSequenceOrByteStringByteStringRecord> : public NativeValueTraitsBase<ByteStringSequenceSequenceOrByteStringByteStringRecord> { + CORE_EXPORT static ByteStringSequenceSequenceOrByteStringByteStringRecord nativeValue(v8::Isolate*, v8::Local<v8::Value>, ExceptionState&); +}; + +template <> +struct V8TypeOf<ByteStringSequenceSequenceOrByteStringByteStringRecord> { + typedef V8ByteStringSequenceSequenceOrByteStringByteStringRecord Type; +}; + +} // namespace blink + +// We need to set canInitializeWithMemset=true because HeapVector supports +// items that can initialize with memset or have a vtable. It is safe to +// set canInitializeWithMemset=true for a union type object in practice. +// See https://codereview.chromium.org/1118993002/#msg5 for more details. +WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::ByteStringSequenceSequenceOrByteStringByteStringRecord); + +#endif // ByteStringSequenceSequenceOrByteStringByteStringRecord_h
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/TestDictionary.cpp b/third_party/WebKit/Source/bindings/tests/results/core/TestDictionary.cpp index 3ae07758..75e4953 100644 --- a/third_party/WebKit/Source/bindings/tests/results/core/TestDictionary.cpp +++ b/third_party/WebKit/Source/bindings/tests/results/core/TestDictionary.cpp
@@ -156,6 +156,17 @@ void TestDictionary::setEventTargetMember(EventTarget* value) { m_eventTargetMember = value; } +bool TestDictionary::hasGarbageCollectedRecordMember() const { + return m_hasGarbageCollectedRecordMember; +} +const HeapVector<std::pair<String, Member<TestObject>>>& TestDictionary::garbageCollectedRecordMember() const { + DCHECK(m_hasGarbageCollectedRecordMember); + return m_garbageCollectedRecordMember; +} +void TestDictionary::setGarbageCollectedRecordMember(const HeapVector<std::pair<String, Member<TestObject>>>& value) { + m_garbageCollectedRecordMember = value; + m_hasGarbageCollectedRecordMember = true; +} bool TestDictionary::hasInternalDictionarySequenceMember() const { return m_hasInternalDictionarySequenceMember; } @@ -217,6 +228,17 @@ void TestDictionary::setPrefixGetMember(ScriptValue value) { m_prefixGetMember = value; } +bool TestDictionary::hasRecordMember() const { + return m_hasRecordMember; +} +const Vector<std::pair<String, int8_t>>& TestDictionary::recordMember() const { + DCHECK(m_hasRecordMember); + return m_recordMember; +} +void TestDictionary::setRecordMember(const Vector<std::pair<String, int8_t>>& value) { + m_recordMember = value; + m_hasRecordMember = true; +} bool TestDictionary::hasRestrictedDoubleMember() const { return m_hasRestrictedDoubleMember; } @@ -392,6 +414,7 @@ visitor->trace(m_doubleOrStringSequenceMember); visitor->trace(m_elementOrNullMember); visitor->trace(m_eventTargetMember); + visitor->trace(m_garbageCollectedRecordMember); visitor->trace(m_internalDictionarySequenceMember); visitor->trace(m_otherDoubleOrStringMember); visitor->trace(m_testInterface2OrUint8ArrayMember);
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/TestDictionary.h b/third_party/WebKit/Source/bindings/tests/results/core/TestDictionary.h index e7a8276..2f925294 100644 --- a/third_party/WebKit/Source/bindings/tests/results/core/TestDictionary.h +++ b/third_party/WebKit/Source/bindings/tests/results/core/TestDictionary.h
@@ -87,6 +87,10 @@ EventTarget* eventTargetMember() const; void setEventTargetMember(EventTarget*); + bool hasGarbageCollectedRecordMember() const; + const HeapVector<std::pair<String, Member<TestObject>>>& garbageCollectedRecordMember() const; + void setGarbageCollectedRecordMember(const HeapVector<std::pair<String, Member<TestObject>>>&); + bool hasInternalDictionarySequenceMember() const; const HeapVector<InternalDictionary>& internalDictionarySequenceMember() const; void setInternalDictionarySequenceMember(const HeapVector<InternalDictionary>&); @@ -112,6 +116,10 @@ ScriptValue getPrefixGetMember() const; void setPrefixGetMember(ScriptValue); + bool hasRecordMember() const; + const Vector<std::pair<String, int8_t>>& recordMember() const; + void setRecordMember(const Vector<std::pair<String, int8_t>>&); + bool hasRestrictedDoubleMember() const; double restrictedDoubleMember() const; void setRestrictedDoubleMember(double); @@ -199,6 +207,8 @@ bool m_hasEnumSequenceMember = false; Vector<String> m_enumSequenceMember; Member<EventTarget> m_eventTargetMember; + bool m_hasGarbageCollectedRecordMember = false; + HeapVector<std::pair<String, Member<TestObject>>> m_garbageCollectedRecordMember; bool m_hasInternalDictionarySequenceMember = false; HeapVector<InternalDictionary> m_internalDictionarySequenceMember; bool m_hasLongMember = false; @@ -207,6 +217,8 @@ ScriptValue m_objectOrNullMember; DoubleOrString m_otherDoubleOrStringMember; ScriptValue m_prefixGetMember; + bool m_hasRecordMember = false; + Vector<std::pair<String, int8_t>> m_recordMember; bool m_hasRestrictedDoubleMember = false; double m_restrictedDoubleMember; bool m_hasRuntimeMember = false;
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestDictionary.cpp b/third_party/WebKit/Source/bindings/tests/results/core/V8TestDictionary.cpp index 1f009f9..77c16c242 100644 --- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestDictionary.cpp +++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestDictionary.cpp
@@ -244,6 +244,20 @@ impl.setEventTargetMember(eventTargetMember); } + v8::Local<v8::Value> garbageCollectedRecordMemberValue; + if (!v8Object->Get(isolate->GetCurrentContext(), v8AtomicString(isolate, "garbageCollectedRecordMember")).ToLocal(&garbageCollectedRecordMemberValue)) { + exceptionState.rethrowV8Exception(block.Exception()); + return; + } + if (garbageCollectedRecordMemberValue.IsEmpty() || garbageCollectedRecordMemberValue->IsUndefined()) { + // Do nothing. + } else { + HeapVector<std::pair<String, Member<TestObject>>> garbageCollectedRecordMember = NativeValueTraits<IDLRecord<IDLUSVString, TestObject>>::nativeValue(isolate, garbageCollectedRecordMemberValue, exceptionState); + if (exceptionState.hadException()) + return; + impl.setGarbageCollectedRecordMember(garbageCollectedRecordMember); + } + v8::Local<v8::Value> internalDictionarySequenceMemberValue; if (!v8Object->Get(isolate->GetCurrentContext(), v8AtomicString(isolate, "internalDictionarySequenceMember")).ToLocal(&internalDictionarySequenceMemberValue)) { exceptionState.rethrowV8Exception(block.Exception()); @@ -337,6 +351,20 @@ impl.setPrefixGetMember(prefixGetMember); } + v8::Local<v8::Value> recordMemberValue; + if (!v8Object->Get(isolate->GetCurrentContext(), v8AtomicString(isolate, "recordMember")).ToLocal(&recordMemberValue)) { + exceptionState.rethrowV8Exception(block.Exception()); + return; + } + if (recordMemberValue.IsEmpty() || recordMemberValue->IsUndefined()) { + // Do nothing. + } else { + Vector<std::pair<String, int8_t>> recordMember = NativeValueTraits<IDLRecord<IDLByteString, IDLByte>>::nativeValue(isolate, recordMemberValue, exceptionState); + if (exceptionState.hadException()) + return; + impl.setRecordMember(recordMember); + } + v8::Local<v8::Value> restrictedDoubleMemberValue; if (!v8Object->Get(isolate->GetCurrentContext(), v8AtomicString(isolate, "restrictedDoubleMember")).ToLocal(&restrictedDoubleMemberValue)) { exceptionState.rethrowV8Exception(block.Exception()); @@ -665,6 +693,11 @@ return false; } + if (impl.hasGarbageCollectedRecordMember()) { + if (!v8CallBoolean(dictionary->CreateDataProperty(isolate->GetCurrentContext(), v8AtomicString(isolate, "garbageCollectedRecordMember"), ToV8(impl.garbageCollectedRecordMember(), creationContext, isolate)))) + return false; + } + if (impl.hasInternalDictionarySequenceMember()) { if (!v8CallBoolean(dictionary->CreateDataProperty(isolate->GetCurrentContext(), v8AtomicString(isolate, "internalDictionarySequenceMember"), ToV8(impl.internalDictionarySequenceMember(), creationContext, isolate)))) return false; @@ -707,6 +740,11 @@ return false; } + if (impl.hasRecordMember()) { + if (!v8CallBoolean(dictionary->CreateDataProperty(isolate->GetCurrentContext(), v8AtomicString(isolate, "recordMember"), ToV8(impl.recordMember(), creationContext, isolate)))) + return false; + } + if (impl.hasRestrictedDoubleMember()) { if (!v8CallBoolean(dictionary->CreateDataProperty(isolate->GetCurrentContext(), v8AtomicString(isolate, "restrictedDoubleMember"), v8::Number::New(isolate, impl.restrictedDoubleMember())))) return false;
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestTypedefs.cpp b/third_party/WebKit/Source/bindings/tests/results/core/V8TestTypedefs.cpp index 17eda00..86e0684 100644 --- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestTypedefs.cpp +++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestTypedefs.cpp
@@ -11,6 +11,7 @@ // clang-format off #include "V8TestTypedefs.h" +#include "bindings/core/v8/ByteStringSequenceSequenceOrByteStringByteStringRecord.h" #include "bindings/core/v8/ExceptionState.h" #include "bindings/core/v8/IDLTypes.h" #include "bindings/core/v8/NativeValueTraitsImpl.h" @@ -21,6 +22,7 @@ #include "bindings/core/v8/V8TestCallbackInterface.h" #include "bindings/core/v8/V8TestInterface.h" #include "bindings/core/v8/V8TestInterfaceEmpty.h" +#include "bindings/core/v8/V8TestObject.h" #include "core/dom/Document.h" #include "core/frame/LocalDOMWindow.h" #include "wtf/GetPtr.h" @@ -242,6 +244,66 @@ v8SetReturnValue(info, ToV8(impl->stringArrayMethodStringArrayArg(stringArrayArg), info.Holder(), info.GetIsolate())); } +static void methodTakingRecordMethod(const v8::FunctionCallbackInfo<v8::Value>& info) { + ExceptionState exceptionState(info.GetIsolate(), ExceptionState::ExecutionContext, "TestTypedefs", "methodTakingRecord"); + + TestTypedefs* impl = V8TestTypedefs::toImpl(info.Holder()); + + if (UNLIKELY(info.Length() < 1)) { + exceptionState.throwTypeError(ExceptionMessages::notEnoughArguments(1, info.Length())); + return; + } + + Vector<std::pair<String, int32_t>> arg; + arg = NativeValueTraits<IDLRecord<IDLByteString, IDLLong>>::nativeValue(info.GetIsolate(), info[0], exceptionState); + if (exceptionState.hadException()) + return; + + impl->methodTakingRecord(arg); +} + +static void methodTakingOilpanValueRecordMethod(const v8::FunctionCallbackInfo<v8::Value>& info) { + ExceptionState exceptionState(info.GetIsolate(), ExceptionState::ExecutionContext, "TestTypedefs", "methodTakingOilpanValueRecord"); + + TestTypedefs* impl = V8TestTypedefs::toImpl(info.Holder()); + + if (UNLIKELY(info.Length() < 1)) { + exceptionState.throwTypeError(ExceptionMessages::notEnoughArguments(1, info.Length())); + return; + } + + HeapVector<std::pair<String, Member<TestObject>>> arg; + arg = NativeValueTraits<IDLRecord<IDLUSVString, TestObject>>::nativeValue(info.GetIsolate(), info[0], exceptionState); + if (exceptionState.hadException()) + return; + + impl->methodTakingOilpanValueRecord(arg); +} + +static void unionWithRecordMethodMethod(const v8::FunctionCallbackInfo<v8::Value>& info) { + ExceptionState exceptionState(info.GetIsolate(), ExceptionState::ExecutionContext, "TestTypedefs", "unionWithRecordMethod"); + + TestTypedefs* impl = V8TestTypedefs::toImpl(info.Holder()); + + if (UNLIKELY(info.Length() < 1)) { + exceptionState.throwTypeError(ExceptionMessages::notEnoughArguments(1, info.Length())); + return; + } + + ByteStringSequenceSequenceOrByteStringByteStringRecord arg; + V8ByteStringSequenceSequenceOrByteStringByteStringRecord::toImpl(info.GetIsolate(), info[0], arg, UnionTypeConversionMode::NotNullable, exceptionState); + if (exceptionState.hadException()) + return; + + v8SetReturnValue(info, impl->unionWithRecordMethod(arg)); +} + +static void methodThatReturnsRecordMethod(const v8::FunctionCallbackInfo<v8::Value>& info) { + TestTypedefs* impl = V8TestTypedefs::toImpl(info.Holder()); + + v8SetReturnValue(info, ToV8(impl->methodThatReturnsRecord(), info.Holder(), info.GetIsolate())); +} + static void constructor(const v8::FunctionCallbackInfo<v8::Value>& info) { if (UNLIKELY(info.Length() < 1)) { V8ThrowException::throwTypeError(info.GetIsolate(), ExceptionMessages::failedToConstruct("TestTypedefs", ExceptionMessages::notEnoughArguments(1, info.Length()))); @@ -313,6 +375,22 @@ TestTypedefsV8Internal::stringArrayMethodStringArrayArgMethod(info); } +void V8TestTypedefs::methodTakingRecordMethodCallback(const v8::FunctionCallbackInfo<v8::Value>& info) { + TestTypedefsV8Internal::methodTakingRecordMethod(info); +} + +void V8TestTypedefs::methodTakingOilpanValueRecordMethodCallback(const v8::FunctionCallbackInfo<v8::Value>& info) { + TestTypedefsV8Internal::methodTakingOilpanValueRecordMethod(info); +} + +void V8TestTypedefs::unionWithRecordMethodMethodCallback(const v8::FunctionCallbackInfo<v8::Value>& info) { + TestTypedefsV8Internal::unionWithRecordMethodMethod(info); +} + +void V8TestTypedefs::methodThatReturnsRecordMethodCallback(const v8::FunctionCallbackInfo<v8::Value>& info) { + TestTypedefsV8Internal::methodThatReturnsRecordMethod(info); +} + // Suppress warning: global constructors, because AttributeConfiguration is trivial // and does not depend on another global objects. #if defined(COMPONENT_BUILD) && defined(WIN32) && COMPILER(CLANG) @@ -340,6 +418,10 @@ {"domStringOrDoubleMethod", V8TestTypedefs::domStringOrDoubleMethodMethodCallback, nullptr, 0, v8::None, V8DOMConfiguration::OnPrototype, V8DOMConfiguration::CheckHolder, V8DOMConfiguration::DoNotCheckAccess}, {"arrayOfStringsMethodArrayOfStringsArg", V8TestTypedefs::arrayOfStringsMethodArrayOfStringsArgMethodCallback, nullptr, 1, v8::None, V8DOMConfiguration::OnPrototype, V8DOMConfiguration::CheckHolder, V8DOMConfiguration::DoNotCheckAccess}, {"stringArrayMethodStringArrayArg", V8TestTypedefs::stringArrayMethodStringArrayArgMethodCallback, nullptr, 1, v8::None, V8DOMConfiguration::OnPrototype, V8DOMConfiguration::CheckHolder, V8DOMConfiguration::DoNotCheckAccess}, + {"methodTakingRecord", V8TestTypedefs::methodTakingRecordMethodCallback, nullptr, 1, v8::None, V8DOMConfiguration::OnPrototype, V8DOMConfiguration::CheckHolder, V8DOMConfiguration::DoNotCheckAccess}, + {"methodTakingOilpanValueRecord", V8TestTypedefs::methodTakingOilpanValueRecordMethodCallback, nullptr, 1, v8::None, V8DOMConfiguration::OnPrototype, V8DOMConfiguration::CheckHolder, V8DOMConfiguration::DoNotCheckAccess}, + {"unionWithRecordMethod", V8TestTypedefs::unionWithRecordMethodMethodCallback, nullptr, 1, v8::None, V8DOMConfiguration::OnPrototype, V8DOMConfiguration::CheckHolder, V8DOMConfiguration::DoNotCheckAccess}, + {"methodThatReturnsRecord", V8TestTypedefs::methodThatReturnsRecordMethodCallback, nullptr, 0, v8::None, V8DOMConfiguration::OnPrototype, V8DOMConfiguration::CheckHolder, V8DOMConfiguration::DoNotCheckAccess}, }; void V8TestTypedefs::constructorCallback(const v8::FunctionCallbackInfo<v8::Value>& info) {
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestTypedefs.h b/third_party/WebKit/Source/bindings/tests/results/core/V8TestTypedefs.h index c1a1f787..5d88480 100644 --- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestTypedefs.h +++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestTypedefs.h
@@ -12,6 +12,7 @@ #ifndef V8TestTypedefs_h #define V8TestTypedefs_h +#include "bindings/core/v8/ByteStringSequenceSequenceOrByteStringByteStringRecord.h" #include "bindings/core/v8/GeneratedCodeHelper.h" #include "bindings/core/v8/NativeValueTraits.h" #include "bindings/core/v8/ScriptWrappable.h" @@ -62,6 +63,10 @@ CORE_EXPORT static void domStringOrDoubleMethodMethodCallback(const v8::FunctionCallbackInfo<v8::Value>&); CORE_EXPORT static void arrayOfStringsMethodArrayOfStringsArgMethodCallback(const v8::FunctionCallbackInfo<v8::Value>&); CORE_EXPORT static void stringArrayMethodStringArrayArgMethodCallback(const v8::FunctionCallbackInfo<v8::Value>&); + CORE_EXPORT static void methodTakingRecordMethodCallback(const v8::FunctionCallbackInfo<v8::Value>&); + CORE_EXPORT static void methodTakingOilpanValueRecordMethodCallback(const v8::FunctionCallbackInfo<v8::Value>&); + CORE_EXPORT static void unionWithRecordMethodMethodCallback(const v8::FunctionCallbackInfo<v8::Value>&); + CORE_EXPORT static void methodThatReturnsRecordMethodCallback(const v8::FunctionCallbackInfo<v8::Value>&); }; template <>
diff --git a/third_party/WebKit/Source/build/scripts/make_computed_style_base.py b/third_party/WebKit/Source/build/scripts/make_computed_style_base.py index 1ac90f3..8d6ee0e8 100755 --- a/third_party/WebKit/Source/build/scripts/make_computed_style_base.py +++ b/third_party/WebKit/Source/build/scripts/make_computed_style_base.py
@@ -58,7 +58,7 @@ 'property_name', # Name of the type (e.g. EClear, int) 'type_name', - # Affects how the field is generated (keyword, flag) + # Affects how the field is generated (keyword, flag, monotonic_flag) 'field_template', # Bits needed for storage 'size', @@ -212,7 +212,7 @@ name=member_name, property_name=field_name, type_name='bool', - field_template='flag', + field_template='monotonic_flag', size=1, default_value='false', getter_method_name=field_name,
diff --git a/third_party/WebKit/Source/build/scripts/templates/ComputedStyleBase.h.tmpl b/third_party/WebKit/Source/build/scripts/templates/ComputedStyleBase.h.tmpl index cb055de9..34c45b7 100644 --- a/third_party/WebKit/Source/build/scripts/templates/ComputedStyleBase.h.tmpl +++ b/third_party/WebKit/Source/build/scripts/templates/ComputedStyleBase.h.tmpl
@@ -10,11 +10,13 @@ #include "{{path}}" {% endfor %} -{# Returns the default value for the field, converted to fit in the storage container. #} -{% macro default_value(field) -%} -{# We only support enum fields for now. #} -static_cast<unsigned>({{field.default_value}}) -{%- endmacro %} +{# Each field template has macros that we can call to generate specific + aspects of the field (e.g. getters, setters). +#} +{% import 'fields/keyword.tmpl' as keyword %} +{% import 'fields/flag.tmpl' as flag %} +{% import 'fields/monotonic_flag.tmpl' as monotonic_flag %} +{% set field_templates = { 'keyword': keyword, 'flag': flag, 'monotonic_flag': monotonic_flag } %} namespace blink { @@ -24,7 +26,7 @@ public: ALWAYS_INLINE ComputedStyleBase() : {% for field in fields %} - {{field.name}}({{default_value(field)}}){{print_if(not loop.last, ',')}} + {{field.name}}(static_cast<unsigned>({{field.default_value}})){{print_if(not loop.last, ',')}} {% endfor %} {} ~ComputedStyleBase() {} @@ -87,24 +89,7 @@ {% for field in fields %} // {{field.property_name}} - inline static {{field.type_name}} {{field.initial_method_name}}() { - return {{field.default_value}}; - } - {{field.type_name}} {{field.getter_method_name}}() const { - return static_cast<{{field.type_name}}>({{field.name}}); - } - {% if field.is_nonproperty %} - void {{field.setter_method_name}}() { - {{field.name}} = static_cast<unsigned>(true); - } - {% else %} - void {{field.setter_method_name}}({{field.type_name}} v) { - {{field.name}} = static_cast<unsigned>(v); - } - {% endif %} - inline void {{field.resetter_method_name}}() { - {{field.name}} = {{default_value(field)}}; - } + {{field_templates[field.field_template].decl_methods(field)|indent(2)}} {% endfor %} protected:
diff --git a/third_party/WebKit/Source/build/scripts/templates/fields/base.tmpl b/third_party/WebKit/Source/build/scripts/templates/fields/base.tmpl new file mode 100644 index 0000000..0685305 --- /dev/null +++ b/third_party/WebKit/Source/build/scripts/templates/fields/base.tmpl
@@ -0,0 +1,15 @@ +{% macro decl_methods(field) -%} +inline static {{field.type_name}} {{field.initial_method_name}}() { + return {{field.default_value}}; +} +{{field.type_name}} {{field.getter_method_name}}() const { + return static_cast<{{field.type_name}}>({{field.name}}); +} +void {{field.setter_method_name}}({{field.type_name}} v) { + {{field.name}} = static_cast<unsigned>(v); +} +inline void {{field.resetter_method_name}}() { + {{field.name}} = static_cast<unsigned>({{field.default_value}}); +} +{%- endmacro %} +
diff --git a/third_party/WebKit/Source/build/scripts/templates/fields/flag.tmpl b/third_party/WebKit/Source/build/scripts/templates/fields/flag.tmpl new file mode 100644 index 0000000..30519af --- /dev/null +++ b/third_party/WebKit/Source/build/scripts/templates/fields/flag.tmpl
@@ -0,0 +1,4 @@ +{% import 'fields/base.tmpl' as base %} +{% macro decl_methods(field) -%} +{{ base.decl_methods(field) }} +{%- endmacro %}
diff --git a/third_party/WebKit/Source/build/scripts/templates/fields/keyword.tmpl b/third_party/WebKit/Source/build/scripts/templates/fields/keyword.tmpl new file mode 100644 index 0000000..3d6cb329 --- /dev/null +++ b/third_party/WebKit/Source/build/scripts/templates/fields/keyword.tmpl
@@ -0,0 +1,5 @@ +{% import 'fields/base.tmpl' as base %} +{% macro decl_methods(field) -%} +{{ base.decl_methods(field) }} +{# TODO(shend): Add special keyword methods like cardinality #} +{%- endmacro %}
diff --git a/third_party/WebKit/Source/build/scripts/templates/fields/monotonic_flag.tmpl b/third_party/WebKit/Source/build/scripts/templates/fields/monotonic_flag.tmpl new file mode 100644 index 0000000..84c47ab --- /dev/null +++ b/third_party/WebKit/Source/build/scripts/templates/fields/monotonic_flag.tmpl
@@ -0,0 +1,8 @@ +{% macro decl_methods(field) %} +bool {{field.getter_method_name}}() const { + return {{field.name}}; +} +void {{field.setter_method_name}}() { + {{field.name}} = static_cast<unsigned>(true); +} +{% endmacro %}
diff --git a/third_party/WebKit/Source/core/BUILD.gn b/third_party/WebKit/Source/core/BUILD.gn index 23398e8..898288d 100644 --- a/third_party/WebKit/Source/core/BUILD.gn +++ b/third_party/WebKit/Source/core/BUILD.gn
@@ -266,6 +266,8 @@ "testing/OriginTrialsTest.cpp", "testing/OriginTrialsTest.h", "testing/OriginTrialsTestPartial.h", + "testing/RecordTest.cpp", + "testing/RecordTest.h", "testing/TypeConversions.h", "testing/UnionTypesTest.cpp", "testing/UnionTypesTest.h", @@ -403,6 +405,10 @@ css_properties("make_core_generated_computed_style_base") { script = "../build/scripts/make_computed_style_base.py" other_inputs = [ + "../build/scripts/templates/fields/base.tmpl", + "../build/scripts/templates/fields/keyword.tmpl", + "../build/scripts/templates/fields/flag.tmpl", + "../build/scripts/templates/fields/monotonic_flag.tmpl", "../build/scripts/templates/ComputedStyleBase.cpp.tmpl", "../build/scripts/templates/ComputedStyleBase.h.tmpl", "../build/scripts/templates/ComputedStyleBaseConstants.h.tmpl",
diff --git a/third_party/WebKit/Source/core/core_idl_files.gni b/third_party/WebKit/Source/core/core_idl_files.gni index 4a301d42..5f02fc6 100644 --- a/third_party/WebKit/Source/core/core_idl_files.gni +++ b/third_party/WebKit/Source/core/core_idl_files.gni
@@ -605,6 +605,7 @@ "testing/LayerRect.idl", "testing/LayerRectList.idl", "testing/OriginTrialsTest.idl", + "testing/RecordTest.idl", "testing/TypeConversions.idl", "testing/UnionTypesTest.idl", ],
diff --git a/third_party/WebKit/Source/core/css/CSSProperties.json5 b/third_party/WebKit/Source/core/css/CSSProperties.json5 index 7768ed42..e945bd9 100644 --- a/third_party/WebKit/Source/core/css/CSSProperties.json5 +++ b/third_party/WebKit/Source/core/css/CSSProperties.json5
@@ -66,6 +66,9 @@ // Field is stored a packed boolean flag and has a initial/getter/setter/resetter. // TODO(shend): generalise this to "primitive" "flag", + // Field is stored as a bool, whose default value is false + // and can only be set to true. Has a initial/getter/setter. + "monotonic_flag" ], },
diff --git a/third_party/WebKit/Source/core/dom/LayoutTreeBuilderTraversal.cpp b/third_party/WebKit/Source/core/dom/LayoutTreeBuilderTraversal.cpp index a502a2595..1fbcd95 100644 --- a/third_party/WebKit/Source/core/dom/LayoutTreeBuilderTraversal.cpp +++ b/third_party/WebKit/Source/core/dom/LayoutTreeBuilderTraversal.cpp
@@ -234,28 +234,69 @@ return nextSkippingChildren(node, stayWithin); } -static LayoutObject* nextSiblingLayoutObjectInternal(Node* node, - int32_t& limit) { +static Node* nextLayoutSiblingInternal(Node* node, int32_t& limit) { for (Node* sibling = node; sibling && limit-- != 0; sibling = LayoutTreeBuilderTraversal::nextSibling(*sibling)) { - LayoutObject* layoutObject = sibling->layoutObject(); + if (!hasDisplayContentsStyle(*sibling)) + return sibling; -#if DCHECK_IS_ON() - if (hasDisplayContentsStyle(*sibling)) - DCHECK(!layoutObject); -#endif + if (Node* inner = + nextLayoutSiblingInternal(pseudoAwareFirstChild(*sibling), limit)) + return inner; - if (!layoutObject && hasDisplayContentsStyle(*sibling)) { - layoutObject = nextSiblingLayoutObjectInternal( - pseudoAwareFirstChild(*sibling), limit); - if (layoutObject) - return layoutObject; - if (limit == -1) - return nullptr; - } + if (limit == -1) + return nullptr; + } - if (layoutObject && !isLayoutObjectReparented(layoutObject)) - return layoutObject; + return nullptr; +} + +Node* LayoutTreeBuilderTraversal::nextLayoutSibling(const Node& node, + int32_t& limit) { + DCHECK_NE(limit, -1); + if (Node* sibling = nextLayoutSiblingInternal(nextSibling(node), limit)) + return sibling; + + Node* parent = LayoutTreeBuilderTraversal::parent(node); + while (limit != -1 && parent && hasDisplayContentsStyle(*parent)) { + if (Node* sibling = nextLayoutSiblingInternal(nextSibling(*parent), limit)) + return sibling; + parent = LayoutTreeBuilderTraversal::parent(*parent); + } + + return nullptr; +} + +static Node* previousLayoutSiblingInternal(Node* node, int32_t& limit) { + for (Node* sibling = node; sibling && limit-- != 0; + sibling = LayoutTreeBuilderTraversal::previousSibling(*sibling)) { + if (!hasDisplayContentsStyle(*sibling)) + return sibling; + + if (Node* inner = previousLayoutSiblingInternal( + pseudoAwareLastChild(*sibling), limit)) + return inner; + + if (limit == -1) + return nullptr; + } + + return nullptr; +} + +Node* LayoutTreeBuilderTraversal::previousLayoutSibling(const Node& node, + int32_t& limit) { + DCHECK_NE(limit, -1); + if (Node* sibling = + previousLayoutSiblingInternal(previousSibling(node), limit)) + return sibling; + + Node* parent = LayoutTreeBuilderTraversal::parent(node); + while (limit != -1 && parent && hasDisplayContentsStyle(*parent)) { + if (Node* sibling = + previousLayoutSiblingInternal(previousSibling(*parent), limit)) + return sibling; + parent = LayoutTreeBuilderTraversal::parent(*parent); } return nullptr; @@ -265,45 +306,12 @@ const Node& node, int32_t limit) { DCHECK(limit == kTraverseAllSiblings || limit >= 0) << limit; - if (LayoutObject* sibling = - nextSiblingLayoutObjectInternal(nextSibling(node), limit)) - return sibling; - - Node* parent = LayoutTreeBuilderTraversal::parent(node); - while (limit != -1 && parent && hasDisplayContentsStyle(*parent)) { - if (LayoutObject* sibling = - nextSiblingLayoutObjectInternal(nextSibling(*parent), limit)) - return sibling; - parent = LayoutTreeBuilderTraversal::parent(*parent); - } - - return nullptr; -} - -static LayoutObject* previousSiblingLayoutObjectInternal(Node* node, - int32_t& limit) { - for (Node* sibling = node; sibling && limit-- != 0; - sibling = LayoutTreeBuilderTraversal::previousSibling(*sibling)) { + for (Node* sibling = nextLayoutSibling(node, limit); sibling && limit != -1; + sibling = nextLayoutSibling(*sibling, limit)) { LayoutObject* layoutObject = sibling->layoutObject(); - -#if DCHECK_IS_ON() - if (hasDisplayContentsStyle(*sibling)) - DCHECK(!layoutObject); -#endif - - if (!layoutObject && hasDisplayContentsStyle(*sibling)) { - layoutObject = previousSiblingLayoutObjectInternal( - pseudoAwareLastChild(*sibling), limit); - if (layoutObject) - return layoutObject; - if (limit == -1) - return nullptr; - } - if (layoutObject && !isLayoutObjectReparented(layoutObject)) return layoutObject; } - return nullptr; } @@ -311,18 +319,13 @@ const Node& node, int32_t limit) { DCHECK(limit == kTraverseAllSiblings || limit >= 0) << limit; - if (LayoutObject* sibling = - previousSiblingLayoutObjectInternal(previousSibling(node), limit)) - return sibling; - - Node* parent = LayoutTreeBuilderTraversal::parent(node); - while (limit != -1 && parent && hasDisplayContentsStyle(*parent)) { - if (LayoutObject* sibling = previousSiblingLayoutObjectInternal( - previousSibling(*parent), limit)) - return sibling; - parent = LayoutTreeBuilderTraversal::parent(*parent); + for (Node* sibling = previousLayoutSibling(node, limit); + sibling && limit != -1; + sibling = previousLayoutSibling(*sibling, limit)) { + LayoutObject* layoutObject = sibling->layoutObject(); + if (layoutObject && !isLayoutObjectReparented(layoutObject)) + return layoutObject; } - return nullptr; }
diff --git a/third_party/WebKit/Source/core/dom/LayoutTreeBuilderTraversal.h b/third_party/WebKit/Source/core/dom/LayoutTreeBuilderTraversal.h index 2d88e16..0053fc9d 100644 --- a/third_party/WebKit/Source/core/dom/LayoutTreeBuilderTraversal.h +++ b/third_party/WebKit/Source/core/dom/LayoutTreeBuilderTraversal.h
@@ -61,6 +61,14 @@ static ContainerNode* layoutParent(const Node&, ParentDetails* = nullptr); static Node* firstChild(const Node&); static Node* nextSibling(const Node&); + static Node* nextLayoutSibling(const Node& node) { + int32_t limit = kTraverseAllSiblings; + return nextLayoutSibling(node, limit); + } + static Node* previousLayoutSibling(const Node& node) { + int32_t limit = kTraverseAllSiblings; + return previousLayoutSibling(node, limit); + } static Node* previousSibling(const Node&); static Node* previous(const Node&, const Node* stayWithin); static Node* next(const Node&, const Node* stayWithin); @@ -78,6 +86,10 @@ ContainerNode* found = parent(node); return found && found->isElementNode() ? toElement(found) : 0; } + + private: + static Node* nextLayoutSibling(const Node&, int32_t& limit); + static Node* previousLayoutSibling(const Node&, int32_t& limit); }; } // namespace blink
diff --git a/third_party/WebKit/Source/core/frame/LocalFrameClient.h b/third_party/WebKit/Source/core/frame/LocalFrameClient.h index 3cf25b46..714313a 100644 --- a/third_party/WebKit/Source/core/frame/LocalFrameClient.h +++ b/third_party/WebKit/Source/core/frame/LocalFrameClient.h
@@ -299,10 +299,6 @@ virtual std::unique_ptr<WebServiceWorkerProvider> createServiceWorkerProvider() = 0; - virtual bool isControlledByServiceWorker(DocumentLoader&) = 0; - - virtual int64_t serviceWorkerID(DocumentLoader&) = 0; - virtual SharedWorkerRepositoryClient* sharedWorkerRepositoryClient() { return 0; }
diff --git a/third_party/WebKit/Source/core/layout/LayoutTextFragment.cpp b/third_party/WebKit/Source/core/layout/LayoutTextFragment.cpp index 72d1e4fd4..09e5c92 100644 --- a/third_party/WebKit/Source/core/layout/LayoutTextFragment.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutTextFragment.cpp
@@ -44,12 +44,7 @@ m_firstLetterPseudoElement(nullptr) {} LayoutTextFragment::LayoutTextFragment(Node* node, StringImpl* str) - : LayoutText(node, str), - m_start(0), - m_fragmentLength(str ? str->length() : 0), - m_isRemainingTextLayoutObject(false), - m_contentString(str), - m_firstLetterPseudoElement(nullptr) {} + : LayoutTextFragment(node, str, 0, str ? str->length() : 0) {} LayoutTextFragment::~LayoutTextFragment() { ASSERT(!m_firstLetterPseudoElement);
diff --git a/third_party/WebKit/Source/core/loader/DocumentLoader.cpp b/third_party/WebKit/Source/core/loader/DocumentLoader.cpp index 5942857..c6659cb 100644 --- a/third_party/WebKit/Source/core/loader/DocumentLoader.cpp +++ b/third_party/WebKit/Source/core/loader/DocumentLoader.cpp
@@ -73,6 +73,7 @@ #include "platform/weborigin/SchemeRegistry.h" #include "platform/weborigin/SecurityPolicy.h" #include "public/platform/Platform.h" +#include "public/platform/modules/serviceworker/WebServiceWorkerNetworkProvider.h" #include "wtf/Assertions.h" #include "wtf/AutoReset.h" #include "wtf/text/WTFString.h" @@ -229,6 +230,11 @@ return resource; } +void DocumentLoader::setServiceWorkerNetworkProvider( + std::unique_ptr<WebServiceWorkerNetworkProvider> provider) { + m_serviceWorkerNetworkProvider = std::move(provider); +} + void DocumentLoader::dispatchLinkHeaderPreloads( ViewportDescriptionWrapper* viewport, LinkLoader::MediaPreloadPolicy mediaPolicy) { @@ -652,6 +658,7 @@ m_fetcher->clearContext(); m_applicationCacheHost->detachFromDocumentLoader(); m_applicationCacheHost.clear(); + m_serviceWorkerNetworkProvider = nullptr; WeakIdentifierMap<DocumentLoader>::notifyObjectDestroyed(this); clearMainResourceHandle(); m_frame = nullptr;
diff --git a/third_party/WebKit/Source/core/loader/DocumentLoader.h b/third_party/WebKit/Source/core/loader/DocumentLoader.h index caa44f8..112552f 100644 --- a/third_party/WebKit/Source/core/loader/DocumentLoader.h +++ b/third_party/WebKit/Source/core/loader/DocumentLoader.h
@@ -64,6 +64,7 @@ class LocalFrameClient; class FrameLoader; class ResourceTimingInfo; +class WebServiceWorkerNetworkProvider; struct ViewportDescriptionWrapper; class CORE_EXPORT DocumentLoader @@ -189,6 +190,16 @@ Resource* startPreload(Resource::Type, FetchRequest&); + void setServiceWorkerNetworkProvider( + std::unique_ptr<WebServiceWorkerNetworkProvider>); + + // May return null before the first HTML tag is inserted by the + // parser (before didCreateDataSource is called), after the document + // is detached from frame, or in tests. + WebServiceWorkerNetworkProvider* getServiceWorkerNetworkProvider() { + return m_serviceWorkerNetworkProvider.get(); + } + DECLARE_VIRTUAL_TRACE(); protected: @@ -283,6 +294,9 @@ Member<ApplicationCacheHost> m_applicationCacheHost; + std::unique_ptr<WebServiceWorkerNetworkProvider> + m_serviceWorkerNetworkProvider; + Member<ContentSecurityPolicy> m_contentSecurityPolicy; ClientHintsPreferences m_clientHintsPreferences; InitialScrollState m_initialScrollState;
diff --git a/third_party/WebKit/Source/core/loader/EmptyClients.h b/third_party/WebKit/Source/core/loader/EmptyClients.h index 354c8eb..5c63535 100644 --- a/third_party/WebKit/Source/core/loader/EmptyClients.h +++ b/third_party/WebKit/Source/core/loader/EmptyClients.h
@@ -361,8 +361,6 @@ std::unique_ptr<WebServiceWorkerProvider> createServiceWorkerProvider() override; - bool isControlledByServiceWorker(DocumentLoader&) override { return false; } - int64_t serviceWorkerID(DocumentLoader&) override { return -1; } std::unique_ptr<WebApplicationCacheHost> createApplicationCacheHost( WebApplicationCacheHostClient*) override;
diff --git a/third_party/WebKit/Source/core/loader/FrameFetchContext.cpp b/third_party/WebKit/Source/core/loader/FrameFetchContext.cpp index 9ccd820..b62fe64 100644 --- a/third_party/WebKit/Source/core/loader/FrameFetchContext.cpp +++ b/third_party/WebKit/Source/core/loader/FrameFetchContext.cpp
@@ -82,6 +82,7 @@ #include "public/platform/WebCachePolicy.h" #include "public/platform/WebInsecureRequestPolicy.h" #include "public/platform/WebViewScheduler.h" +#include "public/platform/modules/serviceworker/WebServiceWorkerNetworkProvider.h" #include "wtf/Vector.h" namespace blink { @@ -823,13 +824,18 @@ if (getSecurityOrigin() && getSecurityOrigin()->hasSuborigin()) return false; - return localFrameClient()->isControlledByServiceWorker( - *masterDocumentLoader()); + auto* service_worker_network_provider = + masterDocumentLoader()->getServiceWorkerNetworkProvider(); + return service_worker_network_provider && + service_worker_network_provider->isControlledByServiceWorker(); } int64_t FrameFetchContext::serviceWorkerID() const { DCHECK(masterDocumentLoader()); - return localFrameClient()->serviceWorkerID(*masterDocumentLoader()); + auto* service_worker_network_provider = + masterDocumentLoader()->getServiceWorkerNetworkProvider(); + return service_worker_network_provider && + service_worker_network_provider->serviceWorkerID(); } bool FrameFetchContext::isMainFrame() const {
diff --git a/third_party/WebKit/Source/core/loader/FrameLoader.cpp b/third_party/WebKit/Source/core/loader/FrameLoader.cpp index 0b2a00a..c62bf54 100644 --- a/third_party/WebKit/Source/core/loader/FrameLoader.cpp +++ b/third_party/WebKit/Source/core/loader/FrameLoader.cpp
@@ -100,6 +100,7 @@ #include "public/platform/WebCachePolicy.h" #include "public/platform/WebFeaturePolicy.h" #include "public/platform/WebURLRequest.h" +#include "public/platform/modules/serviceworker/WebServiceWorkerNetworkProvider.h" #include "wtf/AutoReset.h" #include "wtf/text/CString.h" #include "wtf/text/WTFString.h" @@ -486,7 +487,9 @@ // didObserveLoadingBehavior() must be called after dispatchDidCommitLoad() is // called for the metrics tracking logic to handle it properly. - if (client()->isControlledByServiceWorker(*m_documentLoader)) { + if (m_documentLoader->getServiceWorkerNetworkProvider() && + m_documentLoader->getServiceWorkerNetworkProvider() + ->isControlledByServiceWorker()) { client()->didObserveLoadingBehavior( WebLoadingBehaviorServiceWorkerControlled); }
diff --git a/third_party/WebKit/Source/core/testing/Internals.cpp b/third_party/WebKit/Source/core/testing/Internals.cpp index 7c57d5d2..11e72f6f 100644 --- a/third_party/WebKit/Source/core/testing/Internals.cpp +++ b/third_party/WebKit/Source/core/testing/Internals.cpp
@@ -122,6 +122,7 @@ #include "core/testing/LayerRectList.h" #include "core/testing/MockHyphenation.h" #include "core/testing/OriginTrialsTest.h" +#include "core/testing/RecordTest.h" #include "core/testing/TypeConversions.h" #include "core/testing/UnionTypesTest.h" #include "core/workers/WorkerThread.h" @@ -2365,6 +2366,10 @@ return DictionaryTest::create(); } +RecordTest* Internals::recordTest() const { + return RecordTest::create(); +} + UnionTypesTest* Internals::unionTypesTest() const { return UnionTypesTest::create(); }
diff --git a/third_party/WebKit/Source/core/testing/Internals.h b/third_party/WebKit/Source/core/testing/Internals.h index 8565c296..f62929b 100644 --- a/third_party/WebKit/Source/core/testing/Internals.h +++ b/third_party/WebKit/Source/core/testing/Internals.h
@@ -68,6 +68,7 @@ class OriginTrialsTest; class Page; class Range; +class RecordTest; class SerializedScriptValue; class ShadowRoot; class TypeConversions; @@ -380,6 +381,7 @@ const String& scheme); TypeConversions* typeConversions() const; + RecordTest* recordTest() const; DictionaryTest* dictionaryTest() const; UnionTypesTest* unionTypesTest() const; OriginTrialsTest* originTrialsTest() const;
diff --git a/third_party/WebKit/Source/core/testing/Internals.idl b/third_party/WebKit/Source/core/testing/Internals.idl index 56ebdf7..cafc80a 100644 --- a/third_party/WebKit/Source/core/testing/Internals.idl +++ b/third_party/WebKit/Source/core/testing/Internals.idl
@@ -319,6 +319,7 @@ unsigned long canvasFontCacheMaxFonts(); DictionaryTest dictionaryTest(); + RecordTest recordTest(); UnionTypesTest unionTypesTest(); CallbackFunctionTest callbackFunctionTest(); [RaisesException] void setScrollChain(ScrollState scrollState, sequence<Element> elements);
diff --git a/third_party/WebKit/Source/core/testing/RecordTest.cpp b/third_party/WebKit/Source/core/testing/RecordTest.cpp new file mode 100644 index 0000000..f4e79e6 --- /dev/null +++ b/third_party/WebKit/Source/core/testing/RecordTest.cpp
@@ -0,0 +1,83 @@ +// 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 "RecordTest.h" + +namespace blink { + +RecordTest::RecordTest() {} + +RecordTest::~RecordTest() {} + +void RecordTest::setStringLongRecord( + const Vector<std::pair<String, int32_t>>& arg) { + m_stringLongRecord = arg; +} + +Vector<std::pair<String, int32_t>> RecordTest::getStringLongRecord() { + return m_stringLongRecord; +} + +void RecordTest::setNullableStringLongRecord( + const Nullable<Vector<std::pair<String, int32_t>>>& arg) { + m_nullableStringLongRecord = arg; +} + +Nullable<Vector<std::pair<String, int32_t>>> +RecordTest::getNullableStringLongRecord() { + return m_nullableStringLongRecord; +} + +Vector<std::pair<String, String>> RecordTest::getByteStringByteStringRecord() { + return m_byteStringByteStringRecord; +} + +void RecordTest::setByteStringByteStringRecord( + const Vector<std::pair<String, String>>& arg) { + m_byteStringByteStringRecord = arg; +} + +void RecordTest::setStringElementRecord( + const HeapVector<std::pair<String, Member<Element>>>& arg) { + m_stringElementRecord = arg; +} + +HeapVector<std::pair<String, Member<Element>>> +RecordTest::getStringElementRecord() { + return m_stringElementRecord; +} + +void RecordTest::setUSVStringUSVStringBooleanRecordRecord( + const RecordTest::NestedRecordType& arg) { + m_USVStringUSVStringBooleanRecordRecord = arg; +} + +RecordTest::NestedRecordType +RecordTest::getUSVStringUSVStringBooleanRecordRecord() { + return m_USVStringUSVStringBooleanRecordRecord; +} + +Vector<std::pair<String, Vector<String>>> +RecordTest::returnStringByteStringSequenceRecord() { + Vector<std::pair<String, Vector<String>>> record; + Vector<String> innerVector1; + innerVector1.push_back("hello, world"); + innerVector1.push_back("hi, mom"); + record.push_back(std::make_pair(String("foo"), innerVector1)); + Vector<String> innerVector2; + innerVector2.push_back("goodbye, mom"); + record.push_back(std::make_pair(String("bar"), innerVector2)); + return record; +} + +bool RecordTest::unionReceivedARecord( + const BooleanOrByteStringByteStringRecord& arg) { + return arg.isByteStringByteStringRecord(); +} + +DEFINE_TRACE(RecordTest) { + visitor->trace(m_stringElementRecord); +} + +} // namespace blink
diff --git a/third_party/WebKit/Source/core/testing/RecordTest.h b/third_party/WebKit/Source/core/testing/RecordTest.h new file mode 100644 index 0000000..ceb6f87fe --- /dev/null +++ b/third_party/WebKit/Source/core/testing/RecordTest.h
@@ -0,0 +1,69 @@ +// 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 RecordTest_h +#define RecordTest_h + +#include <utility> +#include "bindings/core/v8/BooleanOrByteStringByteStringRecord.h" +#include "bindings/core/v8/FloatOrStringElementRecord.h" +#include "bindings/core/v8/Nullable.h" +#include "bindings/core/v8/ScriptWrappable.h" +#include "core/dom/Element.h" +#include "platform/heap/Handle.h" +#include "wtf/Vector.h" +#include "wtf/text/WTFString.h" + +namespace blink { + +class RecordTest final : public GarbageCollectedFinalized<RecordTest>, + public ScriptWrappable { + DEFINE_WRAPPERTYPEINFO(); + + public: + static RecordTest* create() { return new RecordTest; } + ~RecordTest(); + + void setStringLongRecord(const Vector<std::pair<String, int32_t>>& arg); + Vector<std::pair<String, int32_t>> getStringLongRecord(); + + void setNullableStringLongRecord( + const Nullable<Vector<std::pair<String, int32_t>>>& arg); + Nullable<Vector<std::pair<String, int32_t>>> getNullableStringLongRecord(); + + Vector<std::pair<String, String>> getByteStringByteStringRecord(); + void setByteStringByteStringRecord( + const Vector<std::pair<String, String>>& arg); + + void setStringElementRecord( + const HeapVector<std::pair<String, Member<Element>>>& arg); + HeapVector<std::pair<String, Member<Element>>> getStringElementRecord(); + + using NestedRecordType = + Vector<std::pair<String, Vector<std::pair<String, bool>>>>; + void setUSVStringUSVStringBooleanRecordRecord(const NestedRecordType& arg); + NestedRecordType getUSVStringUSVStringBooleanRecordRecord(); + + Vector<std::pair<String, Vector<String>>> + returnStringByteStringSequenceRecord(); + + bool unionReceivedARecord(const BooleanOrByteStringByteStringRecord& arg); + + void setFloatOrStringElementRecord(const FloatOrStringElementRecord&){}; + + DECLARE_TRACE(); + + private: + RecordTest(); + + Vector<std::pair<String, int32_t>> m_stringLongRecord; + Nullable<Vector<std::pair<String, int32_t>>> m_nullableStringLongRecord; + Vector<std::pair<String, String>> m_byteStringByteStringRecord; + HeapVector<std::pair<String, Member<Element>>> m_stringElementRecord; + NestedRecordType m_USVStringUSVStringBooleanRecordRecord; +}; + +} // namespace blink + +#endif // RecordTest_h
diff --git a/third_party/WebKit/Source/core/testing/RecordTest.idl b/third_party/WebKit/Source/core/testing/RecordTest.idl new file mode 100644 index 0000000..4d2b153 --- /dev/null +++ b/third_party/WebKit/Source/core/testing/RecordTest.idl
@@ -0,0 +1,29 @@ +// 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. + +typedef record<DOMString, long> RecordTypedef; + +interface RecordTest { + void setStringLongRecord(RecordTypedef arg); + RecordTypedef getStringLongRecord(); + + void setNullableStringLongRecord(RecordTypedef? arg); + RecordTypedef? getNullableStringLongRecord(); + + void setByteStringByteStringRecord(record<ByteString, ByteString> arg); + + void setStringElementRecord(record<DOMString, Element> arg); + record<DOMString, Element> getStringElementRecord(); + + void setUSVStringUSVStringBooleanRecordRecord(record<USVString, record<USVString, boolean>> arg); + record<USVString, record<USVString, boolean>> getUSVStringUSVStringBooleanRecordRecord(); + + record<DOMString, sequence<ByteString>> returnStringByteStringSequenceRecord(); + + boolean unionReceivedARecord((boolean or record<ByteString, ByteString>) arg); + + // Test the bindings generator code: unions and dictionaries must trace a + // record when it's represented as a HeapVector. + void setFloatOrStringElementRecord((float or record<DOMString, Element>) arg); +};
diff --git a/third_party/WebKit/Source/modules/BUILD.gn b/third_party/WebKit/Source/modules/BUILD.gn index 342b6c2e..1d05da24 100644 --- a/third_party/WebKit/Source/modules/BUILD.gn +++ b/third_party/WebKit/Source/modules/BUILD.gn
@@ -93,6 +93,7 @@ "//third_party/WebKit/Source/modules/accessibility", "//third_party/WebKit/Source/modules/app_banner", "//third_party/WebKit/Source/modules/audio_output_devices", + "//third_party/WebKit/Source/modules/background_fetch", "//third_party/WebKit/Source/modules/background_sync", "//third_party/WebKit/Source/modules/battery", "//third_party/WebKit/Source/modules/beacon",
diff --git a/third_party/WebKit/Source/modules/background_fetch/BUILD.gn b/third_party/WebKit/Source/modules/background_fetch/BUILD.gn new file mode 100644 index 0000000..33d44004 --- /dev/null +++ b/third_party/WebKit/Source/modules/background_fetch/BUILD.gn
@@ -0,0 +1,14 @@ +# 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. + +import("//third_party/WebKit/Source/modules/modules.gni") + +blink_modules_sources("background_fetch") { + sources = [ + "BackgroundFetchManager.cpp", + "BackgroundFetchManager.h", + "ServiceWorkerRegistrationBackgroundFetch.cpp", + "ServiceWorkerRegistrationBackgroundFetch.h", + ] +}
diff --git a/third_party/WebKit/Source/modules/background_fetch/BackgroundFetchManager.cpp b/third_party/WebKit/Source/modules/background_fetch/BackgroundFetchManager.cpp new file mode 100644 index 0000000..27fabfc --- /dev/null +++ b/third_party/WebKit/Source/modules/background_fetch/BackgroundFetchManager.cpp
@@ -0,0 +1,29 @@ +// 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 "modules/background_fetch/BackgroundFetchManager.h" + +#include "bindings/core/v8/ScriptState.h" +#include "core/dom/DOMException.h" +#include "modules/serviceworkers/ServiceWorkerRegistration.h" + +namespace blink { + +BackgroundFetchManager::BackgroundFetchManager( + ServiceWorkerRegistration* registration) + : m_registration(registration) { + DCHECK(registration); +} + +ScriptPromise BackgroundFetchManager::getTags(ScriptState* scriptState) { + return ScriptPromise::rejectWithDOMException( + scriptState, + DOMException::create(NotSupportedError, "Not implemented yet.")); +} + +DEFINE_TRACE(BackgroundFetchManager) { + visitor->trace(m_registration); +} + +} // namespace blink
diff --git a/third_party/WebKit/Source/modules/background_fetch/BackgroundFetchManager.h b/third_party/WebKit/Source/modules/background_fetch/BackgroundFetchManager.h new file mode 100644 index 0000000..67d1819 --- /dev/null +++ b/third_party/WebKit/Source/modules/background_fetch/BackgroundFetchManager.h
@@ -0,0 +1,43 @@ +// 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 BackgroundFetchManager_h +#define BackgroundFetchManager_h + +#include "bindings/core/v8/ScriptPromise.h" +#include "bindings/core/v8/ScriptWrappable.h" +#include "platform/heap/GarbageCollected.h" +#include "platform/heap/Handle.h" + +namespace blink { + +class ScriptState; +class ServiceWorkerRegistration; + +// Implementation of the BackgroundFetchManager JavaScript object, accessible +// by developers through ServiceWorkerRegistration.backgroundFetch. +class BackgroundFetchManager final + : public GarbageCollected<BackgroundFetchManager>, + public ScriptWrappable { + DEFINE_WRAPPERTYPEINFO(); + + public: + static BackgroundFetchManager* create( + ServiceWorkerRegistration* registration) { + return new BackgroundFetchManager(registration); + } + + ScriptPromise getTags(ScriptState*); + + DECLARE_TRACE(); + + private: + explicit BackgroundFetchManager(ServiceWorkerRegistration*); + + Member<ServiceWorkerRegistration> m_registration; +}; + +} // namespace blink + +#endif // BackgroundFetchManager_h
diff --git a/third_party/WebKit/Source/modules/background_fetch/BackgroundFetchManager.idl b/third_party/WebKit/Source/modules/background_fetch/BackgroundFetchManager.idl new file mode 100644 index 0000000..18b02a80 --- /dev/null +++ b/third_party/WebKit/Source/modules/background_fetch/BackgroundFetchManager.idl
@@ -0,0 +1,15 @@ +// 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. + +// https://wicg.github.io/background-fetch/#background-fetch-manager + +[ + Exposed=(Window,Worker), + RuntimeEnabled=BackgroundFetch +] interface BackgroundFetchManager { + // TODO(peter): Implement the `fetch` method. + // TODO(peter): Implement the `get` method. + + [CallWith=ScriptState] Promise<FrozenArray<DOMString>> getTags(); +};
diff --git a/third_party/WebKit/Source/modules/background_fetch/OWNERS b/third_party/WebKit/Source/modules/background_fetch/OWNERS new file mode 100644 index 0000000..569df4e --- /dev/null +++ b/third_party/WebKit/Source/modules/background_fetch/OWNERS
@@ -0,0 +1,4 @@ +peter@chromium.org + +# TEAM: platform-capabilities@chromium.org +# COMPONENT: Blink>BackgroundFetch
diff --git a/third_party/WebKit/Source/modules/background_fetch/ServiceWorkerRegistrationBackgroundFetch.cpp b/third_party/WebKit/Source/modules/background_fetch/ServiceWorkerRegistrationBackgroundFetch.cpp new file mode 100644 index 0000000..f2ae0f1 --- /dev/null +++ b/third_party/WebKit/Source/modules/background_fetch/ServiceWorkerRegistrationBackgroundFetch.cpp
@@ -0,0 +1,60 @@ +// 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 "modules/background_fetch/ServiceWorkerRegistrationBackgroundFetch.h" + +#include "modules/background_fetch/BackgroundFetchManager.h" + +namespace blink { + +ServiceWorkerRegistrationBackgroundFetch:: + ServiceWorkerRegistrationBackgroundFetch( + ServiceWorkerRegistration* registration) + : m_registration(registration) {} + +ServiceWorkerRegistrationBackgroundFetch:: + ~ServiceWorkerRegistrationBackgroundFetch() = default; + +const char* ServiceWorkerRegistrationBackgroundFetch::supplementName() { + return "ServiceWorkerRegistrationBackgroundFetch"; +} + +ServiceWorkerRegistrationBackgroundFetch& +ServiceWorkerRegistrationBackgroundFetch::from( + ServiceWorkerRegistration& registration) { + ServiceWorkerRegistrationBackgroundFetch* supplement = + static_cast<ServiceWorkerRegistrationBackgroundFetch*>( + Supplement<ServiceWorkerRegistration>::from(registration, + supplementName())); + + if (!supplement) { + supplement = new ServiceWorkerRegistrationBackgroundFetch(®istration); + provideTo(registration, supplementName(), supplement); + } + + return *supplement; +} + +BackgroundFetchManager* +ServiceWorkerRegistrationBackgroundFetch::backgroundFetch( + ServiceWorkerRegistration& registration) { + return ServiceWorkerRegistrationBackgroundFetch::from(registration) + .backgroundFetch(); +} + +BackgroundFetchManager* +ServiceWorkerRegistrationBackgroundFetch::backgroundFetch() { + if (!m_backgroundFetchManager) + m_backgroundFetchManager = BackgroundFetchManager::create(m_registration); + + return m_backgroundFetchManager.get(); +} + +DEFINE_TRACE(ServiceWorkerRegistrationBackgroundFetch) { + visitor->trace(m_registration); + visitor->trace(m_backgroundFetchManager); + Supplement<ServiceWorkerRegistration>::trace(visitor); +} + +} // namespace blink
diff --git a/third_party/WebKit/Source/modules/background_fetch/ServiceWorkerRegistrationBackgroundFetch.h b/third_party/WebKit/Source/modules/background_fetch/ServiceWorkerRegistrationBackgroundFetch.h new file mode 100644 index 0000000..98d7aeb --- /dev/null +++ b/third_party/WebKit/Source/modules/background_fetch/ServiceWorkerRegistrationBackgroundFetch.h
@@ -0,0 +1,45 @@ +// 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 ServiceWorkerRegistrationBackgroundFetch_h +#define ServiceWorkerRegistrationBackgroundFetch_h + +#include "modules/serviceworkers/ServiceWorkerRegistration.h" +#include "platform/Supplementable.h" +#include "platform/heap/GarbageCollected.h" +#include "platform/heap/Handle.h" + +namespace blink { + +class BackgroundFetchManager; + +class ServiceWorkerRegistrationBackgroundFetch final + : public GarbageCollectedFinalized< + ServiceWorkerRegistrationBackgroundFetch>, + public Supplement<ServiceWorkerRegistration> { + USING_GARBAGE_COLLECTED_MIXIN(ServiceWorkerRegistrationBackgroundFetch); + WTF_MAKE_NONCOPYABLE(ServiceWorkerRegistrationBackgroundFetch); + + public: + virtual ~ServiceWorkerRegistrationBackgroundFetch(); + + static ServiceWorkerRegistrationBackgroundFetch& from( + ServiceWorkerRegistration&); + + static BackgroundFetchManager* backgroundFetch(ServiceWorkerRegistration&); + BackgroundFetchManager* backgroundFetch(); + + DECLARE_VIRTUAL_TRACE(); + + private: + explicit ServiceWorkerRegistrationBackgroundFetch(ServiceWorkerRegistration*); + static const char* supplementName(); + + Member<ServiceWorkerRegistration> m_registration; + Member<BackgroundFetchManager> m_backgroundFetchManager; +}; + +} // namespace blink + +#endif // ServiceWorkerRegistrationBackgroundFetch_h
diff --git a/third_party/WebKit/Source/modules/background_fetch/ServiceWorkerRegistrationBackgroundFetch.idl b/third_party/WebKit/Source/modules/background_fetch/ServiceWorkerRegistrationBackgroundFetch.idl new file mode 100644 index 0000000..9d0ffdc --- /dev/null +++ b/third_party/WebKit/Source/modules/background_fetch/ServiceWorkerRegistrationBackgroundFetch.idl
@@ -0,0 +1,12 @@ +// 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. + +// https://wicg.github.io/background-fetch/#extensions-to-service-worker-registration + +[ + Exposed=(Window,Worker), + RuntimeEnabled=BackgroundFetch +] partial interface ServiceWorkerRegistration { + readonly attribute BackgroundFetchManager backgroundFetch; +};
diff --git a/third_party/WebKit/Source/modules/modules_idl_files.gni b/third_party/WebKit/Source/modules/modules_idl_files.gni index 934f168..4880c79 100644 --- a/third_party/WebKit/Source/modules/modules_idl_files.gni +++ b/third_party/WebKit/Source/modules/modules_idl_files.gni
@@ -41,6 +41,7 @@ get_path_info([ "app_banner/AppBannerPromptResult.idl", "app_banner/BeforeInstallPromptEvent.idl", + "background_fetch/BackgroundFetchManager.idl", "background_sync/SyncEvent.idl", "background_sync/SyncManager.idl", "battery/BatteryManager.idl", @@ -555,6 +556,7 @@ get_path_info( [ "audio_output_devices/HTMLMediaElementAudioOutputDevice.idl", + "background_fetch/ServiceWorkerRegistrationBackgroundFetch.idl", "background_sync/ServiceWorkerGlobalScopeSync.idl", "background_sync/ServiceWorkerRegistrationSync.idl", "battery/NavigatorBattery.idl",
diff --git a/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.json5 b/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.json5 index 83b46fe..c582489 100644 --- a/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.json5 +++ b/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.json5
@@ -86,6 +86,10 @@ status: "stable", }, { + name: "BackgroundFetch", + status: "test", + }, + { name: "BackgroundSync", status: "stable", },
diff --git a/third_party/WebKit/Source/platform/exported/WebURLRequest.cpp b/third_party/WebKit/Source/platform/exported/WebURLRequest.cpp index 893a4163..88b0ea0 100644 --- a/third_party/WebKit/Source/platform/exported/WebURLRequest.cpp +++ b/third_party/WebKit/Source/platform/exported/WebURLRequest.cpp
@@ -364,7 +364,8 @@ } void WebURLRequest::setExtraData(WebURLRequest::ExtraData* extraData) { - m_resourceRequest->setExtraData(ExtraDataContainer::create(extraData)); + if (extraData != getExtraData()) + m_resourceRequest->setExtraData(ExtraDataContainer::create(extraData)); } ResourceRequest& WebURLRequest::toMutableResourceRequest() {
diff --git a/third_party/WebKit/Source/platform/exported/WebURLResponse.cpp b/third_party/WebKit/Source/platform/exported/WebURLResponse.cpp index 92e913cc..852323a 100644 --- a/third_party/WebKit/Source/platform/exported/WebURLResponse.cpp +++ b/third_party/WebKit/Source/platform/exported/WebURLResponse.cpp
@@ -369,7 +369,8 @@ } void WebURLResponse::setExtraData(WebURLResponse::ExtraData* extraData) { - m_resourceResponse->setExtraData(ExtraDataContainer::create(extraData)); + if (extraData != getExtraData()) + m_resourceResponse->setExtraData(ExtraDataContainer::create(extraData)); } void WebURLResponse::appendRedirectResponse(const WebURLResponse& response) {
diff --git a/third_party/WebKit/Source/web/LocalFrameClientImpl.cpp b/third_party/WebKit/Source/web/LocalFrameClientImpl.cpp index 73c1b65e..31528fbc 100644 --- a/third_party/WebKit/Source/web/LocalFrameClientImpl.cpp +++ b/third_party/WebKit/Source/web/LocalFrameClientImpl.cpp
@@ -946,19 +946,6 @@ return WTF::wrapUnique(m_webFrame->client()->createServiceWorkerProvider()); } -bool LocalFrameClientImpl::isControlledByServiceWorker(DocumentLoader& loader) { - return m_webFrame->client() && - m_webFrame->client()->isControlledByServiceWorker( - *WebDataSourceImpl::fromDocumentLoader(&loader)); -} - -int64_t LocalFrameClientImpl::serviceWorkerID(DocumentLoader& loader) { - if (!m_webFrame->client()) - return -1; - return m_webFrame->client()->serviceWorkerID( - *WebDataSourceImpl::fromDocumentLoader(&loader)); -} - SharedWorkerRepositoryClient* LocalFrameClientImpl::sharedWorkerRepositoryClient() { return m_webFrame->sharedWorkerRepositoryClient();
diff --git a/third_party/WebKit/Source/web/LocalFrameClientImpl.h b/third_party/WebKit/Source/web/LocalFrameClientImpl.h index 203a6cb..f5fbad33 100644 --- a/third_party/WebKit/Source/web/LocalFrameClientImpl.h +++ b/third_party/WebKit/Source/web/LocalFrameClientImpl.h
@@ -199,8 +199,6 @@ std::unique_ptr<WebServiceWorkerProvider> createServiceWorkerProvider() override; - bool isControlledByServiceWorker(DocumentLoader&) override; - int64_t serviceWorkerID(DocumentLoader&) override; SharedWorkerRepositoryClient* sharedWorkerRepositoryClient() override; std::unique_ptr<WebApplicationCacheHost> createApplicationCacheHost(
diff --git a/third_party/WebKit/Source/web/WebDataSourceImpl.cpp b/third_party/WebKit/Source/web/WebDataSourceImpl.cpp index c89c9bf..d8a3caf 100644 --- a/third_party/WebKit/Source/web/WebDataSourceImpl.cpp +++ b/third_party/WebKit/Source/web/WebDataSourceImpl.cpp
@@ -37,6 +37,7 @@ #include "public/platform/WebURL.h" #include "public/platform/WebURLError.h" #include "public/platform/WebVector.h" +#include "public/platform/modules/serviceworker/WebServiceWorkerNetworkProvider.h" #include "wtf/PtrUtil.h" namespace blink { @@ -161,6 +162,16 @@ SubresourceFilter::create(this, WTF::wrapUnique(subresourceFilter))); } +void WebDataSourceImpl::setServiceWorkerNetworkProvider( + std::unique_ptr<WebServiceWorkerNetworkProvider> provider) { + DocumentLoader::setServiceWorkerNetworkProvider(std::move(provider)); +} + +WebServiceWorkerNetworkProvider* +WebDataSourceImpl::getServiceWorkerNetworkProvider() { + return DocumentLoader::getServiceWorkerNetworkProvider(); +} + DEFINE_TRACE(WebDataSourceImpl) { DocumentLoader::trace(visitor); }
diff --git a/third_party/WebKit/Source/web/WebDataSourceImpl.h b/third_party/WebKit/Source/web/WebDataSourceImpl.h index f0f464d..f09ccb0 100644 --- a/third_party/WebKit/Source/web/WebDataSourceImpl.h +++ b/third_party/WebKit/Source/web/WebDataSourceImpl.h
@@ -73,6 +73,9 @@ double fetchStartTime, bool hasRedirect) override; void setSubresourceFilter(WebDocumentSubresourceFilter*) override; + void setServiceWorkerNetworkProvider( + std::unique_ptr<WebServiceWorkerNetworkProvider>) override; + WebServiceWorkerNetworkProvider* getServiceWorkerNetworkProvider() override; static WebNavigationType toWebNavigationType(NavigationType);
diff --git a/third_party/WebKit/Source/web/WebEmbeddedWorkerImpl.cpp b/third_party/WebKit/Source/web/WebEmbeddedWorkerImpl.cpp index 3135c41..7ed9670 100644 --- a/third_party/WebKit/Source/web/WebEmbeddedWorkerImpl.cpp +++ b/third_party/WebKit/Source/web/WebEmbeddedWorkerImpl.cpp
@@ -59,6 +59,7 @@ #include "platform/weborigin/SecurityOrigin.h" #include "public/platform/Platform.h" #include "public/platform/WebURLRequest.h" +#include "public/platform/modules/serviceworker/WebServiceWorkerNetworkProvider.h" #include "public/platform/modules/serviceworker/WebServiceWorkerProvider.h" #include "public/web/WebConsoleMessage.h" #include "public/web/WebDevToolsAgent.h" @@ -66,7 +67,6 @@ #include "public/web/WebView.h" #include "public/web/WebWorkerContentSettingsClientProxy.h" #include "public/web/modules/serviceworker/WebServiceWorkerContextClient.h" -#include "public/web/modules/serviceworker/WebServiceWorkerNetworkProvider.h" #include "web/IndexedDBClientImpl.h" #include "web/ServiceWorkerGlobalScopeClientImpl.h" #include "web/ServiceWorkerGlobalScopeProxy.h" @@ -333,21 +333,21 @@ void WebEmbeddedWorkerImpl::willSendRequest(WebLocalFrame* frame, WebURLRequest& request) { - if (m_networkProvider) - m_networkProvider->willSendRequest(frame->dataSource(), request); + auto* networkProvider = + frame->dataSource()->getServiceWorkerNetworkProvider(); + if (networkProvider) + networkProvider->willSendRequest(request); } void WebEmbeddedWorkerImpl::didFinishDocumentLoad(WebLocalFrame* frame) { DCHECK(!m_mainScriptLoader); - DCHECK(!m_networkProvider); DCHECK(m_mainFrame); DCHECK(m_workerContextClient); DCHECK(m_loadingShadowPage); DCHECK(!m_askedToTerminate); m_loadingShadowPage = false; - m_networkProvider = - WTF::wrapUnique(m_workerContextClient->createServiceWorkerNetworkProvider( - frame->dataSource())); + frame->dataSource()->setServiceWorkerNetworkProvider(WTF::wrapUnique( + m_workerContextClient->createServiceWorkerNetworkProvider())); m_mainScriptLoader = WorkerScriptLoader::create(); m_mainScriptLoader->setRequestContext( WebURLRequest::RequestContextServiceWorker);
diff --git a/third_party/WebKit/Source/web/WebEmbeddedWorkerImpl.h b/third_party/WebKit/Source/web/WebEmbeddedWorkerImpl.h index d98cd69..0c49784 100644 --- a/third_party/WebKit/Source/web/WebEmbeddedWorkerImpl.h +++ b/third_party/WebKit/Source/web/WebEmbeddedWorkerImpl.h
@@ -47,7 +47,6 @@ class ParentFrameTaskRunners; class ServiceWorkerGlobalScopeProxy; class WebLocalFrameImpl; -class WebServiceWorkerNetworkProvider; class WebView; class WorkerInspectorProxy; class WorkerScriptLoader; @@ -117,10 +116,6 @@ // to WorkerContext. std::unique_ptr<WebWorkerContentSettingsClientProxy> m_contentSettingsClient; - // We retain ownership of this one which is for use on the - // main thread only. - std::unique_ptr<WebServiceWorkerNetworkProvider> m_networkProvider; - // Kept around only while main script loading is ongoing. RefPtr<WorkerScriptLoader> m_mainScriptLoader;
diff --git a/third_party/WebKit/Source/web/WebEmbeddedWorkerImplTest.cpp b/third_party/WebKit/Source/web/WebEmbeddedWorkerImplTest.cpp index e7aa6ec..6f5937b 100644 --- a/third_party/WebKit/Source/web/WebEmbeddedWorkerImplTest.cpp +++ b/third_party/WebKit/Source/web/WebEmbeddedWorkerImplTest.cpp
@@ -28,8 +28,8 @@ MOCK_METHOD0(workerReadyForInspection, void()); MOCK_METHOD0(workerContextFailedToStart, void()); MOCK_METHOD0(workerScriptLoaded, void()); - MOCK_METHOD1(createServiceWorkerNetworkProvider, - WebServiceWorkerNetworkProvider*(WebDataSource*)); + MOCK_METHOD0(createServiceWorkerNetworkProvider, + WebServiceWorkerNetworkProvider*()); MOCK_METHOD0(createServiceWorkerProvider, WebServiceWorkerProvider*()); bool hasAssociatedRegistration() override { return m_hasAssociatedRegistration; @@ -143,7 +143,7 @@ ::testing::Mock::VerifyAndClearExpectations(m_mockClient); // Load the shadow page. - EXPECT_CALL(*m_mockClient, createServiceWorkerNetworkProvider(::testing::_)) + EXPECT_CALL(*m_mockClient, createServiceWorkerNetworkProvider()) .WillOnce(::testing::Return(nullptr)); Platform::current()->getURLLoaderMockFactory()->serveAsynchronousRequests(); ::testing::Mock::VerifyAndClearExpectations(m_mockClient); @@ -162,7 +162,7 @@ ::testing::Mock::VerifyAndClearExpectations(m_mockClient); // Load the shadow page. - EXPECT_CALL(*m_mockClient, createServiceWorkerNetworkProvider(::testing::_)) + EXPECT_CALL(*m_mockClient, createServiceWorkerNetworkProvider()) .WillOnce(::testing::Return(nullptr)); Platform::current()->getURLLoaderMockFactory()->serveAsynchronousRequests(); ::testing::Mock::VerifyAndClearExpectations(m_mockClient); @@ -198,7 +198,7 @@ ::testing::Mock::VerifyAndClearExpectations(m_mockClient); // Load the shadow page. - EXPECT_CALL(*m_mockClient, createServiceWorkerNetworkProvider(::testing::_)) + EXPECT_CALL(*m_mockClient, createServiceWorkerNetworkProvider()) .WillOnce(::testing::Return(nullptr)); Platform::current()->getURLLoaderMockFactory()->serveAsynchronousRequests(); ::testing::Mock::VerifyAndClearExpectations(m_mockClient); @@ -219,7 +219,7 @@ ::testing::Mock::VerifyAndClearExpectations(m_mockClient); // Load the shadow page. - EXPECT_CALL(*m_mockClient, createServiceWorkerNetworkProvider(::testing::_)) + EXPECT_CALL(*m_mockClient, createServiceWorkerNetworkProvider()) .WillOnce(::testing::Return(nullptr)); Platform::current()->getURLLoaderMockFactory()->serveAsynchronousRequests(); ::testing::Mock::VerifyAndClearExpectations(m_mockClient); @@ -246,7 +246,7 @@ ::testing::Mock::VerifyAndClearExpectations(m_mockClient); // Load the shadow page. - EXPECT_CALL(*m_mockClient, createServiceWorkerNetworkProvider(::testing::_)) + EXPECT_CALL(*m_mockClient, createServiceWorkerNetworkProvider()) .WillOnce(::testing::Return(nullptr)); Platform::current()->getURLLoaderMockFactory()->serveAsynchronousRequests(); ::testing::Mock::VerifyAndClearExpectations(m_mockClient); @@ -274,7 +274,7 @@ ::testing::Mock::VerifyAndClearExpectations(m_mockClient); // Load the shadow page. - EXPECT_CALL(*m_mockClient, createServiceWorkerNetworkProvider(::testing::_)) + EXPECT_CALL(*m_mockClient, createServiceWorkerNetworkProvider()) .WillOnce(::testing::Return(nullptr)); Platform::current()->getURLLoaderMockFactory()->serveAsynchronousRequests(); ::testing::Mock::VerifyAndClearExpectations(m_mockClient);
diff --git a/third_party/WebKit/Source/web/WebSharedWorkerImpl.cpp b/third_party/WebKit/Source/web/WebSharedWorkerImpl.cpp index 1ffd05d..0a5ad09 100644 --- a/third_party/WebKit/Source/web/WebSharedWorkerImpl.cpp +++ b/third_party/WebKit/Source/web/WebSharedWorkerImpl.cpp
@@ -59,12 +59,12 @@ #include "public/platform/WebString.h" #include "public/platform/WebURL.h" #include "public/platform/WebURLRequest.h" +#include "public/platform/modules/serviceworker/WebServiceWorkerNetworkProvider.h" #include "public/web/WebDevToolsAgent.h" #include "public/web/WebFrame.h" #include "public/web/WebSettings.h" #include "public/web/WebView.h" #include "public/web/WebWorkerContentSettingsClientProxy.h" -#include "public/web/modules/serviceworker/WebServiceWorkerNetworkProvider.h" #include "web/IndexedDBClientImpl.h" #include "web/LocalFileSystemClient.h" #include "web/WebDataSourceImpl.h" @@ -170,17 +170,18 @@ void WebSharedWorkerImpl::willSendRequest(WebLocalFrame* frame, WebURLRequest& request) { - DCHECK(isMainThread()); - if (m_networkProvider) - m_networkProvider->willSendRequest(frame->dataSource(), request); + auto* networkProvider = + frame->dataSource()->getServiceWorkerNetworkProvider(); + if (networkProvider) + networkProvider->willSendRequest(request); } void WebSharedWorkerImpl::didFinishDocumentLoad(WebLocalFrame* frame) { DCHECK(isMainThread()); DCHECK(!m_loadingDocument); DCHECK(!m_mainScriptLoader); - m_networkProvider = WTF::wrapUnique( - m_client->createServiceWorkerNetworkProvider(frame->dataSource())); + frame->dataSource()->setServiceWorkerNetworkProvider( + WTF::wrapUnique(m_client->createServiceWorkerNetworkProvider())); m_mainScriptLoader = WorkerScriptLoader::create(); m_mainScriptLoader->setRequestContext( WebURLRequest::RequestContextSharedWorker); @@ -201,20 +202,6 @@ // invoked and |this| might have been deleted at this point. } -bool WebSharedWorkerImpl::isControlledByServiceWorker( - WebDataSource& dataSource) { - DCHECK(isMainThread()); - return m_networkProvider && - m_networkProvider->isControlledByServiceWorker(dataSource); -} - -int64_t WebSharedWorkerImpl::serviceWorkerID(WebDataSource& dataSource) { - DCHECK(isMainThread()); - if (!m_networkProvider) - return -1; - return m_networkProvider->serviceWorkerID(dataSource); -} - void WebSharedWorkerImpl::sendProtocolMessage(int sessionId, int callId, const WebString& message,
diff --git a/third_party/WebKit/Source/web/WebSharedWorkerImpl.h b/third_party/WebKit/Source/web/WebSharedWorkerImpl.h index 7454b51..c6b6ef1 100644 --- a/third_party/WebKit/Source/web/WebSharedWorkerImpl.h +++ b/third_party/WebKit/Source/web/WebSharedWorkerImpl.h
@@ -75,8 +75,6 @@ WebApplicationCacheHostClient*) override; void willSendRequest(WebLocalFrame*, WebURLRequest&) override; void didFinishDocumentLoad(WebLocalFrame*) override; - bool isControlledByServiceWorker(WebDataSource&) override; - int64_t serviceWorkerID(WebDataSource&) override; // WebDevToolsAgentClient overrides. void sendProtocolMessage(int sessionId,
diff --git a/third_party/WebKit/public/BUILD.gn b/third_party/WebKit/public/BUILD.gn index e84d0ea..a2cfbe0 100644 --- a/third_party/WebKit/public/BUILD.gn +++ b/third_party/WebKit/public/BUILD.gn
@@ -384,6 +384,7 @@ "platform/modules/serviceworker/WebServiceWorkerClientsInfo.h", "platform/modules/serviceworker/WebServiceWorkerError.h", "platform/modules/serviceworker/WebServiceWorkerEventResult.h", + "platform/modules/serviceworker/WebServiceWorkerNetworkProvider.h", "platform/modules/serviceworker/WebServiceWorkerProvider.h", "platform/modules/serviceworker/WebServiceWorkerProviderClient.h", "platform/modules/serviceworker/WebServiceWorkerProxy.h", @@ -572,7 +573,6 @@ "web/mac/WebSubstringUtil.h", "web/modules/serviceworker/WebServiceWorkerContextClient.h", "web/modules/serviceworker/WebServiceWorkerContextProxy.h", - "web/modules/serviceworker/WebServiceWorkerNetworkProvider.h", "web/win/WebFontRendering.h", ]
diff --git a/third_party/WebKit/public/web/modules/serviceworker/WebServiceWorkerNetworkProvider.h b/third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerNetworkProvider.h similarity index 90% rename from third_party/WebKit/public/web/modules/serviceworker/WebServiceWorkerNetworkProvider.h rename to third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerNetworkProvider.h index 7e5c111..b17563e9 100644 --- a/third_party/WebKit/public/web/modules/serviceworker/WebServiceWorkerNetworkProvider.h +++ b/third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerNetworkProvider.h
@@ -33,13 +33,15 @@ namespace blink { -class WebDataSource; class WebURLRequest; // This interface is implemented by the client and is only called on the main // thread. Used by ServiceWorker and SharedWorker. isControlledByServiceWorker() // and serviceWorkerID() are to be implemented only by SharedWorker's provider, // as they are needed only for controllee workers. +// +// An instance of this class is owned by the associated loading context, e.g. +// DocumentLoader. class WebServiceWorkerNetworkProvider { public: virtual ~WebServiceWorkerNetworkProvider() {} @@ -47,15 +49,15 @@ // A request is about to be sent out, and the client may modify it. Request // is writable, and changes to the URL, for example, will change the request // made. - virtual void willSendRequest(WebDataSource*, WebURLRequest&) {} + virtual void willSendRequest(WebURLRequest&) {} // Whether the document associated with WebDataSource is controlled by the // ServiceWorker. - virtual bool isControlledByServiceWorker(WebDataSource&) { return false; } + virtual bool isControlledByServiceWorker() { return false; } // Returns an identifier of the service worker controlling the document // associated with the WebDataSource. - virtual int64_t serviceWorkerID(WebDataSource&) { return -1; } + virtual int64_t serviceWorkerID() { return -1; } }; } // namespace blink
diff --git a/third_party/WebKit/public/web/WebDataSource.h b/third_party/WebKit/public/web/WebDataSource.h index c2b118a..a084487 100644 --- a/third_party/WebKit/public/web/WebDataSource.h +++ b/third_party/WebKit/public/web/WebDataSource.h
@@ -31,6 +31,8 @@ #ifndef WebDataSource_h #define WebDataSource_h +#include <memory> + #include "../platform/WebCommon.h" #include "WebNavigationType.h" #include "WebTextDirection.h" @@ -38,6 +40,7 @@ namespace blink { class WebDocumentSubresourceFilter; +class WebServiceWorkerNetworkProvider; class WebURL; class WebURLRequest; class WebURLResponse; @@ -120,6 +123,14 @@ // datasource is destroyed or when a new filter is set. virtual void setSubresourceFilter(WebDocumentSubresourceFilter*) = 0; + // Allows the embedder to set and return the service worker provider + // associated with the data source. The provider may provide the service + // worker that controls the resource loading from this data source. + virtual void setServiceWorkerNetworkProvider( + std::unique_ptr<WebServiceWorkerNetworkProvider>) = 0; + virtual WebServiceWorkerNetworkProvider* + getServiceWorkerNetworkProvider() = 0; + protected: ~WebDataSource() {} };
diff --git a/third_party/WebKit/public/web/WebFrameClient.h b/third_party/WebKit/public/web/WebFrameClient.h index 5bf558bd..539f8ef 100644 --- a/third_party/WebKit/public/web/WebFrameClient.h +++ b/third_party/WebKit/public/web/WebFrameClient.h
@@ -679,16 +679,6 @@ const WebAXObject& endObject, int endOffset) {} - // ServiceWorker ------------------------------------------------------- - - // Whether the document associated with WebDataSource is controlled by the - // ServiceWorker. - virtual bool isControlledByServiceWorker(WebDataSource&) { return false; } - - // Returns an identifier of the service worker controlling the document - // associated with the WebDataSource. - virtual int64_t serviceWorkerID(WebDataSource&) { return -1; } - // Fullscreen ---------------------------------------------------------- // Called to enter/exit fullscreen mode.
diff --git a/third_party/WebKit/public/web/WebSharedWorkerClient.h b/third_party/WebKit/public/web/WebSharedWorkerClient.h index e75a34c5..0525e891c 100644 --- a/third_party/WebKit/public/web/WebSharedWorkerClient.h +++ b/third_party/WebKit/public/web/WebSharedWorkerClient.h
@@ -38,7 +38,6 @@ class WebApplicationCacheHost; class WebApplicationCacheHostClient; -class WebDataSource; class WebNotificationPresenter; class WebSecurityOrigin; class WebServiceWorkerNetworkProvider; @@ -81,8 +80,8 @@ // Called on the main thread during initialization. // Ownership of the returned object is transferred to the caller. - virtual WebServiceWorkerNetworkProvider* createServiceWorkerNetworkProvider( - WebDataSource*) { + virtual WebServiceWorkerNetworkProvider* + createServiceWorkerNetworkProvider() { return nullptr; }
diff --git a/third_party/WebKit/public/web/modules/serviceworker/WebServiceWorkerContextClient.h b/third_party/WebKit/public/web/modules/serviceworker/WebServiceWorkerContextClient.h index 4d1105a..c272ec9b 100644 --- a/third_party/WebKit/public/web/modules/serviceworker/WebServiceWorkerContextClient.h +++ b/third_party/WebKit/public/web/modules/serviceworker/WebServiceWorkerContextClient.h
@@ -45,7 +45,6 @@ namespace blink { struct WebServiceWorkerClientQueryOptions; -class WebDataSource; class WebServiceWorkerContextProxy; class WebServiceWorkerNetworkProvider; class WebServiceWorkerProvider; @@ -203,8 +202,8 @@ // Ownership of the returned object is transferred to the caller. // This is called on the main thread. - virtual WebServiceWorkerNetworkProvider* createServiceWorkerNetworkProvider( - WebDataSource*) { + virtual WebServiceWorkerNetworkProvider* + createServiceWorkerNetworkProvider() { return nullptr; }
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index 8c7f49e..a4e22d5a 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -57428,7 +57428,15 @@ </summary> </histogram> -<histogram name="SafeBrowsing.Pref.Scout" enum="BooleanEnabled"> +<histogram name="SafeBrowsing.Pref.SawInterstitial" enum="Boolean"> + <owner>lpz@chromium.org</owner> + <summary> + Whether the current user has ever seen a security interstitial. Recorded for + all non-Incognito profiles on profile startup. + </summary> +</histogram> + +<histogram name="SafeBrowsing.Pref.Scout" enum="NullableBoolean"> <owner>lpz@chromium.org</owner> <summary> Tracks the Extended Reporting preference transition. Suffixes track which @@ -102883,6 +102891,15 @@ <int value="0" label="0x00000000 - STATUS_SUCCESS"/> </enum> +<enum name="NullableBoolean" type="int"> + <summary> + A Nullable Boolean can True, False or Null (ie: unset or absent). + </summary> + <int value="0" label="False"/> + <int value="1" label="True"/> + <int value="2" label="Null"/> +</enum> + <enum name="OAuth2LoginAccountRevokedMigrationState" type="int"> <int value="0" label="Account ID migration not started"/> <int value="1" label="Account ID migration in progress"/> @@ -121290,6 +121307,7 @@ <histogram_suffixes name="SafeBrowsingScoutPrefValues" separator="."> <suffix name="SBER1Pref" label="Value of the legacy Extended Reporting pref"/> <suffix name="SBER2Pref" label="Value of the new Extended Reporting pref"/> + <affected-histogram name="SafeBrowsing.Pref.SawInterstitial"/> <affected-histogram name="SafeBrowsing.Pref.Scout.NoScoutGroup"/> <affected-histogram name="SafeBrowsing.Pref.Scout.ScoutGroup"/> <affected-histogram name="SafeBrowsing.Pref.Scout.SetPref"/>
diff --git a/tools/perf/benchmarks/v8_browsing.py b/tools/perf/benchmarks/v8_browsing.py index 72a0d76..977f473 100644 --- a/tools/perf/benchmarks/v8_browsing.py +++ b/tools/perf/benchmarks/v8_browsing.py
@@ -167,6 +167,7 @@ TEST_SUFFIX = '' +@benchmark.Disabled('reference') # http://crbug.com/700390 class V8DesktopTurboBrowsingBenchmark(_V8DesktopBrowsingBenchmark): PLATFORM = 'desktop' TEST_SUFFIX = '_turbo' @@ -197,6 +198,7 @@ return possible_browser.platform.GetDeviceTypeName() != 'Desktop' +@benchmark.Disabled('reference') # http://crbug.com/700390 class V8RuntimeStatsDesktopTurboBrowsingBenchmark( _V8RuntimeStatsBrowsingBenchmark): PLATFORM = 'desktop'
diff --git a/ui/android/java/src/org/chromium/ui/base/ViewAndroidDelegate.java b/ui/android/java/src/org/chromium/ui/base/ViewAndroidDelegate.java index 8e3dedac..bf674594 100644 --- a/ui/android/java/src/org/chromium/ui/base/ViewAndroidDelegate.java +++ b/ui/android/java/src/org/chromium/ui/base/ViewAndroidDelegate.java
@@ -4,7 +4,6 @@ package org.chromium.ui.base; -import android.annotation.TargetApi; import android.content.ClipData; import android.content.Intent; import android.graphics.Bitmap; @@ -27,6 +26,10 @@ @JNINamespace("ui") public abstract class ViewAndroidDelegate { private static final String TAG = "ViewAndroidDelegate"; + + // TODO(hush): use View#DRAG_FLAG_GLOBAL when Chromium starts to build with API 24. + private static final int DRAG_FLAG_GLOBAL = 1 << 8; + private static final String GEO_SCHEME = "geo"; private static final String TEL_SCHEME = "tel"; private static final String MAILTO_SCHEME = "mailto"; @@ -92,7 +95,8 @@ * @param shadowImage The shadow image for the dragged text. */ @SuppressWarnings("deprecation") - @TargetApi(Build.VERSION_CODES.N) + // TODO(hush): uncomment below when we build with API 24. + // @TargetApi(Build.VERSION_CODES.N) @CalledByNative private boolean startDragAndDrop(String text, Bitmap shadowImage) { if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.M) return false; @@ -104,8 +108,9 @@ imageView.setImageBitmap(shadowImage); imageView.layout(0, 0, shadowImage.getWidth(), shadowImage.getHeight()); - return containerView.startDragAndDrop(ClipData.newPlainText(null, text), - new View.DragShadowBuilder(imageView), null, View.DRAG_FLAG_GLOBAL); + // TODO(hush): use View#startDragAndDrop when Chromium starts to build with API 24. + return containerView.startDrag(ClipData.newPlainText(null, text), + new View.DragShadowBuilder(imageView), null, DRAG_FLAG_GLOBAL); } /**
diff --git a/ui/events/platform/x11/x11_event_source.cc b/ui/events/platform/x11/x11_event_source.cc index 9fbfe0d..f8bbaeb 100644 --- a/ui/events/platform/x11/x11_event_source.cc +++ b/ui/events/platform/x11/x11_event_source.cc
@@ -149,10 +149,6 @@ BlockOnWindowStructureEvent(window, MapNotify); } -void X11EventSource::BlockUntilWindowUnmapped(XID window) { - BlockOnWindowStructureEvent(window, UnmapNotify); -} - Time X11EventSource::GetCurrentServerTime() { DCHECK(display_);
diff --git a/ui/events/platform/x11/x11_event_source.h b/ui/events/platform/x11/x11_event_source.h index 7b1c37d..c274490 100644 --- a/ui/events/platform/x11/x11_event_source.h +++ b/ui/events/platform/x11/x11_event_source.h
@@ -73,8 +73,6 @@ // functions which require a mapped window. void BlockUntilWindowMapped(XID window); - void BlockUntilWindowUnmapped(XID window); - XDisplay* display() { return display_; } // Returns the timestamp of the event currently being dispatched. Falls back
diff --git a/ui/views/bubble/bubble_dialog_delegate.cc b/ui/views/bubble/bubble_dialog_delegate.cc index 735a2237..c32f4c3 100644 --- a/ui/views/bubble/bubble_dialog_delegate.cc +++ b/ui/views/bubble/bubble_dialog_delegate.cc
@@ -216,12 +216,9 @@ adjust_if_offscreen_(true), parent_window_(NULL) { ViewsDelegate* views_delegate = ViewsDelegate::GetInstance(); - margins_ = views_delegate ? views_delegate->GetBubbleDialogMargins() - : gfx::Insets(kPanelVertMargin, kPanelHorizMargin); - title_margins_ = views_delegate - ? views_delegate->GetDialogFrameViewInsets() - : gfx::Insets(kPanelVertMargin, kPanelHorizMargin, 0, - kPanelHorizMargin); + margins_ = views_delegate->GetInsetsMetric(InsetsMetric::BUBBLE_DIALOG); + title_margins_ = + views_delegate->GetInsetsMetric(InsetsMetric::DIALOG_FRAME_VIEW); if (anchor_view) SetAnchorView(anchor_view); UpdateColorsFromTheme(GetNativeTheme());
diff --git a/ui/views/bubble/bubble_frame_view.cc b/ui/views/bubble/bubble_frame_view.cc index 14f5622..a8220bc 100644 --- a/ui/views/bubble/bubble_frame_view.cc +++ b/ui/views/bubble/bubble_frame_view.cc
@@ -314,8 +314,8 @@ return; // The close button is positioned somewhat closer to the edge of the bubble. - const int close_margin = - ViewsDelegate::GetInstance()->GetDialogCloseButtonMargin(); + const int close_margin = ViewsDelegate::GetInstance()->GetDistanceMetric( + DistanceMetric::CLOSE_BUTTON_MARGIN); close_->SetPosition( gfx::Point(contents_bounds.right() - close_margin - close_->width(), contents_bounds.y() + close_margin));
diff --git a/ui/views/controls/button/label_button.cc b/ui/views/controls/button/label_button.cc index 4a7cfd9..028c4710 100644 --- a/ui/views/controls/button/label_button.cc +++ b/ui/views/controls/button/label_button.cc
@@ -25,15 +25,14 @@ #include "ui/views/animation/square_ink_drop_ripple.h" #include "ui/views/background.h" #include "ui/views/controls/button/label_button_border.h" +#include "ui/views/layout/layout_constants.h" #include "ui/views/painter.h" #include "ui/views/style/platform_style.h" +#include "ui/views/views_delegate.h" #include "ui/views/window/dialog_delegate.h" namespace { -// The default spacing between the icon and text. -const int kSpacing = 5; - gfx::Font::Weight GetValueBolderThan(gfx::Font::Weight weight) { if (weight < gfx::Font::Weight::BOLD) return gfx::Font::Weight::BOLD; @@ -93,7 +92,8 @@ is_default_(false), style_(STYLE_TEXTBUTTON), border_is_themed_border_(true), - image_label_spacing_(kSpacing), + image_label_spacing_(ViewsDelegate::GetInstance()->GetDistanceMetric( + DistanceMetric::RELATED_CONTROL_HORIZONTAL)), horizontal_alignment_(gfx::ALIGN_LEFT) { SetAnimationDuration(kHoverAnimationDurationMs); SetTextInternal(text);
diff --git a/ui/views/controls/button/md_text_button.cc b/ui/views/controls/button/md_text_button.cc index b5e6c1b..4453f2a 100644 --- a/ui/views/controls/button/md_text_button.cc +++ b/ui/views/controls/button/md_text_button.cc
@@ -193,8 +193,8 @@ set_has_ink_drop_action_on_click(true); SetHorizontalAlignment(gfx::ALIGN_CENTER); SetFocusForPlatform(); - const int minimum_width = - ViewsDelegate::GetInstance()->GetButtonMinimumWidth(); + const int minimum_width = ViewsDelegate::GetInstance()->GetDistanceMetric( + DistanceMetric::DIALOG_BUTTON_MINIMUM_WIDTH); SetMinSize(gfx::Size(minimum_width, 0)); SetFocusPainter(nullptr); label()->SetAutoColorReadabilityEnabled(false); @@ -241,7 +241,8 @@ // TODO(estade): can we get rid of the platform style border hoopla if // we apply the MD treatment to all buttons, even GTK buttons? const int horizontal_padding = - ViewsDelegate::GetInstance()->GetButtonHorizontalPadding(); + ViewsDelegate::GetInstance()->GetDistanceMetric( + DistanceMetric::BUTTON_HORIZONTAL_PADDING); SetBorder(CreateEmptyBorder(top_padding, horizontal_padding, bottom_padding, horizontal_padding)); }
diff --git a/ui/views/controls/combobox/combobox.cc b/ui/views/controls/combobox/combobox.cc index cadbfa4..24c5170 100644 --- a/ui/views/controls/combobox/combobox.cc +++ b/ui/views/controls/combobox/combobox.cc
@@ -131,8 +131,11 @@ ~TransparentButton() override {} bool OnMousePressed(const ui::MouseEvent& mouse_event) override { - if (!UseMd()) - parent()->RequestFocus(); +#if !defined(OS_MACOSX) + // On Mac, comboboxes do not take focus on mouse click, but on other + // platforms they do. + parent()->RequestFocus(); +#endif return CustomButton::OnMousePressed(mouse_event); }
diff --git a/ui/views/examples/dialog_example.cc b/ui/views/examples/dialog_example.cc index 37e8770..56be1b8 100644 --- a/ui/views/examples/dialog_example.cc +++ b/ui/views/examples/dialog_example.cc
@@ -132,7 +132,8 @@ const float kStretchy = 1.f; const int horizontal_spacing = - ViewsDelegate::GetInstance()->GetDialogRelatedButtonHorizontalSpacing(); + ViewsDelegate::GetInstance()->GetDistanceMetric( + views::DistanceMetric::RELATED_BUTTON_HORIZONTAL); GridLayout* layout = GridLayout::CreatePanel(container); container->SetLayoutManager(layout); ColumnSet* column_set = layout->AddColumnSet(kFieldsColumnId); @@ -187,7 +188,8 @@ const float kFixedVerticalResize = 0.f; layout->StartRowWithPadding( kFixedVerticalResize, kFieldsColumnId, kFixedVerticalResize, - ViewsDelegate::GetInstance()->GetDialogRelatedControlVerticalSpacing()); + ViewsDelegate::GetInstance()->GetDistanceMetric( + views::DistanceMetric::RELATED_CONTROL_VERTICAL)); layout->AddView(new Label(base::ASCIIToUTF16(label))); }
diff --git a/ui/views/layout/layout_constants.h b/ui/views/layout/layout_constants.h index 620a28d..9813351 100644 --- a/ui/views/layout/layout_constants.h +++ b/ui/views/layout/layout_constants.h
@@ -71,7 +71,7 @@ constexpr int kButtonHEdgeMarginNew = 20; // Spacing between the edge of the window and the edge of the close button. -const int kCloseButtonMargin = 7; +constexpr int kCloseButtonMargin = 7; // Horizontal spacing between buttons that are logically related. constexpr int kRelatedButtonHSpacing = 6; @@ -90,7 +90,7 @@ const int kMinimumButtonWidth = 48; // Minimum width of dialog buttons. -const int kDialogMinimumButtonWidth = 75; +constexpr int kDialogMinimumButtonWidth = 75; } // namespace views
diff --git a/ui/views/views_delegate.cc b/ui/views/views_delegate.cc index 8a78a96..a14cf488 100644 --- a/ui/views/views_delegate.cc +++ b/ui/views/views_delegate.cc
@@ -126,42 +126,38 @@ return nullptr; } -gfx::Insets ViewsDelegate::GetDialogButtonInsets() const { - return gfx::Insets(0, kButtonHEdgeMarginNew, kButtonVEdgeMarginNew, - kButtonHEdgeMarginNew); +gfx::Insets ViewsDelegate::GetInsetsMetric(InsetsMetric metric) const { + switch (metric) { + case InsetsMetric::DIALOG_BUTTON: + return gfx::Insets(0, kButtonHEdgeMarginNew, kButtonVEdgeMarginNew, + kButtonHEdgeMarginNew); + case InsetsMetric::DIALOG_FRAME_VIEW: + return gfx::Insets(kPanelVertMargin, kButtonHEdgeMarginNew, 0, + kButtonHEdgeMarginNew); + case InsetsMetric::BUBBLE_DIALOG: + return gfx::Insets(kPanelVertMargin, kPanelHorizMargin); + } + NOTREACHED(); + return gfx::Insets(); } -int ViewsDelegate::GetDialogCloseButtonMargin() const { - return kCloseButtonMargin; -} - -int ViewsDelegate::GetDialogRelatedButtonHorizontalSpacing() const { - return kRelatedButtonHSpacing; -} - -int ViewsDelegate::GetDialogRelatedControlVerticalSpacing() const { - return kRelatedControlVerticalSpacing; -} - -gfx::Insets ViewsDelegate::GetDialogFrameViewInsets() const { - return gfx::Insets(kPanelVertMargin, kButtonHEdgeMarginNew, 0, - kButtonHEdgeMarginNew); -} - -gfx::Insets ViewsDelegate::GetBubbleDialogMargins() const { - return gfx::Insets(kPanelVertMargin, kPanelHorizMargin); -} - -int ViewsDelegate::GetButtonMinimumWidth() const { - return kMinimumButtonWidth; -} - -int ViewsDelegate::GetDialogButtonMinimumWidth() const { - return kDialogMinimumButtonWidth; -} - -int ViewsDelegate::GetButtonHorizontalPadding() const { - return kButtonHorizontalPadding; +int ViewsDelegate::GetDistanceMetric(DistanceMetric metric) const { + switch (metric) { + case DistanceMetric::CLOSE_BUTTON_MARGIN: + return kCloseButtonMargin; + case DistanceMetric::RELATED_BUTTON_HORIZONTAL: + return kRelatedButtonHSpacing; + case DistanceMetric::RELATED_CONTROL_HORIZONTAL: + return kRelatedControlHorizontalSpacing; + case DistanceMetric::RELATED_CONTROL_VERTICAL: + return kRelatedControlVerticalSpacing; + case DistanceMetric::DIALOG_BUTTON_MINIMUM_WIDTH: + return kDialogMinimumButtonWidth; + case DistanceMetric::BUTTON_HORIZONTAL_PADDING: + return kButtonHorizontalPadding; + } + NOTREACHED(); + return 0; } ViewsDelegate::ViewsDelegate()
diff --git a/ui/views/views_delegate.h b/ui/views/views_delegate.h index 7b3960f..6a784af5 100644 --- a/ui/views/views_delegate.h +++ b/ui/views/views_delegate.h
@@ -58,6 +58,35 @@ class NativeWidgetDelegate; } +enum class InsetsMetric { + // The margins that should be applied around a bubble dialog. + BUBBLE_DIALOG, + // The insets that should be applied around a DialogClientView. Note that + // the top inset is used for the distance between the buttons and the + // DialogClientView's content view. + DIALOG_BUTTON, + // The insets that should be applied around a dialog's frame view. + DIALOG_FRAME_VIEW, +}; + +enum class DistanceMetric { + // The default padding to add on each side of a button's label. + BUTTON_HORIZONTAL_PADDING, + // The distance between a dialog's edge and the close button in the upper + // trailing corner. + CLOSE_BUTTON_MARGIN, + // The default minimum width of a dialog button. + DIALOG_BUTTON_MINIMUM_WIDTH, + // The spacing between a pair of related horizontal buttons, used for + // dialog layout. + RELATED_BUTTON_HORIZONTAL, + // Horizontal spacing between controls that are logically related. + RELATED_CONTROL_HORIZONTAL, + // The spacing between a pair of related vertical controls, used for + // dialog layout. + RELATED_CONTROL_VERTICAL, +}; + // ViewsDelegate is an interface implemented by an object using the views // framework. It is used to obtain various high level application utilities // and perform some actions such as window placement saving. @@ -196,37 +225,12 @@ // Returns a blocking pool task runner given a TaskRunnerType. virtual scoped_refptr<base::TaskRunner> GetBlockingPoolTaskRunner(); - // Returns the insets that should be applied around a DialogClientView. Note - // that the top inset is used for the distance between the buttons and the - // DialogClientView's content view. - virtual gfx::Insets GetDialogButtonInsets() const; + // Returns the insets metric according to the given enumeration element. + virtual gfx::Insets GetInsetsMetric(InsetsMetric metric) const; - // Returns the distance between a dialog's edge and the close button in the - // upper trailing corner. - virtual int GetDialogCloseButtonMargin() const; - - // Returns the spacing between a pair of related horizontal buttons, used for - // dialog layout. - virtual int GetDialogRelatedButtonHorizontalSpacing() const; - - // Returns the spacing between a pair of related vertical controls, used for - // dialog layout. - virtual int GetDialogRelatedControlVerticalSpacing() const; - - // Returns the insets that should be applied around a dialog's frame view. - virtual gfx::Insets GetDialogFrameViewInsets() const; - - // Returns the margins that should be applied around a bubble dialog. - virtual gfx::Insets GetBubbleDialogMargins() const; - - // Returns the default minimum width of a button. - virtual int GetButtonMinimumWidth() const; - - // Returns the minimum width of a dialog button. - virtual int GetDialogButtonMinimumWidth() const; - - // Returns the default padding to add on each side of a button's label. - virtual int GetButtonHorizontalPadding() const; + // Returns the distance metric between elements according to the given + // enumeration element. + virtual int GetDistanceMetric(DistanceMetric metric) const; protected: ViewsDelegate();
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc b/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc index 448baf89..c64b0ca 100644 --- a/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc +++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc
@@ -187,8 +187,8 @@ xwindow_(0), x_root_window_(DefaultRootWindow(xdisplay_)), atom_cache_(xdisplay_, kAtomsToCache), - window_mapped_(false), - wait_for_unmap_(false), + window_mapped_in_server_(false), + window_mapped_in_client_(false), is_fullscreen_(false), is_always_on_top_(false), use_native_frame_(false), @@ -593,7 +593,7 @@ } bool DesktopWindowTreeHostX11::IsVisible() const { - return window_mapped_ && !wait_for_unmap_; + return window_mapped_in_client_; } void DesktopWindowTreeHostX11::SetSize(const gfx::Size& requested_size) { @@ -831,9 +831,9 @@ bool is_active = (has_window_focus_ || has_pointer_focus_) && !ignore_keyboard_input_; - // is_active => window_mapped_ - // !window_mapped_ => !is_active - DCHECK(!is_active || window_mapped_); + // is_active => window_mapped_in_server_ + // !window_mapped_in_server_ => !is_active + DCHECK(!is_active || window_mapped_in_server_); // |has_window_focus_| and |has_pointer_focus_| are mutually exclusive. DCHECK(!has_window_focus_ || !has_pointer_focus_); @@ -1224,7 +1224,7 @@ void DesktopWindowTreeHostX11::HideImpl() { if (IsVisible()) { XWithdrawWindow(xdisplay_, xwindow_, 0); - wait_for_unmap_ = true; + window_mapped_in_client_ = false; } native_widget_delegate_->OnNativeWidgetVisibilityChanged(false); } @@ -1242,9 +1242,12 @@ XWindowChanges changes = {0}; unsigned value_mask = 0; - delayed_resize_task_.Cancel(); if (size_changed) { + // Only cancel the delayed resize task if we're already about to call + // OnHostResized in this function. + delayed_resize_task_.Cancel(); + // Update the minimum and maximum sizes in case they have changed. UpdateMinAndMaxSize(); @@ -1664,9 +1667,6 @@ } void DesktopWindowTreeHostX11::UpdateMinAndMaxSize() { - if (!IsVisible()) - return; - gfx::Size minimum_in_pixels = ToPixelRect(gfx::Rect(native_widget_delegate_->GetMinimumSize())).size(); gfx::Size maximum_in_pixels = @@ -1937,19 +1937,10 @@ ui::X11EventSource* event_source = ui::X11EventSource::GetInstance(); DCHECK(event_source); - if (wait_for_unmap_) { - // Block until our window is unmapped. This avoids a race condition when - // remapping an unmapped window. - event_source->BlockUntilWindowUnmapped(xwindow_); - DCHECK(!wait_for_unmap_); - } + UpdateMinAndMaxSize(); XMapWindow(xdisplay_, xwindow_); - - // We now block until our window is mapped. Some X11 APIs will crash and - // burn if passed |xwindow_| before the window is mapped, and XMapWindow is - // asynchronous. - event_source->BlockUntilWindowMapped(xwindow_); + window_mapped_in_client_ = true; } void DesktopWindowTreeHostX11::SetWindowTransparency() { @@ -2172,13 +2163,11 @@ break; } case MapNotify: { - window_mapped_ = true; + window_mapped_in_server_ = true; for (DesktopWindowTreeHostObserverX11& observer : observer_list_) observer.OnWindowMapped(xwindow_); - UpdateMinAndMaxSize(); - // Some WMs only respect maximize hints after the window has been mapped. // Check whether we need to re-do a maximization. if (should_maximize_after_map_) { @@ -2189,8 +2178,7 @@ break; } case UnmapNotify: { - window_mapped_ = false; - wait_for_unmap_ = false; + window_mapped_in_server_ = false; has_pointer_ = false; has_pointer_grab_ = false; has_pointer_focus_ = false;
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h b/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h index 544f086..757b780 100644 --- a/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h +++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h
@@ -291,13 +291,11 @@ ui::X11AtomCache atom_cache_; - // Is the window mapped to the screen? - bool window_mapped_; + // Whether the window is mapped with respect to the X server. + bool window_mapped_in_server_; - // Should we wait for an UnmapNotify before trying to remap the window? - // If |wait_for_unmap_| is true, we have sent an XUnmapWindow request to the - // server and have yet to receive an UnmapNotify. - bool wait_for_unmap_; + // Whether the window is visible with respect to Aura. + bool window_mapped_in_client_; // The bounds of |xwindow_|. gfx::Rect bounds_in_pixels_;
diff --git a/ui/views/window/dialog_client_view.cc b/ui/views/window/dialog_client_view.cc index fcf37d9f..5d543a7 100644 --- a/ui/views/window/dialog_client_view.cc +++ b/ui/views/window/dialog_client_view.cc
@@ -75,8 +75,8 @@ DialogClientView::DialogClientView(Widget* owner, View* contents_view) : ClientView(owner, contents_view), - button_row_insets_( - ViewsDelegate::GetInstance()->GetDialogButtonInsets()) { + button_row_insets_(ViewsDelegate::GetInstance()->GetInsetsMetric( + InsetsMetric::DIALOG_BUTTON)) { // Doing this now ensures this accelerator will have lower priority than // one set by the contents view. AddAccelerator(ui::Accelerator(ui::VKEY_ESCAPE, ui::EF_NONE)); @@ -281,8 +281,8 @@ button = MdTextButton::CreateSecondaryUiButton(this, title); } - const int minimum_width = - ViewsDelegate::GetInstance()->GetDialogButtonMinimumWidth(); + const int minimum_width = ViewsDelegate::GetInstance()->GetDistanceMetric( + views::DistanceMetric::DIALOG_BUTTON_MINIMUM_WIDTH); button->SetMinSize(gfx::Size(minimum_width, 0)); button->SetGroup(kButtonGroup); @@ -301,8 +301,8 @@ if (GetDialogDelegate()->GetExtraViewPadding(&extra_view_padding)) return extra_view_padding; - return ViewsDelegate::GetInstance() - ->GetDialogRelatedButtonHorizontalSpacing(); + return ViewsDelegate::GetInstance()->GetDistanceMetric( + views::DistanceMetric::RELATED_BUTTON_HORIZONTAL); } std::array<View*, DialogClientView::kNumButtons> @@ -341,8 +341,8 @@ // They expect GetDialogRelatedControlVerticalSpacing() in this case. // TODO(tapted): Remove this under Harmony. if (insets.top() == 0) { - const int top = - ViewsDelegate::GetInstance()->GetDialogRelatedControlVerticalSpacing(); + const int top = ViewsDelegate::GetInstance()->GetDistanceMetric( + views::DistanceMetric::RELATED_CONTROL_VERTICAL); insets.Set(top, insets.left(), insets.bottom(), insets.right()); } @@ -356,8 +356,8 @@ // GetExtraViewSpacing() handles <pad+stretchy>. const int button_spacing = (ok_button_ && cancel_button_) - ? ViewsDelegate::GetInstance() - ->GetDialogRelatedButtonHorizontalSpacing() + ? ViewsDelegate::GetInstance()->GetDistanceMetric( + views::DistanceMetric::RELATED_BUTTON_HORIZONTAL) : 0; constexpr int kButtonRowId = 0;
diff --git a/ui/views/window/dialog_delegate.cc b/ui/views/window/dialog_delegate.cc index 333adf9..9122b10 100644 --- a/ui/views/window/dialog_delegate.cc +++ b/ui/views/window/dialog_delegate.cc
@@ -200,9 +200,10 @@ NonClientFrameView* DialogDelegate::CreateDialogFrameView( Widget* widget, const gfx::Insets& content_margins) { - BubbleFrameView* frame = new BubbleFrameView( - ViewsDelegate::GetInstance()->GetDialogFrameViewInsets(), - content_margins); + BubbleFrameView* frame = + new BubbleFrameView(ViewsDelegate::GetInstance()->GetInsetsMetric( + InsetsMetric::DIALOG_FRAME_VIEW), + content_margins); const BubbleBorder::Shadow kShadow = BubbleBorder::SMALL_SHADOW; std::unique_ptr<BubbleBorder> border( new BubbleBorder(BubbleBorder::FLOAT, kShadow, gfx::kPlaceholderColor));