diff --git a/AUTHORS b/AUTHORS index faf4eca..5d90a2d 100644 --- a/AUTHORS +++ b/AUTHORS
@@ -315,6 +315,7 @@ Ian Cullinan <cullinan@amazon.com> Ian Scott <ian.scott@arteris.com> Ibrar Ahmed <ibrar.ahmad@gmail.com> +Ilia Demianenko <ilia.demianenko@gmail.com> Ilia K <ki.stfu@gmail.com> Ilya Konstantinov <ilya.konstantinov@gmail.com> Ion Rosca <rosca@adobe.com>
diff --git a/DEPS b/DEPS index 37460fe..e2f7355 100644 --- a/DEPS +++ b/DEPS
@@ -98,7 +98,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling PDFium # and whatever else without interference from each other. - 'pdfium_revision': '752e9bf892abdf1ee588ba87c857d0783a017b27', + 'pdfium_revision': 'b8d86800487df4021860f08407c323ed82243c79', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling openmax_dl # and whatever else without interference from each other. @@ -130,7 +130,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': '43a5c4971235ed78db5c8e2df5eb5c2e0dbff2d6', + 'catapult_revision': 'c8947ecc4964bf055ddab8598981f7c83c546f7d', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other. @@ -203,7 +203,7 @@ }, 'src/ios/third_party/material_internationalization_ios/src': { - 'url': Var('chromium_git') + '/external/github.com/material-foundation/material-internationalization-ios.git' + '@' + '5b0f22e4715305ddc3a8810f5939be3f07cb7e3e', + 'url': Var('chromium_git') + '/external/github.com/material-foundation/material-internationalization-ios.git' + '@' + 'fa05ea39c50b232917232c0d6e8b5a34caf7f43f', 'condition': 'checkout_ios', },
diff --git a/ash/BUILD.gn b/ash/BUILD.gn index 137f1e2..939c7d1 100644 --- a/ash/BUILD.gn +++ b/ash/BUILD.gn
@@ -21,15 +21,8 @@ sources = [ "accelerators/accelerator_commands.cc", "accelerators/accelerator_commands.h", - "accelerators/accelerator_commands_classic.cc", - "accelerators/accelerator_commands_classic.h", "accelerators/accelerator_controller.cc", "accelerators/accelerator_controller.h", - "accelerators/accelerator_controller_delegate.h", - "accelerators/accelerator_controller_delegate_classic.cc", - "accelerators/accelerator_controller_delegate_classic.h", - "accelerators/accelerator_controller_delegate_mash.cc", - "accelerators/accelerator_controller_delegate_mash.h", "accelerators/accelerator_controller_registrar.cc", "accelerators/accelerator_controller_registrar.h", "accelerators/accelerator_delegate.cc",
diff --git a/ash/accelerators/accelerator_commands.cc b/ash/accelerators/accelerator_commands.cc index b4096c6..b8f3e8d 100644 --- a/ash/accelerators/accelerator_commands.cc +++ b/ash/accelerators/accelerator_commands.cc
@@ -6,6 +6,7 @@ #include "ash/shell.h" #include "ash/wm/mru_window_tracker.h" +#include "ash/wm/screen_pinning_controller.h" #include "ash/wm/window_state.h" #include "ash/wm/window_util.h" #include "ash/wm/wm_event.h" @@ -73,5 +74,20 @@ wm::GetWindowState(active_window)->OnWMEvent(&event); } +bool CanUnpinWindow() { + // WindowStateType::TRUSTED_PINNED does not allow the user to press a key to + // exit pinned mode. + wm::WindowState* window_state = wm::GetActiveWindowState(); + return window_state && + window_state->GetStateType() == mojom::WindowStateType::PINNED; +} + +void UnpinWindow() { + aura::Window* pinned_window = + Shell::Get()->screen_pinning_controller()->pinned_window(); + if (pinned_window) + wm::GetWindowState(pinned_window)->Restore(); +} + } // namespace accelerators } // namespace ash
diff --git a/ash/accelerators/accelerator_commands.h b/ash/accelerators/accelerator_commands.h index 255d0c2..f33a314f 100644 --- a/ash/accelerators/accelerator_commands.h +++ b/ash/accelerators/accelerator_commands.h
@@ -34,6 +34,13 @@ // by WindowStateDelegate::ToggleFullscreen(). ASH_EXPORT void ToggleFullscreen(); +// True if the user can press a key to exit pinned mode (aka forced +// fullscreen). +ASH_EXPORT bool CanUnpinWindow(); + +// If a window is pinned (aka forced fullscreen), exit from pinned mode. +ASH_EXPORT void UnpinWindow(); + } // namespace accelerators } // namespace ash
diff --git a/ash/accelerators/accelerator_commands_classic.cc b/ash/accelerators/accelerator_commands_classic.cc deleted file mode 100644 index 3d3b2b3..0000000 --- a/ash/accelerators/accelerator_commands_classic.cc +++ /dev/null
@@ -1,22 +0,0 @@ -// Copyright 2013 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 "ash/accelerators/accelerator_commands_classic.h" - -#include "ash/shell.h" -#include "ash/wm/screen_pinning_controller.h" -#include "ash/wm/window_state.h" - -namespace ash { -namespace accelerators { - -void Unpin() { - aura::Window* pinned_window = - Shell::Get()->screen_pinning_controller()->pinned_window(); - if (pinned_window) - wm::GetWindowState(pinned_window)->Restore(); -} - -} // namespace accelerators -} // namespace ash
diff --git a/ash/accelerators/accelerator_commands_classic.h b/ash/accelerators/accelerator_commands_classic.h deleted file mode 100644 index 99460b3..0000000 --- a/ash/accelerators/accelerator_commands_classic.h +++ /dev/null
@@ -1,22 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef ASH_ACCELERATORS_ACCELERATOR_COMMANDS_CLASSIC_H_ -#define ASH_ACCELERATORS_ACCELERATOR_COMMANDS_CLASSIC_H_ - -#include "ash/ash_export.h" - -// This file contains implementations of commands that are bound to keyboard -// shortcuts in Ash or in the embedding application (e.g. Chrome). -// TODO(jamescook): Combine classic ash and mash command files. -namespace ash { -namespace accelerators { - -// If a window is pinned (aka forced fullscreen), exit from pinned mode. -ASH_EXPORT void Unpin(); - -} // namespace accelerators -} // namespace ash - -#endif // ASH_ACCELERATORS_ACCELERATOR_COMMANDS_CLASSIC_H_
diff --git a/ash/accelerators/accelerator_commands_unittest.cc b/ash/accelerators/accelerator_commands_unittest.cc index 19ba420..28e9ab222 100644 --- a/ash/accelerators/accelerator_commands_unittest.cc +++ b/ash/accelerators/accelerator_commands_unittest.cc
@@ -6,7 +6,7 @@ #include <memory> -#include "ash/accelerators/accelerator_commands_classic.h" +#include "ash/accelerators/accelerator_commands.h" #include "ash/test/ash_test_base.h" #include "ash/wm/window_state.h" #include "ash/wm/window_util.h" @@ -60,7 +60,7 @@ wm::PinWindow(window1.get(), /* trusted */ false); EXPECT_TRUE(window_state1->IsPinned()); - Unpin(); + UnpinWindow(); EXPECT_FALSE(window_state1->IsPinned()); }
diff --git a/ash/accelerators/accelerator_controller.cc b/ash/accelerators/accelerator_controller.cc index 37a37d1..c181287 100644 --- a/ash/accelerators/accelerator_controller.cc +++ b/ash/accelerators/accelerator_controller.cc
@@ -4,22 +4,26 @@ #include "ash/accelerators/accelerator_controller.h" +#include <algorithm> +#include <cmath> #include <string> #include <utility> #include "ash/accelerators/accelerator_commands.h" -#include "ash/accelerators/accelerator_controller_delegate.h" #include "ash/accelerators/debug_commands.h" #include "ash/accessibility/accessibility_controller.h" #include "ash/accessibility/accessibility_delegate.h" +#include "ash/debug.h" #include "ash/display/display_configuration_controller.h" #include "ash/display/display_move_window_util.h" #include "ash/focus_cycler.h" #include "ash/ime/ime_controller.h" #include "ash/ime/ime_switch_type.h" +#include "ash/magnifier/magnification_controller.h" #include "ash/media_controller.h" #include "ash/multi_profile_uma.h" #include "ash/new_window_controller.h" +#include "ash/public/cpp/config.h" #include "ash/resources/vector_icons/vector_icons.h" #include "ash/root_window_controller.h" #include "ash/rotator/window_rotation.h" @@ -35,6 +39,7 @@ #include "ash/system/keyboard_brightness_control_delegate.h" #include "ash/system/palette/palette_tray.h" #include "ash/system/palette/palette_utils.h" +#include "ash/system/power/power_button_controller.h" #include "ash/system/status_area_widget.h" #include "ash/system/system_notifier.h" #include "ash/system/toast/toast_data.h" @@ -42,6 +47,7 @@ #include "ash/system/tray/system_tray.h" #include "ash/system/tray/system_tray_notifier.h" #include "ash/system/web_notification/web_notification_tray.h" +#include "ash/touch/touch_hud_debug.h" #include "ash/utility/screenshot_controller.h" #include "ash/voice_interaction/voice_interaction_controller.h" #include "ash/wm/mru_window_tracker.h" @@ -57,6 +63,7 @@ #include "base/optional.h" #include "base/strings/string_split.h" #include "base/strings/utf_string_conversions.h" +#include "base/sys_info.h" #include "chromeos/chromeos_switches.h" #include "chromeos/dbus/dbus_thread_manager.h" #include "chromeos/dbus/power_manager_client.h" @@ -858,16 +865,72 @@ volume_controller->VolumeUp(); } +bool CanHandleMagnifyScreen() { + return Shell::Get()->magnification_controller()->IsEnabled(); +} + +// Magnify the screen +void HandleMagnifyScreen(int delta_index) { + // TODO(crbug.com/612331): Mash support. + if (Shell::GetAshConfig() == Config::MASH) { + NOTIMPLEMENTED(); + return; + } + + if (!Shell::Get()->magnification_controller()->IsEnabled()) + return; + + // TODO(yoshiki): Move the following logic to MagnificationController. + float scale = Shell::Get()->magnification_controller()->GetScale(); + // Calculate rounded logarithm (base kMagnificationScaleFactor) of scale. + int scale_index = + std::round(std::log(scale) / + std::log(MagnificationController::kMagnificationScaleFactor)); + + int new_scale_index = std::max(0, std::min(8, scale_index + delta_index)); + + Shell::Get()->magnification_controller()->SetScale( + std::pow(MagnificationController::kMagnificationScaleFactor, + new_scale_index), + true); +} + +bool CanHandleTouchHud() { + // TODO(crbug.com/612331): Mash support. + if (Shell::GetAshConfig() == Config::MASH) + return false; + + return RootWindowController::ForTargetRootWindow()->touch_hud_debug(); +} + +void HandleTouchHudClear() { + // TODO(crbug.com/612331): Mash support. + if (Shell::GetAshConfig() == Config::MASH) { + NOTIMPLEMENTED(); + return; + } + RootWindowController::ForTargetRootWindow()->touch_hud_debug()->Clear(); +} + +void HandleTouchHudModeChange() { + // TODO(crbug.com/612331): Mash support. + if (Shell::GetAshConfig() == Config::MASH) { + NOTIMPLEMENTED(); + return; + } + RootWindowController* controller = + RootWindowController::ForTargetRootWindow(); + controller->touch_hud_debug()->ChangeToNextMode(); +} + } // namespace //////////////////////////////////////////////////////////////////////////////// // AcceleratorController, public: AcceleratorController::AcceleratorController( - AcceleratorControllerDelegate* delegate, ui::AcceleratorManagerDelegate* manager_delegate) - : delegate_(delegate), - accelerator_manager_(new ui::AcceleratorManager(manager_delegate)), + : accelerator_manager_(new ui::AcceleratorManager(manager_delegate)), accelerator_history_(new ui::AcceleratorHistory) { Init(); } @@ -1104,6 +1167,9 @@ case DEBUG_PRINT_WINDOW_HIERARCHY: case DEBUG_SHOW_TOAST: case DEBUG_TOGGLE_DEVICE_SCALE_FACTOR: + case DEBUG_TOGGLE_SHOW_DEBUG_BORDERS: + case DEBUG_TOGGLE_SHOW_FPS_COUNTER: + case DEBUG_TOGGLE_SHOW_PAINT_RECTS: case DEBUG_TOGGLE_TOUCH_PAD: case DEBUG_TOGGLE_TOUCH_SCREEN: case DEBUG_TOGGLE_TABLET_MODE: @@ -1117,6 +1183,9 @@ return CanHandleDisableCapsLock(previous_accelerator); case LOCK_SCREEN: return CanHandleLock(); + case MAGNIFY_SCREEN_ZOOM_IN: + case MAGNIFY_SCREEN_ZOOM_OUT: + return CanHandleMagnifyScreen(); case MOVE_WINDOW_TO_ABOVE_DISPLAY: case MOVE_WINDOW_TO_BELOW_DISPLAY: case MOVE_WINDOW_TO_LEFT_DISPLAY: @@ -1153,6 +1222,11 @@ return CanHandleToggleMessageCenterBubble(); case TOGGLE_MIRROR_MODE: return true; + case TOUCH_HUD_CLEAR: + case TOUCH_HUD_MODE_CHANGE: + return CanHandleTouchHud(); + case UNPIN: + return accelerators::CanUnpinWindow(); case WINDOW_CYCLE_SNAP_LEFT: case WINDOW_CYCLE_SNAP_RIGHT: return CanHandleWindowSnap(); @@ -1177,6 +1251,8 @@ case LAUNCH_APP_6: case LAUNCH_APP_7: case LAUNCH_LAST_APP: + case LOCK_PRESSED: + case LOCK_RELEASED: case MEDIA_NEXT_TRACK: case MEDIA_PLAY_PAUSE: case MEDIA_PREV_TRACK: @@ -1186,6 +1262,8 @@ case OPEN_FEEDBACK_PAGE: case OPEN_FILE_MANAGER: case OPEN_GET_HELP: + case POWER_PRESSED: + case POWER_RELEASED: case PRINT_UI_HIERARCHIES: case RESTORE_TAB: case ROTATE_WINDOW: @@ -1208,14 +1286,7 @@ case VOLUME_UP: case WINDOW_MINIMIZE: return true; - - default: - // Default switch is temporary until mash transition complete. Needed as - // some actions don't yet work with mash. - break; } - return delegate_ && delegate_->HandlesAction(action) && - delegate_->CanPerformAction(action, accelerator, previous_accelerator); } void AcceleratorController::PerformAction(AcceleratorAction action, @@ -1254,6 +1325,17 @@ case DEBUG_PRINT_WINDOW_HIERARCHY: case DEBUG_SHOW_TOAST: case DEBUG_TOGGLE_DEVICE_SCALE_FACTOR: + debug::PerformDebugActionIfEnabled(action); + break; + case DEBUG_TOGGLE_SHOW_DEBUG_BORDERS: + debug::ToggleShowDebugBorders(); + break; + case DEBUG_TOGGLE_SHOW_FPS_COUNTER: + debug::ToggleShowFpsCounter(); + break; + case DEBUG_TOGGLE_SHOW_PAINT_RECTS: + debug::ToggleShowPaintRects(); + break; case DEBUG_TOGGLE_TOUCH_PAD: case DEBUG_TOGGLE_TOUCH_SCREEN: case DEBUG_TOGGLE_TABLET_MODE: @@ -1324,9 +1406,20 @@ case LAUNCH_LAST_APP: HandleLaunchLastApp(); break; + case LOCK_PRESSED: + case LOCK_RELEASED: + Shell::Get()->power_button_controller()->OnLockButtonEvent( + action == LOCK_PRESSED, base::TimeTicks()); + break; case LOCK_SCREEN: HandleLock(); break; + case MAGNIFY_SCREEN_ZOOM_IN: + HandleMagnifyScreen(1); + break; + case MAGNIFY_SCREEN_ZOOM_OUT: + HandleMagnifyScreen(-1); + break; case MEDIA_NEXT_TRACK: HandleMediaNextTrack(); break; @@ -1366,6 +1459,19 @@ case OPEN_GET_HELP: HandleGetHelp(); break; + case POWER_PRESSED: + case POWER_RELEASED: + if (!base::SysInfo::IsRunningOnChromeOS()) { + // There is no powerd, the Chrome OS power manager, in linux desktop, + // so call the PowerButtonController here. + Shell::Get()->power_button_controller()->OnPowerButtonEvent( + action == POWER_PRESSED, base::TimeTicks()); + } + // We don't do anything with these at present on the device, + // (power button events are reported to us from powerm via + // D-BUS), but we consume them to prevent them from getting + // passed to apps -- see http://crbug.com/146609. + break; case PREVIOUS_IME: HandlePreviousIme(accelerator); break; @@ -1462,6 +1568,15 @@ case TOGGLE_WIFI: Shell::Get()->system_tray_notifier()->NotifyRequestToggleWifi(); break; + case TOUCH_HUD_CLEAR: + HandleTouchHudClear(); + break; + case TOUCH_HUD_MODE_CHANGE: + HandleTouchHudModeChange(); + break; + case UNPIN: + accelerators::UnpinWindow(); + break; case VOLUME_DOWN: HandleVolumeDown(volume_controller_.get(), accelerator); break; @@ -1481,12 +1596,6 @@ case WINDOW_POSITION_CENTER: HandlePositionCenter(); break; - default: - // Temporary until mash transition complete. Needed as some actions - // don't yet work with mash. - DCHECK(delegate_ && delegate_->HandlesAction(action)); - delegate_->PerformAction(action, accelerator); - break; } }
diff --git a/ash/accelerators/accelerator_controller.h b/ash/accelerators/accelerator_controller.h index 96c03e0..a481d7c 100644 --- a/ash/accelerators/accelerator_controller.h +++ b/ash/accelerators/accelerator_controller.h
@@ -31,7 +31,6 @@ namespace ash { struct AcceleratorData; -class AcceleratorControllerDelegate; class ExitWarningHandler; // Identifier for the high contrast toggle accelerator notification. @@ -43,8 +42,8 @@ class ASH_EXPORT AcceleratorController : public ui::AcceleratorTarget, public mojom::AcceleratorController { public: - AcceleratorController(AcceleratorControllerDelegate* delegate, - ui::AcceleratorManagerDelegate* manager_delegate); + explicit AcceleratorController( + ui::AcceleratorManagerDelegate* manager_delegate); ~AcceleratorController() override; // A list of possible ways in which an accelerator should be restricted before @@ -178,8 +177,6 @@ AcceleratorAction action, const ui::Accelerator& accelerator) const; - AcceleratorControllerDelegate* delegate_; - std::unique_ptr<ui::AcceleratorManager> accelerator_manager_; // A tracker for the current and previous accelerators.
diff --git a/ash/accelerators/accelerator_controller_delegate.h b/ash/accelerators/accelerator_controller_delegate.h deleted file mode 100644 index 5cc1a8a0..0000000 --- a/ash/accelerators/accelerator_controller_delegate.h +++ /dev/null
@@ -1,43 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef ASH_ACCELERATORS_ACCELERATOR_CONTROLLER_DELEGATE_H_ -#define ASH_ACCELERATORS_ACCELERATOR_CONTROLLER_DELEGATE_H_ - -#include "ash/accelerators/accelerator_table.h" -#include "ash/ash_export.h" - -namespace ui { -class Accelerator; -} - -namespace ash { - -// Used by AcceleratorController to handle environment specific commands. This -// file is temporary while ash supports both mus and aura. -class ASH_EXPORT AcceleratorControllerDelegate { - public: - // Returns true if the delegate is responsible for handling |action|. This - // should not return whether the action may be enabled, only if this delegate - // handles the action. - virtual bool HandlesAction(AcceleratorAction action) = 0; - - // Returns true if the delegate can perform the action at this time. Only - // invoked if HandlesAction() returns true. - virtual bool CanPerformAction( - AcceleratorAction action, - const ui::Accelerator& accelerator, - const ui::Accelerator& previous_accelerator) = 0; - - // Performs the specified action. - virtual void PerformAction(AcceleratorAction action, - const ui::Accelerator& accelerator) = 0; - - protected: - virtual ~AcceleratorControllerDelegate() {} -}; - -} // namespace ash - -#endif // ASH_ACCELERATORS_ACCELERATOR_CONTROLLER_DELEGATE_H_
diff --git a/ash/accelerators/accelerator_controller_delegate_classic.cc b/ash/accelerators/accelerator_controller_delegate_classic.cc deleted file mode 100644 index 7389e99..0000000 --- a/ash/accelerators/accelerator_controller_delegate_classic.cc +++ /dev/null
@@ -1,200 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ash/accelerators/accelerator_controller_delegate_classic.h" - -#include <algorithm> -#include <cmath> -#include <memory> -#include <string> -#include <utility> - -#include "ash/accelerators/accelerator_commands_classic.h" -#include "ash/accelerators/debug_commands.h" -#include "ash/debug.h" -#include "ash/host/ash_window_tree_host.h" -#include "ash/magnifier/magnification_controller.h" -#include "ash/public/cpp/shell_window_ids.h" -#include "ash/root_window_controller.h" -#include "ash/shell.h" -#include "ash/system/power/power_button_controller.h" -#include "ash/system/system_notifier.h" -#include "ash/touch/touch_hud_debug.h" -#include "ash/wm/tablet_mode/tablet_mode_controller.h" -#include "ash/wm/window_state.h" -#include "ash/wm/wm_event.h" -#include "base/sys_info.h" -#include "third_party/skia/include/core/SkColor.h" -#include "ui/base/accelerators/accelerator.h" -#include "ui/display/manager/display_manager.h" -#include "ui/events/event.h" -#include "ui/events/keycodes/keyboard_codes.h" - -namespace ash { -namespace { - -bool CanHandleMagnifyScreen() { - return Shell::Get()->magnification_controller()->IsEnabled(); -} - -// Magnify the screen -void HandleMagnifyScreen(int delta_index) { - if (Shell::Get()->magnification_controller()->IsEnabled()) { - // TODO(yoshiki): Move the following logic to MagnificationController. - float scale = Shell::Get()->magnification_controller()->GetScale(); - // Calculate rounded logarithm (base kMagnificationScaleFactor) of scale. - int scale_index = std::round( - std::log(scale) / - std::log(MagnificationController::kMagnificationScaleFactor)); - - int new_scale_index = std::max(0, std::min(8, scale_index + delta_index)); - - Shell::Get()->magnification_controller()->SetScale( - std::pow(MagnificationController::kMagnificationScaleFactor, - new_scale_index), - true); - } -} - -bool CanHandleUnpin() { - // Returns true only for WindowStateType::PINNED. - // WindowStateType::TRUSTED_PINNED does not accept user's unpin operation. - wm::WindowState* window_state = wm::GetActiveWindowState(); - return window_state && - window_state->GetStateType() == mojom::WindowStateType::PINNED; -} - -bool CanHandleTouchHud() { - return RootWindowController::ForTargetRootWindow()->touch_hud_debug(); -} - -void HandleTouchHudClear() { - RootWindowController::ForTargetRootWindow()->touch_hud_debug()->Clear(); -} - -void HandleTouchHudModeChange() { - RootWindowController* controller = - RootWindowController::ForTargetRootWindow(); - controller->touch_hud_debug()->ChangeToNextMode(); -} - -} // namespace - -AcceleratorControllerDelegateClassic::AcceleratorControllerDelegateClassic() = - default; - -AcceleratorControllerDelegateClassic::~AcceleratorControllerDelegateClassic() = - default; - -bool AcceleratorControllerDelegateClassic::HandlesAction( - AcceleratorAction action) { - // NOTE: When adding a new accelerator that only depends on //ash/common code, - // add it to accelerator_controller.cc instead. See class comment. - switch (action) { - case DEBUG_TOGGLE_SHOW_DEBUG_BORDERS: - case DEBUG_TOGGLE_SHOW_FPS_COUNTER: - case DEBUG_TOGGLE_SHOW_PAINT_RECTS: - case LOCK_PRESSED: - case LOCK_RELEASED: - case MAGNIFY_SCREEN_ZOOM_IN: - case MAGNIFY_SCREEN_ZOOM_OUT: - case POWER_PRESSED: - case POWER_RELEASED: - case TOGGLE_MESSAGE_CENTER_BUBBLE: - case TOUCH_HUD_CLEAR: - case TOUCH_HUD_MODE_CHANGE: - case UNPIN: - return true; - - default: - break; - } - return false; -} - -bool AcceleratorControllerDelegateClassic::CanPerformAction( - AcceleratorAction action, - const ui::Accelerator& accelerator, - const ui::Accelerator& previous_accelerator) { - switch (action) { - case DEBUG_TOGGLE_SHOW_DEBUG_BORDERS: - case DEBUG_TOGGLE_SHOW_FPS_COUNTER: - case DEBUG_TOGGLE_SHOW_PAINT_RECTS: - return debug::DebugAcceleratorsEnabled(); - case MAGNIFY_SCREEN_ZOOM_IN: - case MAGNIFY_SCREEN_ZOOM_OUT: - return CanHandleMagnifyScreen(); - case UNPIN: - return CanHandleUnpin(); - - // Following are always enabled: - case LOCK_PRESSED: - case LOCK_RELEASED: - case POWER_PRESSED: - case POWER_RELEASED: - return true; - - case TOUCH_HUD_CLEAR: - case TOUCH_HUD_MODE_CHANGE: - return CanHandleTouchHud(); - - default: - NOTREACHED(); - break; - } - return false; -} - -void AcceleratorControllerDelegateClassic::PerformAction( - AcceleratorAction action, - const ui::Accelerator& accelerator) { - switch (action) { - case DEBUG_TOGGLE_SHOW_DEBUG_BORDERS: - debug::ToggleShowDebugBorders(); - break; - case DEBUG_TOGGLE_SHOW_FPS_COUNTER: - debug::ToggleShowFpsCounter(); - break; - case DEBUG_TOGGLE_SHOW_PAINT_RECTS: - debug::ToggleShowPaintRects(); - break; - case LOCK_PRESSED: - case LOCK_RELEASED: - Shell::Get()->power_button_controller()->OnLockButtonEvent( - action == LOCK_PRESSED, base::TimeTicks()); - break; - case MAGNIFY_SCREEN_ZOOM_IN: - HandleMagnifyScreen(1); - break; - case MAGNIFY_SCREEN_ZOOM_OUT: - HandleMagnifyScreen(-1); - break; - case POWER_PRESSED: // fallthrough - case POWER_RELEASED: - if (!base::SysInfo::IsRunningOnChromeOS()) { - // There is no powerd, the Chrome OS power manager, in linux desktop, - // so call the PowerButtonController here. - Shell::Get()->power_button_controller()->OnPowerButtonEvent( - action == POWER_PRESSED, base::TimeTicks()); - } - // We don't do anything with these at present on the device, - // (power button events are reported to us from powerm via - // D-BUS), but we consume them to prevent them from getting - // passed to apps -- see http://crbug.com/146609. - break; - case TOUCH_HUD_CLEAR: - HandleTouchHudClear(); - break; - case TOUCH_HUD_MODE_CHANGE: - HandleTouchHudModeChange(); - break; - case UNPIN: - accelerators::Unpin(); - break; - default: - break; - } -} - -} // namespace ash
diff --git a/ash/accelerators/accelerator_controller_delegate_classic.h b/ash/accelerators/accelerator_controller_delegate_classic.h deleted file mode 100644 index 0e6a734..0000000 --- a/ash/accelerators/accelerator_controller_delegate_classic.h +++ /dev/null
@@ -1,39 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef ASH_ACCELERATORS_ACCELERATOR_CONTROLLER_DELEGATE_CLASSIC_H_ -#define ASH_ACCELERATORS_ACCELERATOR_CONTROLLER_DELEGATE_CLASSIC_H_ - -#include <memory> - -#include "ash/accelerators/accelerator_controller_delegate.h" -#include "base/macros.h" - -namespace ash { - -// Support for accelerators that only work in classic ash and not in mash, -// for example accelerators related to display management. These sorts of -// accelerators should be rare. Most new accelerators should be added to -// accelerator_controller.cc instead. -class ASH_EXPORT AcceleratorControllerDelegateClassic - : public AcceleratorControllerDelegate { - public: - AcceleratorControllerDelegateClassic(); - ~AcceleratorControllerDelegateClassic() override; - - // AcceleratorControllerDelegate: - bool HandlesAction(AcceleratorAction action) override; - bool CanPerformAction(AcceleratorAction action, - const ui::Accelerator& accelerator, - const ui::Accelerator& previous_accelerator) override; - void PerformAction(AcceleratorAction action, - const ui::Accelerator& accelerator) override; - - private: - DISALLOW_COPY_AND_ASSIGN(AcceleratorControllerDelegateClassic); -}; - -} // namespace ash - -#endif // ASH_ACCELERATORS_ACCELERATOR_CONTROLLER_DELEGATE_CLASSIC_H_
diff --git a/ash/accelerators/accelerator_controller_delegate_mash.cc b/ash/accelerators/accelerator_controller_delegate_mash.cc deleted file mode 100644 index 68a364d96..0000000 --- a/ash/accelerators/accelerator_controller_delegate_mash.cc +++ /dev/null
@@ -1,33 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ash/accelerators/accelerator_controller_delegate_mash.h" - -#include "base/logging.h" - -namespace ash { - -AcceleratorControllerDelegateMash::AcceleratorControllerDelegateMash() = - default; - -AcceleratorControllerDelegateMash::~AcceleratorControllerDelegateMash() = - default; - -bool AcceleratorControllerDelegateMash::HandlesAction( - AcceleratorAction action) { - return false; -} - -bool AcceleratorControllerDelegateMash::CanPerformAction( - AcceleratorAction action, - const ui::Accelerator& accelerator, - const ui::Accelerator& previous_accelerator) { - return false; -} - -void AcceleratorControllerDelegateMash::PerformAction( - AcceleratorAction action, - const ui::Accelerator& accelerator) {} - -} // namespace ash
diff --git a/ash/accelerators/accelerator_controller_delegate_mash.h b/ash/accelerators/accelerator_controller_delegate_mash.h deleted file mode 100644 index 6f2e21be..0000000 --- a/ash/accelerators/accelerator_controller_delegate_mash.h +++ /dev/null
@@ -1,35 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef ASH_ACCELERATORS_ACCELERATOR_CONTROLLER_DELEGATE_MASH_H_ -#define ASH_ACCELERATORS_ACCELERATOR_CONTROLLER_DELEGATE_MASH_H_ - -#include "ash/accelerators/accelerator_controller_delegate.h" -#include "base/macros.h" - -namespace ash { - -// Controls accelerators that are specific to mash. -// TODO(jamescook): Eliminate this class and inline the checks for mash into -// AcceleratorController. -class AcceleratorControllerDelegateMash : public AcceleratorControllerDelegate { - public: - AcceleratorControllerDelegateMash(); - ~AcceleratorControllerDelegateMash() override; - - // AcceleratorControllerDelegate: - bool HandlesAction(AcceleratorAction action) override; - bool CanPerformAction(AcceleratorAction action, - const ui::Accelerator& accelerator, - const ui::Accelerator& previous_accelerator) override; - void PerformAction(AcceleratorAction action, - const ui::Accelerator& accelerator) override; - - private: - DISALLOW_COPY_AND_ASSIGN(AcceleratorControllerDelegateMash); -}; - -} // namespace ash - -#endif // ASH_ACCELERATORS_ACCELERATOR_CONTROLLER_DELEGATE_MASH_H_
diff --git a/ash/accelerators/accelerator_controller_unittest.cc b/ash/accelerators/accelerator_controller_unittest.cc index 0cb5deb5..b7d73682 100644 --- a/ash/accelerators/accelerator_controller_unittest.cc +++ b/ash/accelerators/accelerator_controller_unittest.cc
@@ -551,7 +551,7 @@ ui::EF_CONTROL_DOWN | ui::EF_SHIFT_DOWN); display::Display::Rotation new_rotation = GetActiveDisplayRotation(display.id()); - // |new_rotation| is determined by the AcceleratorControllerDelegate. + // |new_rotation| is determined by the AcceleratorController. EXPECT_NE(initial_rotation, new_rotation); }
diff --git a/ash/app_list/model/BUILD.gn b/ash/app_list/model/BUILD.gn index 015aad0..1deaded 100644 --- a/ash/app_list/model/BUILD.gn +++ b/ash/app_list/model/BUILD.gn
@@ -18,20 +18,6 @@ "app_list_view_state.h", "folder_image.cc", "folder_image.h", - "search/term_break_iterator.cc", - "search/term_break_iterator.h", - "search/tokenized_string.cc", - "search/tokenized_string.h", - "search/tokenized_string_char_iterator.cc", - "search/tokenized_string_char_iterator.h", - "search/tokenized_string_match.cc", - "search/tokenized_string_match.h", - "search_box_model.cc", - "search_box_model.h", - "search_box_model_observer.h", - "search_result.cc", - "search_result.h", - "search_result_observer.h", ] defines = [ "APP_LIST_MODEL_IMPLEMENTATION" ] @@ -46,3 +32,32 @@ "//ui/gfx", ] } + +component("search_model") { + sources = [ + "search/search_box_model.cc", + "search/search_box_model.h", + "search/search_box_model_observer.h", + "search/search_model.cc", + "search/search_model.h", + "search/search_result.cc", + "search/search_result.h", + "search/search_result_observer.h", + "search/term_break_iterator.cc", + "search/term_break_iterator.h", + "search/tokenized_string.cc", + "search/tokenized_string.h", + "search/tokenized_string_char_iterator.cc", + "search/tokenized_string_char_iterator.h", + "search/tokenized_string_match.cc", + "search/tokenized_string_match.h", + ] + + defines = [ "APP_LIST_MODEL_IMPLEMENTATION" ] + + deps = [ + "//base:i18n", + "//ui/base", + "//ui/gfx", + ] +}
diff --git a/ash/app_list/model/app_list_model.cc b/ash/app_list/model/app_list_model.cc index 70853b0e..fb535cd 100644 --- a/ash/app_list/model/app_list_model.cc +++ b/ash/app_list/model/app_list_model.cc
@@ -10,21 +10,11 @@ #include "ash/app_list/model/app_list_folder_item.h" #include "ash/app_list/model/app_list_item.h" #include "ash/app_list/model/app_list_model_observer.h" -#include "ash/app_list/model/search_box_model.h" namespace app_list { AppListModel::AppListModel() - : top_level_item_list_(new AppListItemList), - search_box_(new SearchBoxModel), - results_(new SearchResults), - status_(STATUS_NORMAL), - state_(INVALID_STATE), - state_fullscreen_(AppListViewState::CLOSED), - folders_enabled_(false), - custom_launcher_page_enabled_(true), - search_engine_is_google_(false), - is_tablet_mode_(false) { + : top_level_item_list_(std::make_unique<AppListItemList>()) { top_level_item_list_->AddObserver(this); } @@ -50,26 +40,13 @@ } void AppListModel::SetState(State state) { - if (state_ == state) - return; - - State old_state = state_; - state_ = state; - - for (auto& observer : observers_) - observer.OnAppListModelStateChanged(old_state, state_); } void AppListModel::SetStateFullscreen(AppListViewState state) { state_fullscreen_ = state; } -void AppListModel::SetTabletMode(bool started) { - is_tablet_mode_ = started; - search_box_->SetTabletMode(started); -} - AppListItem* AppListModel::FindItem(const std::string& id) { AppListItem* item = top_level_item_list_->FindItem(id); if (item) @@ -334,22 +311,6 @@ observer.OnCustomLauncherPageEnabledStateChanged(enabled); } -std::vector<SearchResult*> AppListModel::FilterSearchResultsByDisplayType( - SearchResults* results, - SearchResult::DisplayType display_type, - size_t max_results) { - std::vector<SearchResult*> matches; - for (size_t i = 0; i < results->item_count(); ++i) { - SearchResult* item = results->GetItemAt(i); - if (item->display_type() == display_type) { - matches.push_back(item); - if (matches.size() == max_results) - break; - } - } - return matches; -} - void AppListModel::PushCustomLauncherPageSubpage() { custom_launcher_page_subpage_depth_++; } @@ -366,10 +327,6 @@ custom_launcher_page_subpage_depth_ = 0; } -void AppListModel::SetSearchEngineIsGoogle(bool is_google) { - search_engine_is_google_ = is_google; -} - // Private methods void AppListModel::OnListItemMoved(size_t from_index,
diff --git a/ash/app_list/model/app_list_model.h b/ash/app_list/model/app_list_model.h index e1a3e7d8..bb2c774c 100644 --- a/ash/app_list/model/app_list_model.h +++ b/ash/app_list/model/app_list_model.h
@@ -15,10 +15,8 @@ #include "ash/app_list/model/app_list_item_list_observer.h" #include "ash/app_list/model/app_list_model_export.h" #include "ash/app_list/model/app_list_view_state.h" -#include "ash/app_list/model/search_result.h" #include "base/macros.h" #include "base/observer_list.h" -#include "ui/base/models/list_model.h" namespace app_list { @@ -26,12 +24,9 @@ class AppListItem; class AppListItemList; class AppListModelObserver; -class SearchBoxModel; -// Master model of app list that consists of three sub models: AppListItemList, -// SearchBoxModel and SearchResults. The AppListItemList sub model owns a list -// of AppListItems and is displayed in the grid view. SearchBoxModel is -// the model for SearchBoxView. SearchResults owns a list of SearchResult. +// Master model of app list that holds AppListItemList, which owns a list +// of AppListItems and is displayed in the grid view. // NOTE: Currently this class observes |top_level_item_list_|. The View code may // move entries in the item list directly (but can not add or remove them) and // the model needs to notify its observers when this occurs. @@ -54,8 +49,6 @@ STATE_LAST = INVALID_STATE, }; - typedef ui::ListModel<SearchResult> SearchResults; - AppListModel(); ~AppListModel() override; @@ -71,10 +64,6 @@ void SetStateFullscreen(AppListViewState state); AppListViewState state_fullscreen() const { return state_fullscreen_; } - // Whether tablet mode is active. Controlled by AppListView. - void SetTabletMode(bool started); - bool tablet_mode() const { return is_tablet_mode_; } - // Finds the item matching |id|. AppListItem* FindItem(const std::string& id); @@ -175,20 +164,8 @@ return custom_launcher_page_subpage_depth_; } - void SetSearchEngineIsGoogle(bool is_google); - bool search_engine_is_google() const { return search_engine_is_google_; } - - // Filters the given |results| by |display_type|. The returned list is - // truncated to |max_results|. - static std::vector<SearchResult*> FilterSearchResultsByDisplayType( - SearchResults* results, - SearchResult::DisplayType display_type, - size_t max_results); - AppListItemList* top_level_item_list() { return top_level_item_list_.get(); } - SearchBoxModel* search_box() { return search_box_.get(); } - SearchResults* results() { return results_.get(); } Status status() const { return status_; } bool folders_enabled() const { return folders_enabled_; } @@ -227,20 +204,14 @@ std::unique_ptr<AppListItemList> top_level_item_list_; - std::unique_ptr<SearchBoxModel> search_box_; - std::unique_ptr<SearchResults> results_; - - Status status_; - State state_; + Status status_ = STATUS_NORMAL; + State state_ = INVALID_STATE; // The AppListView state. Controlled by the AppListView. - AppListViewState state_fullscreen_; + AppListViewState state_fullscreen_ = AppListViewState::CLOSED; base::ObserverList<AppListModelObserver, true> observers_; - bool folders_enabled_; - bool custom_launcher_page_enabled_; + bool folders_enabled_ = false; + bool custom_launcher_page_enabled_ = true; std::string custom_launcher_page_name_; - bool search_engine_is_google_; - // Whether tablet mode is active. Controlled by the AppListView. - bool is_tablet_mode_; // The current number of subpages the custom launcher page has pushed. int custom_launcher_page_subpage_depth_;
diff --git a/ash/app_list/model/app_list_model_observer.h b/ash/app_list/model/app_list_model_observer.h index ed4ee8d..7edb7110 100644 --- a/ash/app_list/model/app_list_model_observer.h +++ b/ash/app_list/model/app_list_model_observer.h
@@ -17,10 +17,6 @@ // Triggered after AppListModel's status has changed. virtual void OnAppListModelStatusChanged() {} - // Triggered after AppListModel's state has changed. - virtual void OnAppListModelStateChanged(AppListModel::State old_state, - AppListModel::State new_state) {} - // Triggered after |item| has been added to the model. virtual void OnAppListItemAdded(AppListItem* item) {}
diff --git a/ash/app_list/model/search_box_model.cc b/ash/app_list/model/search/search_box_model.cc similarity index 95% rename from ash/app_list/model/search_box_model.cc rename to ash/app_list/model/search/search_box_model.cc index e91012b..037e88a 100644 --- a/ash/app_list/model/search_box_model.cc +++ b/ash/app_list/model/search/search_box_model.cc
@@ -2,11 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "ash/app_list/model/search_box_model.h" +#include "ash/app_list/model/search/search_box_model.h" #include <utility> -#include "ash/app_list/model/search_box_model_observer.h" +#include "ash/app_list/model/search/search_box_model_observer.h" #include "base/metrics/histogram_macros.h" namespace app_list {
diff --git a/ash/app_list/model/search_box_model.h b/ash/app_list/model/search/search_box_model.h similarity index 95% rename from ash/app_list/model/search_box_model.h rename to ash/app_list/model/search/search_box_model.h index f20f74b..0c45249 100644 --- a/ash/app_list/model/search_box_model.h +++ b/ash/app_list/model/search/search_box_model.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 ASH_APP_LIST_MODEL_SEARCH_BOX_MODEL_H_ -#define ASH_APP_LIST_MODEL_SEARCH_BOX_MODEL_H_ +#ifndef ASH_APP_LIST_MODEL_SEARCH_SEARCH_BOX_MODEL_H_ +#define ASH_APP_LIST_MODEL_SEARCH_SEARCH_BOX_MODEL_H_ #include <memory> @@ -99,4 +99,4 @@ } // namespace app_list -#endif // ASH_APP_LIST_MODEL_SEARCH_BOX_MODEL_H_ +#endif // ASH_APP_LIST_MODEL_SEARCH_SEARCH_BOX_MODEL_H_
diff --git a/ash/app_list/model/search_box_model_observer.h b/ash/app_list/model/search/search_box_model_observer.h similarity index 80% rename from ash/app_list/model/search_box_model_observer.h rename to ash/app_list/model/search/search_box_model_observer.h index ec54748..7a31642 100644 --- a/ash/app_list/model/search_box_model_observer.h +++ b/ash/app_list/model/search/search_box_model_observer.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 ASH_APP_LIST_MODEL_SEARCH_BOX_MODEL_OBSERVER_H_ -#define ASH_APP_LIST_MODEL_SEARCH_BOX_MODEL_OBSERVER_H_ +#ifndef ASH_APP_LIST_MODEL_SEARCH_SEARCH_BOX_MODEL_OBSERVER_H_ +#define ASH_APP_LIST_MODEL_SEARCH_SEARCH_BOX_MODEL_OBSERVER_H_ #include "ash/app_list/model/app_list_model_export.h" @@ -30,4 +30,4 @@ } // namespace app_list -#endif // ASH_APP_LIST_MODEL_SEARCH_BOX_MODEL_OBSERVER_H_ +#endif // ASH_APP_LIST_MODEL_SEARCH_SEARCH_BOX_MODEL_OBSERVER_H_
diff --git a/ash/app_list/model/search/search_model.cc b/ash/app_list/model/search/search_model.cc new file mode 100644 index 0000000..5bbab52 --- /dev/null +++ b/ash/app_list/model/search/search_model.cc
@@ -0,0 +1,36 @@ +// 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 "ash/app_list/model/search/search_model.h" + +namespace app_list { + +SearchModel::SearchModel() + : search_box_(std::make_unique<SearchBoxModel>()), + results_(std::make_unique<SearchResults>()) {} + +SearchModel::~SearchModel() {} + +void SearchModel::SetTabletMode(bool started) { + is_tablet_mode_ = started; + search_box_->SetTabletMode(started); +} + +std::vector<SearchResult*> SearchModel::FilterSearchResultsByDisplayType( + SearchResults* results, + SearchResult::DisplayType display_type, + size_t max_results) { + std::vector<SearchResult*> matches; + for (size_t i = 0; i < results->item_count(); ++i) { + SearchResult* item = results->GetItemAt(i); + if (item->display_type() == display_type) { + matches.push_back(item); + if (matches.size() == max_results) + break; + } + } + return matches; +} + +} // namespace app_list
diff --git a/ash/app_list/model/search/search_model.h b/ash/app_list/model/search/search_model.h new file mode 100644 index 0000000..d61b45a --- /dev/null +++ b/ash/app_list/model/search/search_model.h
@@ -0,0 +1,61 @@ +// 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 ASH_APP_LIST_MODEL_SEARCH_SEARCH_MODEL_H_ +#define ASH_APP_LIST_MODEL_SEARCH_SEARCH_MODEL_H_ + +#include <memory> +#include <vector> + +#include "ash/app_list/model/app_list_model_export.h" +#include "ash/app_list/model/search/search_box_model.h" +#include "ash/app_list/model/search/search_result.h" +#include "ui/base/models/list_model.h" + +namespace app_list { + +class SearchBoxModel; + +// A model of app list that holds two search related sub models: +// - SearchBoxModel: the model for SearchBoxView. +// - SearchResults: owning a list of SearchResult. +class APP_LIST_MODEL_EXPORT SearchModel { + public: + using SearchResults = ui::ListModel<SearchResult>; + + SearchModel(); + ~SearchModel(); + + // Whether tablet mode is active. Controlled by AppListView. + void SetTabletMode(bool started); + bool tablet_mode() const { return is_tablet_mode_; } + + void SetSearchEngineIsGoogle(bool is_google) { + search_engine_is_google_ = is_google; + } + bool search_engine_is_google() const { return search_engine_is_google_; } + + // Filters the given |results| by |display_type|. The returned list is + // truncated to |max_results|. + static std::vector<SearchResult*> FilterSearchResultsByDisplayType( + SearchResults* results, + SearchResult::DisplayType display_type, + size_t max_results); + + SearchBoxModel* search_box() { return search_box_.get(); } + SearchResults* results() { return results_.get(); } + + private: + std::unique_ptr<SearchBoxModel> search_box_; + std::unique_ptr<SearchResults> results_; + bool search_engine_is_google_ = false; + // Whether tablet mode is active. Controlled by the AppListView. + bool is_tablet_mode_ = false; + + DISALLOW_COPY_AND_ASSIGN(SearchModel); +}; + +} // namespace app_list + +#endif // ASH_APP_LIST_MODEL_SEARCH_SEARCH_MODEL_H_
diff --git a/ash/app_list/model/search_result.cc b/ash/app_list/model/search/search_result.cc similarity index 97% rename from ash/app_list/model/search_result.cc rename to ash/app_list/model/search/search_result.cc index 48bc5733..84de0170 100644 --- a/ash/app_list/model/search_result.cc +++ b/ash/app_list/model/search/search_result.cc
@@ -2,13 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "ash/app_list/model/search_result.h" +#include "ash/app_list/model/search/search_result.h" #include <map> +#include "ash/app_list/model/search/search_result_observer.h" #include "ash/app_list/model/search/tokenized_string.h" #include "ash/app_list/model/search/tokenized_string_match.h" -#include "ash/app_list/model/search_result_observer.h" namespace app_list {
diff --git a/ash/app_list/model/search_result.h b/ash/app_list/model/search/search_result.h similarity index 97% rename from ash/app_list/model/search_result.h rename to ash/app_list/model/search/search_result.h index 57399b5..807af1a 100644 --- a/ash/app_list/model/search_result.h +++ b/ash/app_list/model/search/search_result.h
@@ -2,11 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef ASH_APP_LIST_MODEL_SEARCH_RESULT_H_ -#define ASH_APP_LIST_MODEL_SEARCH_RESULT_H_ +#ifndef ASH_APP_LIST_MODEL_SEARCH_SEARCH_RESULT_H_ +#define ASH_APP_LIST_MODEL_SEARCH_SEARCH_RESULT_H_ #include <stddef.h> +#include <memory> #include <string> #include <vector> @@ -260,4 +261,4 @@ } // namespace app_list -#endif // ASH_APP_LIST_MODEL_SEARCH_RESULT_H_ +#endif // ASH_APP_LIST_MODEL_SEARCH_SEARCH_RESULT_H_
diff --git a/ash/app_list/model/search_result_observer.h b/ash/app_list/model/search/search_result_observer.h similarity index 87% rename from ash/app_list/model/search_result_observer.h rename to ash/app_list/model/search/search_result_observer.h index 2838eb4..1dd4772 100644 --- a/ash/app_list/model/search_result_observer.h +++ b/ash/app_list/model/search/search_result_observer.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 ASH_APP_LIST_MODEL_SEARCH_RESULT_OBSERVER_H_ -#define ASH_APP_LIST_MODEL_SEARCH_RESULT_OBSERVER_H_ +#ifndef ASH_APP_LIST_MODEL_SEARCH_SEARCH_RESULT_OBSERVER_H_ +#define ASH_APP_LIST_MODEL_SEARCH_SEARCH_RESULT_OBSERVER_H_ #include "ash/app_list/model/app_list_model_export.h" @@ -44,4 +44,4 @@ } // namespace app_list -#endif // ASH_APP_LIST_MODEL_SEARCH_RESULT_OBSERVER_H_ +#endif // ASH_APP_LIST_MODEL_SEARCH_SEARCH_RESULT_OBSERVER_H_
diff --git a/ash/message_center/message_center_view.cc b/ash/message_center/message_center_view.cc index b9320369..307ad53 100644 --- a/ash/message_center/message_center_view.cc +++ b/ash/message_center/message_center_view.cc
@@ -108,6 +108,22 @@ DISALLOW_COPY_AND_ASSIGN(EmptyNotificationView); }; +class MessageCenterScrollView : public views::ScrollView { + public: + explicit MessageCenterScrollView(MessageCenterView* owner) : owner_(owner) {} + + private: + // views::View: + void GetAccessibleNodeData(ui::AXNodeData* node_data) override { + node_data->role = ui::AX_ROLE_DIALOG; + node_data->SetName(owner_->GetButtonBarTitle()); + } + + MessageCenterView* owner_; + + DISALLOW_COPY_AND_ASSIGN(MessageCenterScrollView); +}; + } // namespace // MessageCenterView /////////////////////////////////////////////////////////// @@ -129,7 +145,7 @@ message_center_->AddObserver(this); set_notify_enter_exit_on_child(true); SetBackground(views::CreateSolidBackground(kBackgroundColor)); - SetFocusBehavior(views::View::FocusBehavior::ALWAYS); + SetFocusBehavior(views::View::FocusBehavior::NEVER); button_bar_ = new MessageCenterButtonBar( this, message_center, initially_settings_visible, GetButtonBarTitle()); @@ -137,7 +153,7 @@ const int button_height = button_bar_->GetPreferredSize().height(); - scroller_ = new views::ScrollView(); + scroller_ = new MessageCenterScrollView(this); scroller_->SetBackgroundColor(kBackgroundColor); scroller_->ClipHeightTo(kMinScrollViewHeight, max_height - button_height); scroller_->SetVerticalScrollBar(new views::OverlayScrollBar(false)); @@ -266,6 +282,12 @@ message_center_->AddObserver(this); } +base::string16 MessageCenterView::GetButtonBarTitle() const { + return is_locked_ ? + l10n_util::GetStringUTF16(IDS_ASH_MESSAGE_CENTER_FOOTER_LOCKSCREEN) : + l10n_util::GetStringUTF16(IDS_ASH_MESSAGE_CENTER_FOOTER_TITLE); +} + void MessageCenterView::OnDidChangeFocus(views::View* before, views::View* now) { // Update the button visibility when the focus state is changed. @@ -356,11 +378,6 @@ Update(true /* animate */); } -void MessageCenterView::GetAccessibleNodeData(ui::AXNodeData* node_data) { - node_data->role = ui::AX_ROLE_DIALOG; - node_data->SetName(GetButtonBarTitle()); -} - void MessageCenterView::OnNotificationAdded(const std::string& id) { int index = 0; const NotificationList::Notifications& notifications = @@ -543,13 +560,6 @@ message_list_view_->AddNotificationAt(view, index); } -base::string16 MessageCenterView::GetButtonBarTitle() const { - if (is_locked_) - return l10n_util::GetStringUTF16(IDS_ASH_MESSAGE_CENTER_FOOTER_LOCKSCREEN); - - return l10n_util::GetStringUTF16(IDS_ASH_MESSAGE_CENTER_FOOTER_TITLE); -} - void MessageCenterView::Update(bool animate) { bool no_message_views = (message_list_view_->GetNotificationCount() == 0);
diff --git a/ash/message_center/message_center_view.h b/ash/message_center/message_center_view.h index bf3f7cd..0ff47fc 100644 --- a/ash/message_center/message_center_view.h +++ b/ash/message_center/message_center_view.h
@@ -71,6 +71,8 @@ void SetIsClosing(bool is_closing); + base::string16 GetButtonBarTitle() const; + // Overridden from views::FocusChangeListener void OnWillChangeFocus(views::View* before, views::View* now) override {} void OnDidChangeFocus(views::View* before, views::View* now) override; @@ -82,7 +84,7 @@ protected: // Potentially sets the reposition target, and then returns whether or not it - // was was set. + // was set. virtual bool SetRepositionTarget(); // Overridden from views::View: @@ -91,7 +93,6 @@ int GetHeightForWidth(int width) const override; bool OnMouseWheel(const ui::MouseWheelEvent& event) override; void OnMouseExited(const ui::MouseEvent& event) override; - void GetAccessibleNodeData(ui::AXNodeData* node_data) override; // Overridden from MessageCenterObserver: void OnNotificationAdded(const std::string& id) override; @@ -137,7 +138,6 @@ void AddNotificationAt(const message_center::Notification& notification, int index); - base::string16 GetButtonBarTitle() const; void Update(bool animate); void SetVisibilityMode(Mode mode, bool animate); void UpdateButtonBarStatus();
diff --git a/ash/shell/app_list.cc b/ash/shell/app_list.cc index baf302fd..c0e8455 100644 --- a/ash/shell/app_list.cc +++ b/ash/shell/app_list.cc
@@ -10,8 +10,9 @@ #include "ash/app_list/model/app_list_item.h" #include "ash/app_list/model/app_list_item_list.h" #include "ash/app_list/model/app_list_model.h" -#include "ash/app_list/model/search_box_model.h" -#include "ash/app_list/model/search_result.h" +#include "ash/app_list/model/search/search_box_model.h" +#include "ash/app_list/model/search/search_model.h" +#include "ash/app_list/model/search/search_result.h" #include "ash/session/session_controller.h" #include "ash/shell.h" #include "ash/shell/example_factory.h" @@ -198,9 +199,11 @@ class ExampleAppListViewDelegate : public app_list::AppListViewDelegate { public: - ExampleAppListViewDelegate() : model_(new app_list::AppListModel) { + ExampleAppListViewDelegate() + : model_(std::make_unique<app_list::AppListModel>()), + search_model_(std::make_unique<app_list::SearchModel>()) { PopulateApps(); - DecorateSearchBox(model_->search_box()); + DecorateSearchBox(search_model_->search_box()); } private: @@ -222,6 +225,10 @@ // Overridden from app_list::AppListViewDelegate: app_list::AppListModel* GetModel() override { return model_.get(); } + app_list::SearchModel* GetSearchModel() override { + return search_model_.get(); + } + app_list::SpeechUIModel* GetSpeechUI() override { return &speech_ui_; } void OpenSearchResult(app_list::SearchResult* result, @@ -244,10 +251,11 @@ void StartSearch() override { base::string16 query; - base::TrimWhitespace(model_->search_box()->text(), base::TRIM_ALL, &query); + base::TrimWhitespace(search_model_->search_box()->text(), base::TRIM_ALL, + &query); query = base::i18n::ToLower(query); - model_->results()->DeleteAll(); + search_model_->results()->DeleteAll(); if (query.empty()) return; @@ -259,7 +267,7 @@ base::UTF8ToUTF16(WindowTypeShelfItem::GetTitle(type)); if (base::i18n::StringSearchIgnoringCaseAndAccents(query, title, NULL, NULL)) { - model_->results()->Add( + search_model_->results()->Add( std::make_unique<ExampleSearchResult>(type, query)); } } @@ -310,6 +318,7 @@ } std::unique_ptr<app_list::AppListModel> model_; + std::unique_ptr<app_list::SearchModel> search_model_; app_list::SpeechUIModel speech_ui_; DISALLOW_COPY_AND_ASSIGN(ExampleAppListViewDelegate);
diff --git a/ash/shell_port_classic.cc b/ash/shell_port_classic.cc index 5fcfce48..546e45cb 100644 --- a/ash/shell_port_classic.cc +++ b/ash/shell_port_classic.cc
@@ -8,7 +8,6 @@ #include <utility> #include "ash/accelerators/accelerator_controller.h" -#include "ash/accelerators/accelerator_controller_delegate_classic.h" #include "ash/host/ash_window_tree_host.h" #include "ash/host/ash_window_tree_host_init_params.h" #include "ash/keyboard/keyboard_ui.h" @@ -165,11 +164,7 @@ std::unique_ptr<AcceleratorController> ShellPortClassic::CreateAcceleratorController() { - DCHECK(!accelerator_controller_delegate_); - accelerator_controller_delegate_ = - std::make_unique<AcceleratorControllerDelegateClassic>(); - return std::make_unique<AcceleratorController>( - accelerator_controller_delegate_.get(), nullptr); + return std::make_unique<AcceleratorController>(nullptr); } void ShellPortClassic::AddVideoDetectorObserver(
diff --git a/ash/shell_port_classic.h b/ash/shell_port_classic.h index d1e8685..591b0b6 100644 --- a/ash/shell_port_classic.h +++ b/ash/shell_port_classic.h
@@ -14,7 +14,6 @@ namespace ash { -class AcceleratorControllerDelegateClassic; class PointerWatcherAdapterClassic; // Implementation of ShellPort for classic ash/aura. See ash/README.md for more @@ -26,10 +25,6 @@ static ShellPortClassic* Get(); - AcceleratorControllerDelegateClassic* accelerator_controller_delegate() { - return accelerator_controller_delegate_.get(); - } - // ShellPort: void Shutdown() override; Config GetAshConfig() const override; @@ -74,9 +69,6 @@ private: std::unique_ptr<PointerWatcherAdapterClassic> pointer_watcher_adapter_; - std::unique_ptr<AcceleratorControllerDelegateClassic> - accelerator_controller_delegate_; - DISALLOW_COPY_AND_ASSIGN(ShellPortClassic); };
diff --git a/ash/shell_port_mash.cc b/ash/shell_port_mash.cc index aa2e64b..1af5cfb0 100644 --- a/ash/shell_port_mash.cc +++ b/ash/shell_port_mash.cc
@@ -8,7 +8,6 @@ #include <utility> #include "ash/accelerators/accelerator_controller.h" -#include "ash/accelerators/accelerator_controller_delegate_mash.h" #include "ash/accelerators/accelerator_controller_registrar.h" #include "ash/keyboard/keyboard_ui_mash.h" #include "ash/public/cpp/config.h" @@ -152,8 +151,6 @@ std::unique_ptr<AcceleratorController> ShellPortMash::CreateAcceleratorController() { - DCHECK(!accelerator_controller_delegate_); - uint16_t accelerator_namespace_id = 0u; const bool add_result = window_manager_->GetNextAcceleratorNamespaceId(&accelerator_namespace_id); @@ -161,13 +158,10 @@ // should always succeed. DCHECK(add_result); - accelerator_controller_delegate_ = - std::make_unique<AcceleratorControllerDelegateMash>(); accelerator_controller_registrar_ = std::make_unique<AcceleratorControllerRegistrar>( window_manager_, accelerator_namespace_id); return std::make_unique<AcceleratorController>( - accelerator_controller_delegate_.get(), accelerator_controller_registrar_.get()); }
diff --git a/ash/shell_port_mash.h b/ash/shell_port_mash.h index 79b35945..a3a84de6 100644 --- a/ash/shell_port_mash.h +++ b/ash/shell_port_mash.h
@@ -19,7 +19,6 @@ namespace ash { -class AcceleratorControllerDelegateMash; class AcceleratorControllerRegistrar; class ImmersiveHandlerFactoryMash; class WindowManager; @@ -68,8 +67,6 @@ private: views::PointerWatcherEventRouter* pointer_watcher_event_router_ = nullptr; - std::unique_ptr<AcceleratorControllerDelegateMash> - accelerator_controller_delegate_; std::unique_ptr<AcceleratorControllerRegistrar> accelerator_controller_registrar_; std::unique_ptr<ImmersiveHandlerFactoryMash> immersive_handler_factory_;
diff --git a/ash/shell_port_mus.cc b/ash/shell_port_mus.cc index 66a7fa39..db7f2d7 100644 --- a/ash/shell_port_mus.cc +++ b/ash/shell_port_mus.cc
@@ -8,7 +8,6 @@ #include <utility> #include "ash/accelerators/accelerator_controller.h" -#include "ash/accelerators/accelerator_controller_delegate_classic.h" #include "ash/display/display_synchronizer.h" #include "ash/host/ash_window_tree_host_init_params.h" #include "ash/host/ash_window_tree_host_mus.h" @@ -255,11 +254,7 @@ std::unique_ptr<AcceleratorController> ShellPortMus::CreateAcceleratorController() { - DCHECK(!accelerator_controller_delegate_); - accelerator_controller_delegate_ = - std::make_unique<AcceleratorControllerDelegateClassic>(); - return std::make_unique<AcceleratorController>( - accelerator_controller_delegate_.get(), nullptr); + return std::make_unique<AcceleratorController>(nullptr); } void ShellPortMus::AddVideoDetectorObserver(
diff --git a/ash/shell_port_mus.h b/ash/shell_port_mus.h index a13a4478..f7a1d3b 100644 --- a/ash/shell_port_mus.h +++ b/ash/shell_port_mus.h
@@ -18,7 +18,6 @@ namespace ash { -class AcceleratorControllerDelegateClassic; class DisplaySynchronizer; class PointerWatcherAdapterClassic; class RootWindowController; @@ -36,10 +35,6 @@ ash::RootWindowController* GetRootWindowControllerWithDisplayId(int64_t id); - AcceleratorControllerDelegateClassic* accelerator_controller_delegate() { - return accelerator_controller_delegate_.get(); - } - aura::WindowTreeClient* window_tree_client(); WindowManager* window_manager() { return window_manager_; } @@ -90,8 +85,6 @@ private: std::unique_ptr<PointerWatcherAdapterClassic> pointer_watcher_adapter_; - std::unique_ptr<AcceleratorControllerDelegateClassic> - accelerator_controller_delegate_; std::unique_ptr<DisplaySynchronizer> display_synchronizer_;
diff --git a/cc/animation/animation_host.cc b/cc/animation/animation_host.cc index debdf30..38a592f8a 100644 --- a/cc/animation/animation_host.cc +++ b/cc/animation/animation_host.cc
@@ -5,10 +5,10 @@ #include "cc/animation/animation_host.h" #include <algorithm> +#include <memory> #include "base/callback.h" #include "base/macros.h" -#include "base/memory/ptr_util.h" #include "base/trace_event/trace_event.h" #include "base/trace_event/trace_event_argument.h" #include "cc/animation/animation_delegate.h" @@ -336,7 +336,7 @@ const ScrollTree& scroll_tree) { TRACE_EVENT0("cc", "AnimationHost::CollectAnimatorsState"); std::unique_ptr<MutatorInputState> result = - base::MakeUnique<MutatorInputState>(); + std::make_unique<MutatorInputState>(); for (auto& player : ticking_players_) { if (!player->IsWorkletAnimationPlayer())
diff --git a/cc/paint/paint_image.cc b/cc/paint/paint_image.cc index f397127..0b1541aa 100644 --- a/cc/paint/paint_image.cc +++ b/cc/paint/paint_image.cc
@@ -4,9 +4,10 @@ #include "cc/paint/paint_image.h" +#include <memory> + #include "base/atomic_sequence_num.h" #include "base/hash.h" -#include "base/memory/ptr_util.h" #include "cc/paint/paint_image_generator.h" #include "cc/paint/paint_record.h" #include "cc/paint/skia_paint_image_generator.h" @@ -120,7 +121,7 @@ nullptr, nullptr, SkImage::BitDepth::kU8, SkColorSpace::MakeSRGB()); } else if (paint_image_generator_) { cached_sk_image_ = - SkImage::MakeFromGenerator(base::MakeUnique<SkiaPaintImageGenerator>( + SkImage::MakeFromGenerator(std::make_unique<SkiaPaintImageGenerator>( paint_image_generator_, frame_index_)); } @@ -274,7 +275,7 @@ return GetSkImage(); sk_sp<SkImage> image = SkImage::MakeFromGenerator( - base::MakeUnique<SkiaPaintImageGenerator>(paint_image_generator_, index)); + std::make_unique<SkiaPaintImageGenerator>(paint_image_generator_, index)); if (!subset_rect_.IsEmpty()) image = image->makeSubset(gfx::RectToSkIRect(subset_rect_)); return image;
diff --git a/cc/paint/transfer_cache_entry.cc b/cc/paint/transfer_cache_entry.cc index c4d5fc7..ff4f0a5 100644 --- a/cc/paint/transfer_cache_entry.cc +++ b/cc/paint/transfer_cache_entry.cc
@@ -4,8 +4,9 @@ #include "cc/paint/transfer_cache_entry.h" +#include <memory> + #include "base/logging.h" -#include "base/memory/ptr_util.h" #include "cc/paint/image_transfer_cache_entry.h" #include "cc/paint/raw_memory_transfer_cache_entry.h" @@ -15,9 +16,9 @@ TransferCacheEntryType type) { switch (type) { case TransferCacheEntryType::kRawMemory: - return base::MakeUnique<ServiceRawMemoryTransferCacheEntry>(); + return std::make_unique<ServiceRawMemoryTransferCacheEntry>(); case TransferCacheEntryType::kImage: - return base::MakeUnique<ServiceImageTransferCacheEntry>(); + return std::make_unique<ServiceImageTransferCacheEntry>(); } NOTREACHED();
diff --git a/cc/resources/display_resource_provider.cc b/cc/resources/display_resource_provider.cc index 795364575..a8ac0338 100644 --- a/cc/resources/display_resource_provider.cc +++ b/cc/resources/display_resource_provider.cc
@@ -71,6 +71,18 @@ } #endif +void DisplayResourceProvider::WaitSyncToken(viz::ResourceId id) { + viz::internal::Resource* resource = GetResource(id); + WaitSyncTokenInternal(resource); +#if defined(OS_ANDROID) + // Now that the resource is synced, we may send it a promotion hint. We could + // sync all |wants_promotion_hint| resources elsewhere, and send 'no' to all + // resources that weren't used. However, there's no real advantage. + if (resource->wants_promotion_hint) + wants_promotion_hints_set_.insert(id); +#endif // OS_ANDROID +} + DisplayResourceProvider::ScopedBatchReturnResources::ScopedBatchReturnResources( DisplayResourceProvider* resource_provider) : resource_provider_(resource_provider) { @@ -328,8 +340,6 @@ #if defined(OS_ANDROID) resource->is_backed_by_surface_texture = it->is_backed_by_surface_texture; resource->wants_promotion_hint = it->wants_promotion_hint; - if (resource->wants_promotion_hint) - wants_promotion_hints_set_.insert(local_id); #endif } resource->child_id = child;
diff --git a/cc/resources/display_resource_provider.h b/cc/resources/display_resource_provider.h index b34c938..093629f2 100644 --- a/cc/resources/display_resource_provider.h +++ b/cc/resources/display_resource_provider.h
@@ -35,6 +35,8 @@ const OverlayCandidateList::PromotionHintInfoMap& promotion_hints); #endif + void WaitSyncToken(viz::ResourceId id); + // The following lock classes are part of the DisplayResourceProvider API and // are needed to read the resource contents. The user must ensure that they // only use GL locks on GL resources, etc, and this is enforced by assertions.
diff --git a/cc/resources/resource_provider.cc b/cc/resources/resource_provider.cc index aea9471..9623b794 100644 --- a/cc/resources/resource_provider.cc +++ b/cc/resources/resource_provider.cc
@@ -979,10 +979,6 @@ } } -void ResourceProvider::WaitSyncToken(viz::ResourceId id) { - WaitSyncTokenInternal(GetResource(id)); -} - void ResourceProvider::WaitSyncTokenInternal( viz::internal::Resource* resource) { DCHECK(resource);
diff --git a/cc/resources/resource_provider.h b/cc/resources/resource_provider.h index 7157b0a..dee3fca 100644 --- a/cc/resources/resource_provider.h +++ b/cc/resources/resource_provider.h
@@ -319,9 +319,6 @@ size_t CountPromotionHintRequestsForTesting(); #endif - // TODO(danakj): Move to DisplayResourceProvider. - void WaitSyncToken(viz::ResourceId id); - static GLint GetActiveTextureUnit(gpu::gles2::GLES2Interface* gl); static gpu::SyncToken GenerateSyncTokenHelper(gpu::gles2::GLES2Interface* gl);
diff --git a/cc/resources/resource_provider_unittest.cc b/cc/resources/resource_provider_unittest.cc index dd85f137..770b6c61 100644 --- a/cc/resources/resource_provider_unittest.cc +++ b/cc/resources/resource_provider_unittest.cc
@@ -10,13 +10,13 @@ #include <algorithm> #include <map> +#include <memory> #include <set> #include <unordered_map> #include <vector> #include "base/bind.h" #include "base/logging.h" -#include "base/memory/ptr_util.h" #include "base/memory/ref_counted.h" #include "cc/test/test_context_provider.h" #include "cc/test/test_shared_bitmap_manager.h" @@ -797,7 +797,8 @@ EXPECT_FALSE(child_resource_provider_->InUseByConsumer(id3)); { - child_resource_provider_->WaitSyncToken(id1); + // ScopedWriteLockGL will wait for the sync token, which is convenient since + // |child_resource_provider_| doesn't expose that. ResourceProvider::ScopedWriteLockGL lock(child_resource_provider_.get(), id1); ASSERT_NE(0U, lock.GetTexture()); @@ -805,7 +806,7 @@ // Ensure copying to resource doesn't fail. child_resource_provider_->CopyToResource(id2, data2, size); { - child_resource_provider_->WaitSyncToken(id2); + // ScopedWriteLockGL will wait for the sync token. ResourceProvider::ScopedWriteLockGL lock(child_resource_provider_.get(), id2); ASSERT_NE(0U, lock.GetTexture()); @@ -913,11 +914,19 @@ resource_provider_->GetChildToParentMap(child_id); viz::ResourceId mapped_id1 = resource_map[list[0].id]; viz::ResourceId mapped_id2 = resource_map[list[1].id]; + + // The promotion hints should not be recorded until after we wait. This is + // because we can't notify them until they're synchronized, and we choose to + // ignore unwaited resources rather than send them a "no" hint. If they end + // up in the request set before we wait, then the attempt to notify them wil; + // DCHECK when we try to lock them for reading in SendPromotionHints. + EXPECT_EQ(0u, resource_provider_->CountPromotionHintRequestsForTesting()); { resource_provider_->WaitSyncToken(mapped_id1); DisplayResourceProvider::ScopedReadLockGL lock(resource_provider_.get(), mapped_id1); } + EXPECT_EQ(1u, resource_provider_->CountPromotionHintRequestsForTesting()); EXPECT_EQ(list[0].mailbox_holder.sync_token, context3d_->last_waited_sync_token()); @@ -941,8 +950,6 @@ EXPECT_FALSE(resource_provider_->IsBackedBySurfaceTexture(mapped_id2)); EXPECT_FALSE(resource_provider_->WantsPromotionHintForTesting(mapped_id2)); - EXPECT_EQ(1u, resource_provider_->CountPromotionHintRequestsForTesting()); - // ResourceProvider maintains a set of promotion hint requests that should be // cleared when resources are deleted. resource_provider_->DeclareUsedResourcesFromChild(child_id, @@ -1177,7 +1184,8 @@ EXPECT_EQ(1u, returned_to_child.size()); child_resource_provider_->ReceiveReturnsFromParent(returned_to_child); - child_resource_provider_->WaitSyncToken(id1); + // No need to wait for the sync token here -- it will be returned to the + // client on delete. EXPECT_EQ(1u, child_resource_provider_->num_resources()); child_resource_provider_->DeleteResource(id1); EXPECT_EQ(0u, child_resource_provider_->num_resources()); @@ -3151,7 +3159,7 @@ return; auto context_owned = - base::MakeUnique<StrictMock<AllocationTrackingContext3D>>(); + std::make_unique<StrictMock<AllocationTrackingContext3D>>(); auto* context = context_owned.get(); context->set_support_texture_storage(true); context->set_support_texture_usage(true);
diff --git a/cc/tiles/gpu_image_decode_cache_unittest.cc b/cc/tiles/gpu_image_decode_cache_unittest.cc index 369dd0f8..6c72e94f 100644 --- a/cc/tiles/gpu_image_decode_cache_unittest.cc +++ b/cc/tiles/gpu_image_decode_cache_unittest.cc
@@ -4,7 +4,8 @@ #include "cc/tiles/gpu_image_decode_cache.h" -#include "base/memory/ptr_util.h" +#include <memory> + #include "cc/paint/draw_image.h" #include "cc/paint/paint_image_builder.h" #include "cc/test/fake_paint_image_generator.h" @@ -171,8 +172,8 @@ static scoped_refptr<DiscardableTextureMockContextProvider> Create( FakeDiscardableManager* discardable_manager) { return new DiscardableTextureMockContextProvider( - base::MakeUnique<FakeDiscardableGLES2Interface>(discardable_manager), - base::MakeUnique<FakeDiscardableGLES2Interface>(discardable_manager), + std::make_unique<FakeDiscardableGLES2Interface>(discardable_manager), + std::make_unique<FakeDiscardableGLES2Interface>(discardable_manager), TestWebGraphicsContext3D::Create()); }
diff --git a/cc/trees/image_animation_controller_unittest.cc b/cc/trees/image_animation_controller_unittest.cc index c4db878b..5214058 100644 --- a/cc/trees/image_animation_controller_unittest.cc +++ b/cc/trees/image_animation_controller_unittest.cc
@@ -4,7 +4,8 @@ #include "cc/trees/image_animation_controller.h" -#include "base/memory/ptr_util.h" +#include <memory> + #include "base/run_loop.h" #include "base/test/gtest_util.h" #include "base/threading/thread_task_runner_handle.h" @@ -76,7 +77,7 @@ base::Closure invalidation_callback = base::Bind(&ImageAnimationControllerTest::RequestInvalidation, base::Unretained(this)); - controller_ = base::MakeUnique<ImageAnimationController>( + controller_ = std::make_unique<ImageAnimationController>( task_runner_.get(), invalidation_callback); now_ += base::TimeDelta::FromSeconds(10); }
diff --git a/chrome/android/java/res/drawable/ic_check_googblue_24dp_animated.xml b/chrome/android/java/res/drawable/ic_check_googblue_24dp_animated.xml new file mode 100644 index 0000000..d020b19 --- /dev/null +++ b/chrome/android/java/res/drawable/ic_check_googblue_24dp_animated.xml
@@ -0,0 +1,45 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- 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. --> + +<animated-vector xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + xmlns:aapt="http://schemas.android.com/aapt" + tools:targetApi="21"> + + <aapt:attr name="android:drawable"> + <vector + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + + <!-- This path is calculated from the icon ic_check_googblue_24dp. --> + <path + android:name="ic_check" + android:pathData="M4.12,12.705 l4.88,4.88 l11.295,-11.29" + android:strokeColor="#4285F4" + android:strokeWidth="2" /> + </vector> + </aapt:attr> + + <target android:name="ic_check" > + <aapt:attr name="android:animation"> + <set> + <objectAnimator + android:duration="200" + android:propertyName="pathData" + android:valueFrom="M4.12,12.705 l0,0 l0,0" + android:valueTo="M4.12,12.705 l4.88,4.88 l0,0" + android:valueType="pathType"/> + <objectAnimator + android:duration="200" + android:propertyName="pathData" + android:valueFrom="M4.12,12.705 l4.88,4.88 l0,0" + android:valueTo="M4.12,12.705 l4.88,4.88 l11.295,-11.29" + android:valueType="pathType"/> + </set> + </aapt:attr> + </target> +</animated-vector> \ No newline at end of file
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkItemsAdapter.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkItemsAdapter.java index b8a60a2..a207ff9 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkItemsAdapter.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkItemsAdapter.java
@@ -73,6 +73,12 @@ public void bookmarkNodeRemoved(BookmarkItem parent, int oldIndex, BookmarkItem node, boolean isDoingExtensiveChanges) { assert mDelegate != null; + + if (mDelegate.getCurrentState() == BookmarkUIState.STATE_SEARCHING + && TextUtils.equals(mSearchText, EMPTY_QUERY)) { + mDelegate.closeSearchUI(); + } + if (node.isFolder()) { mDelegate.notifyStateChange(BookmarkItemsAdapter.this); } else {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkManager.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkManager.java index 4c3e43b8..8e6615f6 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkManager.java
@@ -410,15 +410,7 @@ @Override public void closeSearchUI() { - mSelectableListLayout.onEndSearch(); - - // Pop the search state off the stack. - mStateStack.pop(); - - // Set the state back to the folder that was previously being viewed. Listeners, including - // the BookmarkItemsAdapter, will be notified of the change and the list of bookmarks will - // be updated. - setState(mStateStack.pop()); + mToolbar.hideSearchView(); } @Override @@ -456,7 +448,15 @@ @Override public void onEndSearch() { - closeSearchUI(); + mSelectableListLayout.onEndSearch(); + + // Pop the search state off the stack. + mStateStack.pop(); + + // Set the state back to the folder that was previously being viewed. Listeners, including + // the BookmarkItemsAdapter, will be notified of the change and the list of bookmarks will + // be updated. + setState(mStateStack.pop()); } // Testing methods @@ -466,6 +466,11 @@ return mToolbar; } + @VisibleForTesting + public BookmarkUndoController getUndoControllerForTests() { + return mUndoController; + } + /** * @param preventLoading Whether to prevent the bookmark model from fully loading for testing. */
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchBarBannerControl.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchBarBannerControl.java index aa8767e..7dd5d892 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchBarBannerControl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchBarBannerControl.java
@@ -4,6 +4,8 @@ package org.chromium.chrome.browser.compositor.bottombar.contextualsearch; +import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; import android.content.Context; import android.view.ViewGroup; @@ -31,6 +33,11 @@ private boolean mIsVisible; /** + * Whether the Bar Banner is in the process of hiding. + */ + private boolean mIsHiding; + + /** * The height of the Bar Banner, in pixels. */ private float mHeightPx; @@ -111,15 +118,18 @@ void hide() { if (!mIsVisible) return; - mIsVisible = false; - mHeightPx = 0.f; + if (mHeightPx == 0.f) { + mIsVisible = false; + } else { + animateDisappearance(); + } } /** * @return The height of the Bar Banner when the Panel is the peeked state. */ float getHeightPeekingPx() { - return mIsVisible ? getPaddedHeightPx() : 0.f; + return (!isVisible() || mIsHiding) ? 0.f : getPaddedHeightPx(); } /** Calculates the padded height of the bar banner if it has not been calculated before. @@ -204,7 +214,7 @@ * @param percentage The completion percentage. */ public void onUpdateFromCloseToPeek(float percentage) { - if (!isVisible()) return; + if (!isVisible() || mIsHiding) return; mHeightPx = Math.round(getPaddedHeightPx()); } @@ -215,7 +225,7 @@ * @param percentage The completion percentage. */ public void onUpdateFromPeekToExpand(float percentage) { - if (!isVisible()) return; + if (!isVisible() || mIsHiding) return; mHeightPx = Math.round(MathUtils.interpolate(getPaddedHeightPx(), 0.f, percentage)); mTextOpacity = MathUtils.interpolate(1.f, 0.f, percentage); @@ -227,7 +237,7 @@ * @param percentage The completion percentage. */ public void onUpdateFromExpandToMaximize(float percentage) { - if (!isVisible()) return; + if (!isVisible() || mIsHiding) return; mHeightPx = 0.f; mTextOpacity = 0.f; @@ -262,4 +272,32 @@ OverlayPanelAnimation.BASE_ANIMATION_DURATION_MS, listener); appearance.start(); } + + /** + * Animates the Bar Banner disappearance. + */ + private void animateDisappearance() { + mIsHiding = true; + CompositorAnimator disappearance = + CompositorAnimator.ofFloat(mOverlayPanel.getAnimationHandler(), 1.f, 0.f, + OverlayPanelAnimation.BASE_ANIMATION_DURATION_MS, null); + disappearance.addUpdateListener(new AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(CompositorAnimator animator) { + if (isVisible()) { + float percentage = animator.getAnimatedFraction(); + mHeightPx = MathUtils.interpolate(getPaddedHeightPx(), 0.f, percentage); + } + } + }); + disappearance.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + mHeightPx = 0.f; + mIsHiding = false; + hide(); + } + }); + disappearance.start(); + } } \ No newline at end of file
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchIPH.java b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchIPH.java index 5b706f8..66cd6ce 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchIPH.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchIPH.java
@@ -29,7 +29,7 @@ private boolean mIsShowing; /** - * Constructs the helper class and initializes string ids according to featureName. + * Constructs the helper class. */ ContextualSearchIPH() {} @@ -55,7 +55,13 @@ */ void beforePanelShown(boolean wasActivatedByTap, boolean isTapSupported, Profile profile) { if (!wasActivatedByTap && isTapSupported) { - maybeShow(FeatureConstants.CONTEXTUAL_SEARCH_PROMOTE_TAP_FEATURE, profile); + if (mIsShowing + && mFeatureName.equals( + FeatureConstants.CONTEXTUAL_SEARCH_PROMOTE_TAP_FEATURE)) { + dismiss(profile); + } else { + maybeShow(FeatureConstants.CONTEXTUAL_SEARCH_PROMOTE_TAP_FEATURE, profile); + } } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/ui/DownloadItemView.java b/chrome/android/java/src/org/chromium/chrome/browser/download/ui/DownloadItemView.java index fcf7671..8a1a300 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/ui/DownloadItemView.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/ui/DownloadItemView.java
@@ -272,8 +272,9 @@ } else { mIconView.setBackgroundColor(mIconBackgroundColorSelected); } - mIconView.setImageResource(R.drawable.ic_check_googblue_24dp); + mIconView.setImageDrawable(mCheckDrawable); mIconView.setTint(mCheckedIconForegroundColorList); + mCheckDrawable.start(); } else if (mThumbnailBitmap != null) { assert !mThumbnailBitmap.isRecycled(); mIconView.setBackground(null);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/feedback/SystemInfoFeedbackSource.java b/chrome/android/java/src/org/chromium/chrome/browser/feedback/SystemInfoFeedbackSource.java index 3472130c..679ee6d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/feedback/SystemInfoFeedbackSource.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/feedback/SystemInfoFeedbackSource.java
@@ -12,6 +12,7 @@ import org.chromium.base.ApiCompatibilityUtils; import org.chromium.base.CollectionUtil; +import org.chromium.base.LocaleUtils; import org.chromium.base.annotations.JNINamespace; import java.io.File; @@ -96,7 +97,8 @@ "Available Memory (MB)", Integer.toString(nativeGetAvailableMemoryMB())), Pair.create("Total Memory (MB)", Integer.toString(nativeGetTotalMemoryMB())), Pair.create("GPU Vendor", nativeGetGpuVendor()), - Pair.create("GPU Model", nativeGetGpuModel())); + Pair.create("GPU Model", nativeGetGpuModel()), + Pair.create("UI Locale", LocaleUtils.getDefaultLocaleString())); if (isReady()) { Long availSpace = mStorageTask.getAvailableSpaceMB();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/selection/SelectableItemView.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/selection/SelectableItemView.java index 144d4ff..64a5847 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/widget/selection/SelectableItemView.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/selection/SelectableItemView.java
@@ -8,6 +8,8 @@ import android.content.res.ColorStateList; import android.graphics.drawable.Drawable; import android.support.annotation.Nullable; +import android.support.annotation.VisibleForTesting; +import android.support.graphics.drawable.AnimatedVectorDrawableCompat; import android.util.AttributeSet; import android.view.View; import android.view.View.OnClickListener; @@ -35,6 +37,7 @@ OnClickListener, OnLongClickListener, SelectionObserver<E> { protected final int mDefaultLevel; protected final int mSelectedLevel; + protected final AnimatedVectorDrawableCompat mCheckDrawable; protected TintedImageView mIconView; protected TextView mTitleView; @@ -55,6 +58,8 @@ ApiCompatibilityUtils.getColorStateList(getResources(), R.color.white_mode_tint); mDefaultLevel = getResources().getInteger(R.integer.list_item_level_default); mSelectedLevel = getResources().getInteger(R.integer.list_item_level_selected); + mCheckDrawable = AnimatedVectorDrawableCompat.create( + getContext(), R.drawable.ic_check_googblue_24dp_animated); } /** @@ -208,8 +213,9 @@ if (isChecked()) { mIconView.getBackground().setLevel(mSelectedLevel); - mIconView.setImageResource(R.drawable.ic_check_googblue_24dp); + mIconView.setImageDrawable(mCheckDrawable); mIconView.setTint(mIconColorList); + mCheckDrawable.start(); } else { mIconView.getBackground().setLevel(mDefaultLevel); mIconView.setImageDrawable(mIconDrawable); @@ -236,4 +242,9 @@ * that case. */ protected abstract void onClick(); + + @VisibleForTesting + public void endAnimationsForTests() { + mCheckDrawable.stop(); + } }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkTest.java index eec89281..834ce591 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkTest.java
@@ -319,6 +319,62 @@ @Test @MediumTest + public void testSearchBookmarks_Delete() throws Exception { + BookmarkPromoHeader.forcePromoStateForTests(BookmarkPromoHeader.PromoState.PROMO_NONE); + BookmarkId testFolder = addFolder(TEST_FOLDER_TITLE); + BookmarkId testBookmark = addBookmark(TEST_PAGE_TITLE_GOOGLE, mTestPage); + addBookmark(TEST_PAGE_TITLE_FOO, mTestPageFoo); + openBookmarkManager(); + + BookmarkItemsAdapter adapter = ((BookmarkItemsAdapter) mItemsContainer.getAdapter()); + BookmarkManager manager = (BookmarkManager) adapter.getDelegateForTesting(); + + Assert.assertEquals(BookmarkUIState.STATE_FOLDER, manager.getCurrentState()); + assertBookmarkItems("Wrong number of items before starting search.", 3, adapter, manager); + + // Start searching without entering a query. + ThreadUtils.runOnUiThreadBlocking(manager::openSearchUI); + Assert.assertEquals(BookmarkUIState.STATE_SEARCHING, manager.getCurrentState()); + + // Select the folder and delete it. + ThreadUtils.runOnUiThreadBlocking( + () -> manager.getSelectionDelegate().toggleSelectionForItem(adapter.getItem(0))); + ThreadUtils.runOnUiThreadBlocking( + () + -> manager.getToolbarForTests().onMenuItemClick( + manager.getToolbarForTests().getMenu().findItem( + R.id.selection_mode_delete_menu_id))); + + // Search should be exited and the folder should be gone. + Assert.assertEquals(BookmarkUIState.STATE_FOLDER, manager.getCurrentState()); + assertBookmarkItems("Wrong number of items before starting search.", 2, adapter, manager); + + // Start searching, enter a query. + ThreadUtils.runOnUiThreadBlocking(manager::openSearchUI); + Assert.assertEquals(BookmarkUIState.STATE_SEARCHING, manager.getCurrentState()); + searchBookmarks("Google"); + assertBookmarkItems( + "Wrong number of items after searching.", 1, mItemsContainer.getAdapter(), manager); + + // Remove the bookmark. + removeBookmark(testBookmark); + + // The user should still be searching, and the bookmark should be gone. + Assert.assertEquals(BookmarkUIState.STATE_SEARCHING, manager.getCurrentState()); + assertBookmarkItems( + "Wrong number of items after searching.", 0, mItemsContainer.getAdapter(), manager); + + // Undo the deletion. + ThreadUtils.runOnUiThreadBlocking(() -> manager.getUndoControllerForTests().onAction(null)); + + // The user should still be searching, and the bookmark should reappear. + Assert.assertEquals(BookmarkUIState.STATE_SEARCHING, manager.getCurrentState()); + assertBookmarkItems( + "Wrong number of items after searching.", 1, mItemsContainer.getAdapter(), manager); + } + + @Test + @MediumTest @Feature({"RenderTest"}) public void testBookmarkFolderIcon() throws Exception { BookmarkPromoHeader.forcePromoStateForTests(BookmarkPromoHeader.PromoState.PROMO_NONE); @@ -331,9 +387,11 @@ mRenderTestRule.render(manager.getView(), "bookmark_manager_one_folder"); ThreadUtils.runOnUiThreadBlocking(() -> { - manager.getRecyclerView() - .findViewHolderForAdapterPosition(0) - .itemView.performLongClick(); + BookmarkRow itemView = (BookmarkRow) manager.getRecyclerView() + .findViewHolderForAdapterPosition(0) + .itemView; + itemView.performLongClick(); + itemView.endAnimationsForTests(); manager.getToolbarForTests().endAnimationsForTesting(); });
diff --git a/chrome/app/resources/locale_settings_chromiumos.grd b/chrome/app/resources/locale_settings_chromiumos.grd index 8e2f0e8..b0c2a3e 100644 --- a/chrome/app/resources/locale_settings_chromiumos.grd +++ b/chrome/app/resources/locale_settings_chromiumos.grd
@@ -155,19 +155,19 @@ <!-- The default value for |WebPreference::standard_font_family_map| for Arabic script. --> <message name="IDS_STANDARD_FONT_FAMILY_ARABIC" use_name_for_id="true"> - Noto Naskh Arabic UI + Noto Sans Arabic UI </message> <!-- The default value for |WebPreference::serif_font_family_map| for Arabic script. --> <message name="IDS_SERIF_FONT_FAMILY_ARABIC" use_name_for_id="true"> - Noto Kufi Arabic + Noto Naskh Arabic </message> <!-- The default value for |WebPreference::sans_serif_font_family_map| for Arabic script. --> <message name="IDS_SANS_SERIF_FONT_FAMILY_ARABIC" use_name_for_id="true"> - Noto Naskh Arabic UI + Noto Sans Arabic UI </message> <!-- The default value for |WebPreference::standard_font_family_map| for
diff --git a/chrome/app/resources/locale_settings_google_chromeos.grd b/chrome/app/resources/locale_settings_google_chromeos.grd index d140589..ee2d0615 100644 --- a/chrome/app/resources/locale_settings_google_chromeos.grd +++ b/chrome/app/resources/locale_settings_google_chromeos.grd
@@ -155,19 +155,19 @@ <!-- The default value for |WebPreference::standard_font_family_map| for Arabic script. --> <message name="IDS_STANDARD_FONT_FAMILY_ARABIC" use_name_for_id="true"> - Noto Naskh Arabic UI + Noto Sans Arabic UI </message> <!-- The default value for |WebPreference::serif_font_family_map| for Arabic script. --> <message name="IDS_SERIF_FONT_FAMILY_ARABIC" use_name_for_id="true"> - Noto Kufi Arabic + Noto Naskh Arabic </message> <!-- The default value for |WebPreference::sans_serif_font_family_map| for Arabic script. --> <message name="IDS_SANS_SERIF_FONT_FAMILY_ARABIC" use_name_for_id="true"> - Noto Naskh Arabic UI + Noto Sans Arabic UI </message> <!-- The default value for |WebPreference::standard_font_family_map| for
diff --git a/chrome/browser/certificate_manager_model.cc b/chrome/browser/certificate_manager_model.cc index c9e9c827..14f7796 100644 --- a/chrome/browser/certificate_manager_model.cc +++ b/chrome/browser/certificate_manager_model.cc
@@ -121,7 +121,7 @@ cert_db_->ListModules(&modules, false); DVLOG(1) << "refresh waiting for unlocking..."; chrome::UnlockSlotsIfNecessary( - std::move(modules), chrome::kCryptoModulePasswordListCerts, + std::move(modules), kCryptoModulePasswordListCerts, net::HostPortPair(), // unused. NULL, // TODO(mattm): supply parent window. base::Bind(&CertificateManagerModel::RefreshSlotsUnlocked,
diff --git a/chrome/browser/chromeos/login/lock/screen_locker.h b/chrome/browser/chromeos/login/lock/screen_locker.h index 8755614..791d3b6 100644 --- a/chrome/browser/chromeos/login/lock/screen_locker.h +++ b/chrome/browser/chromeos/login/lock/screen_locker.h
@@ -109,6 +109,7 @@ // Returns the default instance if it has been created. static ScreenLocker* default_screen_locker() { return screen_locker_; } + // Returns true if the lock UI has been confirmed as displayed. bool locked() const { return locked_; } // Initialize and show the screen locker.
diff --git a/chrome/browser/chromeos/preferences_chromeos_browsertest.cc b/chrome/browser/chromeos/preferences_chromeos_browsertest.cc index fae576e..3c59ca5 100644 --- a/chrome/browser/chromeos/preferences_chromeos_browsertest.cc +++ b/chrome/browser/chromeos/preferences_chromeos_browsertest.cc
@@ -24,7 +24,6 @@ #include "chrome/browser/chromeos/settings/cros_settings.h" #include "chrome/browser/chromeos/settings/stub_cros_settings_provider.h" #include "chrome/browser/chromeos/system/fake_input_device_settings.h" -#include "chrome/browser/ui/ash/multi_user/multi_user_window_manager_chromeos.h" #include "chrome/browser/ui/browser.h" #include "chrome/common/pref_names.h" #include "chrome/test/base/in_process_browser_test.h" @@ -134,15 +133,6 @@ prefs->GetBoolean(prefs::kPrimaryMouseButtonRight)); } - void DisableAnimations() { - // Disable animations for user transitions. - MultiUserWindowManagerChromeOS* manager = - static_cast<MultiUserWindowManagerChromeOS*>( - MultiUserWindowManager::GetInstance()); - manager->SetAnimationSpeedForTest( - MultiUserWindowManagerChromeOS::ANIMATION_SPEED_DISABLED); - } - std::vector<AccountId> test_users_; private: @@ -213,8 +203,7 @@ chromeos::StartupUtils::MarkOobeCompleted(); } -// This test is flaking both with and without mash. http://crbug.com/787050 -IN_PROC_BROWSER_TEST_F(PreferencesTest, DISABLED_MultiProfiles) { +IN_PROC_BROWSER_TEST_F(PreferencesTest, MultiProfiles) { user_manager::UserManager* user_manager = user_manager::UserManager::Get(); // Add first user and init its preferences. Check that corresponding @@ -230,7 +219,6 @@ // Add second user and init its prefs with different values. UserAddingScreen::Get()->Start(); content::RunAllPendingInMessageLoop(); - DisableAnimations(); AddUser(test_users_[1].GetUserEmail()); content::RunAllPendingInMessageLoop(); const user_manager::User* user2 = user_manager->FindUser(test_users_[1]);
diff --git a/chrome/browser/component_updater/sw_reporter_installer_win.cc b/chrome/browser/component_updater/sw_reporter_installer_win.cc index c7c05a7..f511b4b7 100644 --- a/chrome/browser/component_updater/sw_reporter_installer_win.cc +++ b/chrome/browser/component_updater/sw_reporter_installer_win.cc
@@ -185,8 +185,7 @@ const base::Version& version, std::unique_ptr<base::DictionaryValue> manifest, const SwReporterRunner& reporter_runner, - SwReporterInvocationType invocation_type, - OnReporterSequenceDone on_sequence_done) { + SwReporterInvocationType invocation_type) { const base::ListValue* parameter_list = nullptr; // Allow an empty or missing launch_params list, but log an error if @@ -212,14 +211,12 @@ .WithSupportedBehaviours( SwReporterInvocation::BEHAVIOURS_ENABLED_BY_DEFAULT)}); reporter_runner.Run(invocation_type, - SwReporterInvocationSequence( - version, invocations, std::move(on_sequence_done))); + SwReporterInvocationSequence(version, invocations)); return; } safe_browsing::SwReporterInvocationSequence invocations( - version, SwReporterInvocationSequence::Queue(), - std::move(on_sequence_done)); + version, SwReporterInvocationSequence::Queue()); for (const auto& iter : *parameter_list) { const base::DictionaryValue* invocation_params = nullptr; if (!iter.GetAsDictionary(&invocation_params)) { @@ -293,11 +290,8 @@ SwReporterInstallerPolicy::SwReporterInstallerPolicy( const SwReporterRunner& reporter_runner, - SwReporterInvocationType invocation_type, - OnReporterSequenceDone on_sequence_done) - : reporter_runner_(reporter_runner), - invocation_type_(invocation_type), - on_sequence_done_(std::move(on_sequence_done)) {} + SwReporterInvocationType invocation_type) + : reporter_runner_(reporter_runner), invocation_type_(invocation_type) {} SwReporterInstallerPolicy::~SwReporterInstallerPolicy() {} @@ -331,7 +325,7 @@ DCHECK_CURRENTLY_ON(content::BrowserThread::UI); const base::FilePath exe_path(install_dir.Append(kSwReporterExeName)); RunSwReporters(exe_path, version, std::move(manifest), reporter_runner_, - invocation_type_, std::move(on_sequence_done_)); + invocation_type_); } base::FilePath SwReporterInstallerPolicy::GetRelativeInstallDir() const { @@ -379,7 +373,6 @@ void RegisterSwReporterComponentWithParams( safe_browsing::SwReporterInvocationType invocation_type, - OnReporterSequenceDone on_sequence_done, ComponentUpdateService* cus) { // Check if we have information from Cleaner and record UMA statistics. base::string16 cleaner_key_name( @@ -457,17 +450,13 @@ // Install the component. auto installer = base::MakeRefCounted<ComponentInstaller>( std::make_unique<SwReporterInstallerPolicy>( - base::Bind(&RunSwReportersAfterStartup), invocation_type, - std::move(on_sequence_done))); + base::BindRepeating(&RunSwReportersAfterStartup), invocation_type)); installer->Register(cus, base::OnceClosure()); } void RegisterSwReporterComponent(ComponentUpdateService* cus) { - // This is called during start-up and there is no pending action to be - // performed once done. Because of that, the on sequence done callback - // is defined as a no-op. RegisterSwReporterComponentWithParams(SwReporterInvocationType::kPeriodicRun, - OnReporterSequenceDone(), cus); + cus); } void RegisterPrefsForSwReporter(PrefRegistrySimple* registry) {
diff --git a/chrome/browser/component_updater/sw_reporter_installer_win.h b/chrome/browser/component_updater/sw_reporter_installer_win.h index dc5b0e4..9f45273 100644 --- a/chrome/browser/component_updater/sw_reporter_installer_win.h +++ b/chrome/browser/component_updater/sw_reporter_installer_win.h
@@ -55,11 +55,9 @@ class SwReporterInstallerPolicy : public ComponentInstallerPolicy { public: - // Note: |on_sequence_done| will be invoked on the UI thread. SwReporterInstallerPolicy( const SwReporterRunner& reporter_runner, - safe_browsing::SwReporterInvocationType invocation_type, - safe_browsing::OnReporterSequenceDone on_sequence_done); + safe_browsing::SwReporterInvocationType invocation_type); ~SwReporterInstallerPolicy() override; // ComponentInstallerPolicy implementation. @@ -87,21 +85,14 @@ const safe_browsing::SwReporterInvocationType invocation_type_; - // The action to be called on the first time the invocation sequence - // runs. - safe_browsing::OnReporterSequenceDone on_sequence_done_; - DISALLOW_COPY_AND_ASSIGN(SwReporterInstallerPolicy); }; // Installs the SwReporter component and runs the reporter once it's available. // Once ready, this may trigger either a periodic or a user-initiated run of -// the reporter, depending on |invocation_type|. Once the last invocation -// finishes, |on_sequence_done| is called with a boolean variable indicating if -// the run succeeded. +// the reporter, depending on |invocation_type|. void RegisterSwReporterComponentWithParams( safe_browsing::SwReporterInvocationType invocation_type, - safe_browsing::OnReporterSequenceDone on_sequence_done, ComponentUpdateService* cus); // Call once during startup to make the component update service aware of the
diff --git a/chrome/browser/component_updater/sw_reporter_installer_win_unittest.cc b/chrome/browser/component_updater/sw_reporter_installer_win_unittest.cc index 28cd7c19..7d40382 100644 --- a/chrome/browser/component_updater/sw_reporter_installer_win_unittest.cc +++ b/chrome/browser/component_updater/sw_reporter_installer_win_unittest.cc
@@ -37,7 +37,6 @@ constexpr char kExperimentTag[] = "experiment_tag"; constexpr char kMissingTag[] = "missing_tag"; -using safe_browsing::OnReporterSequenceDone; using safe_browsing::SwReporterInvocation; using safe_browsing::SwReporterInvocationResult; using safe_browsing::SwReporterInvocationSequence; @@ -239,8 +238,7 @@ SwReporterInvocationType::kUserInitiatedWithLogsAllowed)); TEST_P(SwReporterInstallerTest, MissingManifest) { - SwReporterInstallerPolicy policy(launched_callback_, invocation_type_, - OnReporterSequenceDone()); + SwReporterInstallerPolicy policy(launched_callback_, invocation_type_); ExpectEmptyAttributes(policy); policy.ComponentReady(default_version_, default_path_, std::make_unique<base::DictionaryValue>()); @@ -248,8 +246,7 @@ } TEST_P(SwReporterInstallerTest, MissingTag) { - SwReporterInstallerPolicy policy(launched_callback_, invocation_type_, - OnReporterSequenceDone()); + SwReporterInstallerPolicy policy(launched_callback_, invocation_type_); CreateFeatureWithoutTag(); ExpectAttributesWithTag(policy, kMissingTag); histograms_.ExpectUniqueSample(kErrorHistogramName, @@ -257,8 +254,7 @@ } TEST_P(SwReporterInstallerTest, InvalidTag) { - SwReporterInstallerPolicy policy(launched_callback_, invocation_type_, - OnReporterSequenceDone()); + SwReporterInstallerPolicy policy(launched_callback_, invocation_type_); CreateFeatureWithTag("tag with invalid whitespace chars"); ExpectAttributesWithTag(policy, kMissingTag); histograms_.ExpectUniqueSample(kErrorHistogramName, @@ -266,8 +262,7 @@ } TEST_P(SwReporterInstallerTest, TagTooLong) { - SwReporterInstallerPolicy policy(launched_callback_, invocation_type_, - OnReporterSequenceDone()); + SwReporterInstallerPolicy policy(launched_callback_, invocation_type_); std::string tag_too_long(500, 'x'); CreateFeatureWithTag(tag_too_long); ExpectAttributesWithTag(policy, kMissingTag); @@ -276,8 +271,7 @@ } TEST_P(SwReporterInstallerTest, EmptyTag) { - SwReporterInstallerPolicy policy(launched_callback_, invocation_type_, - OnReporterSequenceDone()); + SwReporterInstallerPolicy policy(launched_callback_, invocation_type_); CreateFeatureWithTag(""); ExpectAttributesWithTag(policy, kMissingTag); histograms_.ExpectUniqueSample(kErrorHistogramName, @@ -285,15 +279,13 @@ } TEST_P(SwReporterInstallerTest, ValidTag) { - SwReporterInstallerPolicy policy(launched_callback_, invocation_type_, - OnReporterSequenceDone()); + SwReporterInstallerPolicy policy(launched_callback_, invocation_type_); CreateFeatureWithTag(kExperimentTag); ExpectAttributesWithTag(policy, kExperimentTag); } TEST_P(SwReporterInstallerTest, SingleInvocation) { - SwReporterInstallerPolicy policy(launched_callback_, invocation_type_, - OnReporterSequenceDone()); + SwReporterInstallerPolicy policy(launched_callback_, invocation_type_); static constexpr char kTestManifest[] = "{\"launch_params\": [" @@ -331,8 +323,7 @@ } TEST_P(SwReporterInstallerTest, MultipleInvocations) { - SwReporterInstallerPolicy policy(launched_callback_, invocation_type_, - OnReporterSequenceDone()); + SwReporterInstallerPolicy policy(launched_callback_, invocation_type_); static constexpr char kTestManifest[] = "{\"launch_params\": [" @@ -392,8 +383,7 @@ } TEST_P(SwReporterInstallerTest, MissingSuffix) { - SwReporterInstallerPolicy policy(launched_callback_, invocation_type_, - OnReporterSequenceDone()); + SwReporterInstallerPolicy policy(launched_callback_, invocation_type_); static constexpr char kTestManifest[] = "{\"launch_params\": [" @@ -409,8 +399,7 @@ } TEST_P(SwReporterInstallerTest, EmptySuffix) { - SwReporterInstallerPolicy policy(launched_callback_, invocation_type_, - OnReporterSequenceDone()); + SwReporterInstallerPolicy policy(launched_callback_, invocation_type_); static constexpr char kTestManifest[] = "{\"launch_params\": [" @@ -427,8 +416,7 @@ } TEST_P(SwReporterInstallerTest, MissingSuffixAndArgs) { - SwReporterInstallerPolicy policy(launched_callback_, invocation_type_, - OnReporterSequenceDone()); + SwReporterInstallerPolicy policy(launched_callback_, invocation_type_); static constexpr char kTestManifest[] = "{\"launch_params\": [" @@ -443,8 +431,7 @@ } TEST_P(SwReporterInstallerTest, EmptySuffixAndArgs) { - SwReporterInstallerPolicy policy(launched_callback_, invocation_type_, - OnReporterSequenceDone()); + SwReporterInstallerPolicy policy(launched_callback_, invocation_type_); static constexpr char kTestManifest[] = "{\"launch_params\": [" @@ -461,8 +448,7 @@ } TEST_P(SwReporterInstallerTest, EmptySuffixAndArgsWithEmptyString) { - SwReporterInstallerPolicy policy(launched_callback_, invocation_type_, - OnReporterSequenceDone()); + SwReporterInstallerPolicy policy(launched_callback_, invocation_type_); static constexpr char kTestManifest[] = "{\"launch_params\": [" @@ -479,8 +465,7 @@ } TEST_P(SwReporterInstallerTest, MissingArguments) { - SwReporterInstallerPolicy policy(launched_callback_, invocation_type_, - OnReporterSequenceDone()); + SwReporterInstallerPolicy policy(launched_callback_, invocation_type_); static constexpr char kTestManifest[] = "{\"launch_params\": [" @@ -496,8 +481,7 @@ } TEST_P(SwReporterInstallerTest, EmptyArguments) { - SwReporterInstallerPolicy policy(launched_callback_, invocation_type_, - OnReporterSequenceDone()); + SwReporterInstallerPolicy policy(launched_callback_, invocation_type_); static constexpr char kTestManifest[] = "{\"launch_params\": [" @@ -514,8 +498,7 @@ } TEST_P(SwReporterInstallerTest, EmptyArgumentsWithEmptyString) { - SwReporterInstallerPolicy policy(launched_callback_, invocation_type_, - OnReporterSequenceDone()); + SwReporterInstallerPolicy policy(launched_callback_, invocation_type_); static constexpr char kTestManifest[] = "{\"launch_params\": [" @@ -532,8 +515,7 @@ } TEST_P(SwReporterInstallerTest, EmptyManifest) { - SwReporterInstallerPolicy policy(launched_callback_, invocation_type_, - OnReporterSequenceDone()); + SwReporterInstallerPolicy policy(launched_callback_, invocation_type_); static constexpr char kTestManifest[] = "{}"; policy.ComponentReady( @@ -543,8 +525,7 @@ } TEST_P(SwReporterInstallerTest, EmptyLaunchParams) { - SwReporterInstallerPolicy policy(launched_callback_, invocation_type_, - OnReporterSequenceDone()); + SwReporterInstallerPolicy policy(launched_callback_, invocation_type_); static constexpr char kTestManifest[] = "{\"launch_params\": []}"; policy.ComponentReady( @@ -554,8 +535,7 @@ } TEST_P(SwReporterInstallerTest, BadSuffix) { - SwReporterInstallerPolicy policy(launched_callback_, invocation_type_, - OnReporterSequenceDone()); + SwReporterInstallerPolicy policy(launched_callback_, invocation_type_); static constexpr char kTestManifest[] = "{\"launch_params\": [" @@ -575,8 +555,7 @@ } TEST_P(SwReporterInstallerTest, SuffixTooLong) { - SwReporterInstallerPolicy policy(launched_callback_, invocation_type_, - OnReporterSequenceDone()); + SwReporterInstallerPolicy policy(launched_callback_, invocation_type_); static constexpr char kTestManifest[] = "{\"launch_params\": [" @@ -599,8 +578,7 @@ } TEST_P(SwReporterInstallerTest, BadTypesInManifest_ArgumentsIsNotAList) { - SwReporterInstallerPolicy policy(launched_callback_, invocation_type_, - OnReporterSequenceDone()); + SwReporterInstallerPolicy policy(launched_callback_, invocation_type_); // This has a string instead of a list for "arguments". static constexpr char kTestManifest[] = @@ -621,8 +599,7 @@ } TEST_P(SwReporterInstallerTest, BadTypesInManifest_InvocationParamsIsNotAList) { - SwReporterInstallerPolicy policy(launched_callback_, invocation_type_, - OnReporterSequenceDone()); + SwReporterInstallerPolicy policy(launched_callback_, invocation_type_); // This has the invocation parameters as direct children of "launch_params", // instead of using a list. @@ -644,8 +621,7 @@ } TEST_P(SwReporterInstallerTest, BadTypesInManifest_SuffixIsAList) { - SwReporterInstallerPolicy policy(launched_callback_, invocation_type_, - OnReporterSequenceDone()); + SwReporterInstallerPolicy policy(launched_callback_, invocation_type_); // This has a list for suffix as well as for arguments. static constexpr char kTestManifest[] = @@ -666,8 +642,7 @@ } TEST_P(SwReporterInstallerTest, BadTypesInManifest_PromptIsNotABoolean) { - SwReporterInstallerPolicy policy(launched_callback_, invocation_type_, - OnReporterSequenceDone()); + SwReporterInstallerPolicy policy(launched_callback_, invocation_type_); // This has an int instead of a bool for prompt. static constexpr char kTestManifest[] = @@ -689,8 +664,7 @@ } TEST_P(SwReporterInstallerTest, BadTypesInManifest_LaunchParamsIsScalar) { - SwReporterInstallerPolicy policy(launched_callback_, invocation_type_, - OnReporterSequenceDone()); + SwReporterInstallerPolicy policy(launched_callback_, invocation_type_); static constexpr char kTestManifest[] = "{\"launch_params\": 0}"; policy.ComponentReady( @@ -704,8 +678,7 @@ } TEST_P(SwReporterInstallerTest, BadTypesInManifest_LaunchParamsIsDict) { - SwReporterInstallerPolicy policy(launched_callback_, invocation_type_, - OnReporterSequenceDone()); + SwReporterInstallerPolicy policy(launched_callback_, invocation_type_); static constexpr char kTestManifest[] = "{\"launch_params\": {}}"; policy.ComponentReady(
diff --git a/chrome/browser/download/chrome_download_manager_delegate.cc b/chrome/browser/download/chrome_download_manager_delegate.cc index 9e21057..1857d94 100644 --- a/chrome/browser/download/chrome_download_manager_delegate.cc +++ b/chrome/browser/download/chrome_download_manager_delegate.cc
@@ -48,7 +48,7 @@ #include "chrome/common/pref_names.h" #include "chrome/common/safe_browsing/file_type_policies.h" #include "chrome/grit/generated_resources.h" -#include "components/download/downloader/in_progress/in_progress_cache.h" +#include "components/download/downloader/in_progress/in_progress_cache_impl.h" #include "components/pref_registry/pref_registry_syncable.h" #include "components/prefs/pref_member.h" #include "components/prefs/pref_service.h" @@ -269,7 +269,7 @@ DCHECK(!profile_->GetPath().empty()); base::FilePath metadata_cache_file = profile_->GetPath().Append(chrome::kDownloadMetadataStoreFilename); - download_metadata_cache_.reset(new download::InProgressCache( + download_metadata_cache_.reset(new download::InProgressCacheImpl( metadata_cache_file, disk_access_task_runner_)); } @@ -549,7 +549,6 @@ } download::InProgressCache* ChromeDownloadManagerDelegate::GetInProgressCache() { - // TODO(crbug.com/778425): Make sure the cache is initialized. DCHECK(download_metadata_cache_ != nullptr); return download_metadata_cache_.get(); }
diff --git a/chrome/browser/download/download_history.cc b/chrome/browser/download/download_history.cc index fb47fa8..de609851 100644 --- a/chrome/browser/download/download_history.cc +++ b/chrome/browser/download/download_history.cc
@@ -315,7 +315,10 @@ ++history_size_; } notifier_.GetManager()->CheckForHistoryFilesRemoval(); - notifier_.GetManager()->PostInitialization(); + + // Indicate that the history db is initialized. + notifier_.GetManager()->PostInitialization( + content::DownloadManager::DOWNLOAD_INITIALIZATION_DEPENDENCY_HISTORY_DB); initial_history_query_complete_ = true; for (Observer& observer : observers_)
diff --git a/chrome/browser/download/download_ui_controller_unittest.cc b/chrome/browser/download/download_ui_controller_unittest.cc index 0df21614..490fc49 100644 --- a/chrome/browser/download/download_ui_controller_unittest.cc +++ b/chrome/browser/download/download_ui_controller_unittest.cc
@@ -330,7 +330,10 @@ EXPECT_CALL(*item, GetOriginalMimeType()); EXPECT_CALL(*manager(), CheckForHistoryFilesRemoval()); - EXPECT_CALL(*manager(), PostInitialization()); + EXPECT_CALL( + *manager(), + PostInitialization(content::DownloadManager:: + DOWNLOAD_INITIALIZATION_DEPENDENCY_HISTORY_DB)); { testing::InSequence s;
diff --git a/chrome/browser/extensions/api/autotest_private/autotest_private_api.cc b/chrome/browser/extensions/api/autotest_private/autotest_private_api.cc index b01bc99..8432002 100644 --- a/chrome/browser/extensions/api/autotest_private/autotest_private_api.cc +++ b/chrome/browser/extensions/api/autotest_private/autotest_private_api.cc
@@ -109,8 +109,12 @@ #if defined(OS_CHROMEOS) const user_manager::UserManager* user_manager = user_manager::UserManager::Get(); + + // default_screen_locker()->locked() is set when the UI is ready, so this + // tells us both views based lockscreen UI and screenlocker are ready. const bool is_screen_locked = - !!chromeos::ScreenLocker::default_screen_locker(); + !!chromeos::ScreenLocker::default_screen_locker() && + chromeos::ScreenLocker::default_screen_locker()->locked(); if (user_manager) { result->SetBoolean("isLoggedIn", user_manager->IsUserLoggedIn());
diff --git a/chrome/browser/extensions/api/cryptotoken_private/OWNERS b/chrome/browser/extensions/api/cryptotoken_private/OWNERS index b79c1b5..0a8ba68 100644 --- a/chrome/browser/extensions/api/cryptotoken_private/OWNERS +++ b/chrome/browser/extensions/api/cryptotoken_private/OWNERS
@@ -1,3 +1,5 @@ agl@chromium.org +mab@chromium.org kpaulhamus@chromium.org arnarb@chromium.org +juanlang@chromium.org
diff --git a/chrome/browser/loader/chrome_resource_dispatcher_host_delegate.cc b/chrome/browser/loader/chrome_resource_dispatcher_host_delegate.cc index 1d0aafb..ef8b495 100644 --- a/chrome/browser/loader/chrome_resource_dispatcher_host_delegate.cc +++ b/chrome/browser/loader/chrome_resource_dispatcher_host_delegate.cc
@@ -926,7 +926,7 @@ if (data_reduction_proxy_io_data && previews_io_data) { previews::PreviewsUserData::Create(url_request, previews_io_data->GeneratePageId()); - if (data_reduction_proxy_io_data->ShouldEnableServerPreviews( + if (data_reduction_proxy_io_data->ShouldAcceptServerPreview( *url_request, previews_io_data)) { previews_state |= content::SERVER_LOFI_ON; previews_state |= content::SERVER_LITE_PAGE_ON;
diff --git a/chrome/browser/net/nqe/ui_network_quality_estimator_service_browsertest.cc b/chrome/browser/net/nqe/ui_network_quality_estimator_service_browsertest.cc index 5bd55116..fd7487af 100644 --- a/chrome/browser/net/nqe/ui_network_quality_estimator_service_browsertest.cc +++ b/chrome/browser/net/nqe/ui_network_quality_estimator_service_browsertest.cc
@@ -173,7 +173,8 @@ net::NetworkChangeNotifier::CONNECTION_ETHERNET) { // Verify that the network ID was written correctly. net::nqe::internal::NetworkID ethernet_network_id( - net::NetworkChangeNotifier::CONNECTION_ETHERNET, std::string()); + net::NetworkChangeNotifier::CONNECTION_ETHERNET, std::string(), + INT32_MIN); EXPECT_EQ(ethernet_network_id, read_prefs.begin()->first); } }
diff --git a/chrome/browser/profiles/profile_io_data.cc b/chrome/browser/profiles/profile_io_data.cc index f03c54f3..ebef091d 100644 --- a/chrome/browser/profiles/profile_io_data.cc +++ b/chrome/browser/profiles/profile_io_data.cc
@@ -980,11 +980,11 @@ base::MakeUnique<chromeos::ClientCertFilterChromeOS>( use_system_key_slot_, username_hash_), base::Bind(&CreateCryptoModuleBlockingPasswordDelegate, - chrome::kCryptoModulePasswordClientAuth))); + kCryptoModulePasswordClientAuth))); #elif defined(USE_NSS_CERTS) return std::unique_ptr<net::ClientCertStore>(new net::ClientCertStoreNSS( base::Bind(&CreateCryptoModuleBlockingPasswordDelegate, - chrome::kCryptoModulePasswordClientAuth))); + kCryptoModulePasswordClientAuth))); #elif defined(OS_WIN) return std::unique_ptr<net::ClientCertStore>(new net::ClientCertStoreWin()); #elif defined(OS_MACOSX)
diff --git a/chrome/browser/resources/cryptotoken/OWNERS b/chrome/browser/resources/cryptotoken/OWNERS index aac50e0..7fc1909d 100644 --- a/chrome/browser/resources/cryptotoken/OWNERS +++ b/chrome/browser/resources/cryptotoken/OWNERS
@@ -1,2 +1 @@ -arnarb@chromium.org -juanlang@chromium.org +file://chrome/browser/extensions/api/cryptotoken_private/OWNERS
diff --git a/chrome/browser/resources/settings/chrome_cleanup_page/chrome_cleanup_page.js b/chrome/browser/resources/settings/chrome_cleanup_page/chrome_cleanup_page.js index caaf5da8..bb612ac 100644 --- a/chrome/browser/resources/settings/chrome_cleanup_page/chrome_cleanup_page.js +++ b/chrome/browser/resources/settings/chrome_cleanup_page/chrome_cleanup_page.js
@@ -9,6 +9,8 @@ */ settings.ChromeCleanupIdleReason = { INITIAL: 'initial', + REPORTER_FOUND_NOTHING: 'reporter_found_nothing', + REPORTER_FAILED: 'reporter_failed', SCANNING_FOUND_NOTHING: 'scanning_found_nothing', SCANNING_FAILED: 'scanning_failed', CONNECTION_LOST: 'connection_lost',
diff --git a/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_controller_impl_win.cc b/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_controller_impl_win.cc index b0679d4..ebc9ff6 100644 --- a/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_controller_impl_win.cc +++ b/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_controller_impl_win.cc
@@ -186,6 +186,10 @@ ChromeCleanerRebootDialogControllerImpl::Create(controller); } +bool ChromeCleanerControllerDelegate::UserInitiatedCleanupsFeatureEnabled() { + return UserInitiatedCleanupsEnabled(); +} + // static ChromeCleanerControllerImpl* ChromeCleanerControllerImpl::GetInstance() { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); @@ -272,6 +276,12 @@ DCHECK(delegate_); } +void ChromeCleanerControllerImpl::SetStateForTesting(State state) { + state_ = state; + if (state_ == State::kIdle) + idle_reason_ = IdleReason::kInitial; +} + // static void ChromeCleanerControllerImpl::ResetInstanceForTesting() { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); @@ -293,6 +303,72 @@ observer_list_.RemoveObserver(observer); } +void ChromeCleanerControllerImpl::OnReporterSequenceStarted() { + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + if (!delegate_->UserInitiatedCleanupsFeatureEnabled()) + return; + + if (state() == State::kIdle) + SetStateAndNotifyObservers(State::kReporterRunning); +} + +void ChromeCleanerControllerImpl::OnReporterSequenceDone( + SwReporterInvocationResult result) { + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + DCHECK_NE(SwReporterInvocationResult::kUnspecified, result); + + if (!delegate_->UserInitiatedCleanupsFeatureEnabled()) + return; + + // Ignore if any interaction with cleaner runs is ongoing. This can happen + // in two situations: + // - The controller is currently handling the cleanup flow (states: infected, + // cleaning, reboot required); + // - The controller was handling the cleanup flow when the reporter sequence + // started, and we didn't transition to the reporter running state. + // + // That situation can happen, for example, if a new version of the reporter + // component becomes available while the controller is handling the cleanup + // flow. The UI should block any attempt of starting a new user-initiated scan + // if the controller is not on an idle state, which includes when a reporter + // sequence is currently running. + if (state() != State::kReporterRunning) + return; + + switch (result) { + case SwReporterInvocationResult::kNotScheduled: + // This can happen if a new periodic reporter run tried to start (for + // example, because a new reporter component version became available) and + // there is another reporter sequence currently running. + // Ignore and wait until the other sequence completes to update state. + return; + + case SwReporterInvocationResult::kTimedOut: + case SwReporterInvocationResult::kProcessFailedToLaunch: + case SwReporterInvocationResult::kGeneralFailure: + idle_reason_ = IdleReason::kReporterFailed; + break; + + case SwReporterInvocationResult::kNothingFound: + idle_reason_ = IdleReason::kReporterFoundNothing; + break; + + case SwReporterInvocationResult::kCleanupNotOffered: + idle_reason_ = IdleReason::kReporterFoundNothing; + break; + + case SwReporterInvocationResult::kCleanupToBeOffered: + // A request to scan will immediately follow this message, so no state + // transition will be needed. + return; + + default: + NOTREACHED(); + } + + SetStateAndNotifyObservers(State::kIdle); +} + void ChromeCleanerControllerImpl::Scan( const SwReporterInvocation& reporter_invocation) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); @@ -387,6 +463,9 @@ case State::kIdle: observer->OnIdle(idle_reason_); break; + case State::kReporterRunning: + observer->OnReporterRunning(); + break; case State::kScanning: observer->OnScanning(); break;
diff --git a/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_controller_impl_win.h b/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_controller_impl_win.h index 5578b1b..e8f1f4c 100644 --- a/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_controller_impl_win.h +++ b/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_controller_impl_win.h
@@ -43,6 +43,9 @@ // Starts the reboot prompt flow if a cleanup requires a machine restart. virtual void StartRebootPromptFlow(ChromeCleanerController* controller); + + // Returns true if the UserInitiatedCleanups feature is enabled. + virtual bool UserInitiatedCleanupsFeatureEnabled(); }; class ChromeCleanerControllerImpl : public ChromeCleanerController { @@ -60,6 +63,8 @@ void ResetIdleState() override; void AddObserver(Observer* observer) override; void RemoveObserver(Observer* observer) override; + void OnReporterSequenceStarted() override; + void OnReporterSequenceDone(SwReporterInvocationResult result) override; void Scan(const SwReporterInvocation& reporter_invocation) override; void ReplyWithUserResponse(Profile* profile, UserResponse user_response) override; @@ -70,6 +75,10 @@ // production version. void SetDelegateForTesting(ChromeCleanerControllerDelegate* delegate); + // Force the current controller's state for tests that check the effect of + // starting and completing reporter runs. + void SetStateForTesting(State state); + private: ChromeCleanerControllerImpl(); ~ChromeCleanerControllerImpl() override;
diff --git a/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_controller_impl_win_unittest.cc b/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_controller_impl_win_unittest.cc index dca2007c..ebab1aa9 100644 --- a/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_controller_impl_win_unittest.cc +++ b/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_controller_impl_win_unittest.cc
@@ -36,6 +36,7 @@ namespace { using ::chrome_cleaner::mojom::PromptAcceptance; +using ::testing::Bool; using ::testing::Combine; using ::testing::DoAll; using ::testing::InvokeWithoutArgs; @@ -72,6 +73,7 @@ : public ChromeCleanerController::Observer { public: MOCK_METHOD1(OnIdle, void(ChromeCleanerController::IdleReason)); + MOCK_METHOD0(OnReporterRunning, void()); MOCK_METHOD0(OnScanning, void()); MOCK_METHOD1(OnInfected, void(const ChromeCleanerScannerResults&)); MOCK_METHOD1(OnCleaning, void(const ChromeCleanerScannerResults&)); @@ -115,6 +117,7 @@ void TearDown() override { ChromeCleanerControllerImpl::GetInstance()->SetDelegateForTesting(nullptr); SetChromeCleanerRunnerTestDelegateForTesting(nullptr); + ChromeCleanerControllerImpl::ResetInstanceForTesting(); } // ChromeCleanerControllerDelegate overrides. @@ -263,6 +266,7 @@ void TearDown() override { controller_->SetDelegateForTesting(nullptr); SetChromeCleanerRunnerTestDelegateForTesting(nullptr); + ChromeCleanerControllerImpl::ResetInstanceForTesting(); } // ChromeCleanerControllerDelegate overrides. @@ -703,5 +707,179 @@ UserResponse::kDismissed)), ChromeCleanerControllerTestParamsToString()); +// Tests for the interaction between reporter runs and all possible states. +// Signals from reporter execution may lead to state transitions only if there +// is no cleaner activity, so it's enough to check the state after a signal. +// +// Parameters: +// - user_initiated_cleanups_enabled_: if the UserInitiatedCleanups feature +// is enabled. +// - initial_state_: the state of the controller before receiving a signal from +// the reporter. +using ChromeCleanerControllerReporterInteractionTestParams = + std::tuple<bool, ChromeCleanerController::State>; + +class ChromeCleanerControllerReporterInteractionTest + : public testing::TestWithParam< + ChromeCleanerControllerReporterInteractionTestParams>, + public ChromeCleanerControllerDelegate { + public: + void SetUp() override { + std::tie(user_initiated_cleanups_enabled_, initial_state_) = GetParam(); + + ChromeCleanerControllerImpl::ResetInstanceForTesting(); + controller_ = ChromeCleanerControllerImpl::GetInstance(); + ASSERT_TRUE(controller_); + + controller_->SetDelegateForTesting(this); + + controller_->SetStateForTesting(initial_state_); + ASSERT_EQ(initial_state_, controller_->state()); + } + + void TearDown() override { + controller_->SetDelegateForTesting(nullptr); + ChromeCleanerControllerImpl::ResetInstanceForTesting(); + } + + bool UserInitiatedCleanupsFeatureEnabled() override { + return user_initiated_cleanups_enabled_; + } + + void ExpectNoStateChangeOnReporterSequenceDone( + SwReporterInvocationResult reporter_result) { + controller_->OnReporterSequenceDone(reporter_result); + EXPECT_EQ(initial_state_, controller_->state()); + } + + void MaybeExpectStateChangeToIdle( + SwReporterInvocationResult reporter_result, + ChromeCleanerController::IdleReason idle_reason) { + controller_->OnReporterSequenceDone(reporter_result); + if (user_initiated_cleanups_enabled_ && + initial_state_ == ChromeCleanerController::State::kReporterRunning) { + EXPECT_EQ(ChromeCleanerController::State::kIdle, controller_->state()); + EXPECT_EQ(idle_reason, controller_->idle_reason()); + } else { + EXPECT_EQ(initial_state_, controller_->state()); + } + } + + // We need this because we need UI and IO threads during tests. The thread + // bundle should be the first member of the class so that it will be destroyed + // last. + content::TestBrowserThreadBundle thread_bundle_; + + bool user_initiated_cleanups_enabled_; + ChromeCleanerController::State initial_state_; + + ChromeCleanerControllerImpl* controller_ = nullptr; + StrictMock<MockChromeCleanerControllerObserver> mock_observer_; +}; + +TEST_P(ChromeCleanerControllerReporterInteractionTest, + OnReporterSequenceStarted) { + controller_->OnReporterSequenceStarted(); + EXPECT_EQ(user_initiated_cleanups_enabled_ && + (initial_state_ == ChromeCleanerController::State::kIdle) + ? ChromeCleanerController::State::kReporterRunning + : initial_state_, + controller_->state()); +} + +TEST_P(ChromeCleanerControllerReporterInteractionTest, + OnReporterSequenceDone_NotScheduled) { + ExpectNoStateChangeOnReporterSequenceDone( + SwReporterInvocationResult::kNotScheduled); +} + +TEST_P(ChromeCleanerControllerReporterInteractionTest, + OnReporterSequenceDone_TimedOut) { + MaybeExpectStateChangeToIdle( + SwReporterInvocationResult::kTimedOut, + ChromeCleanerController::IdleReason::kReporterFailed); +} + +TEST_P(ChromeCleanerControllerReporterInteractionTest, + OnReporterSequenceDone_ProcessFailedToLaunch) { + MaybeExpectStateChangeToIdle( + SwReporterInvocationResult::kProcessFailedToLaunch, + ChromeCleanerController::IdleReason::kReporterFailed); +} + +TEST_P(ChromeCleanerControllerReporterInteractionTest, + OnReporterSequenceDone_GeneralFailure) { + MaybeExpectStateChangeToIdle( + SwReporterInvocationResult::kGeneralFailure, + ChromeCleanerController::IdleReason::kReporterFailed); +} + +TEST_P(ChromeCleanerControllerReporterInteractionTest, + OnReporterSequenceDone_NothingFound) { + MaybeExpectStateChangeToIdle( + SwReporterInvocationResult::kNothingFound, + ChromeCleanerController::IdleReason::kReporterFoundNothing); +} + +TEST_P(ChromeCleanerControllerReporterInteractionTest, + OnReporterSequenceDone_CleanupNotOffered) { + MaybeExpectStateChangeToIdle( + SwReporterInvocationResult::kCleanupNotOffered, + ChromeCleanerController::IdleReason::kReporterFoundNothing); +} + +TEST_P(ChromeCleanerControllerReporterInteractionTest, + OnReporterSequenceDone_CleanupToBeOffered) { + ExpectNoStateChangeOnReporterSequenceDone( + SwReporterInvocationResult::kCleanupToBeOffered); +} + +std::ostream& operator<<(std::ostream& out, + ChromeCleanerController::State state) { + switch (state) { + case ChromeCleanerController::State::kIdle: + return out << "Idle"; + case ChromeCleanerController::State::kReporterRunning: + return out << "ReporterRunning"; + case ChromeCleanerController::State::kScanning: + return out << "Scanning"; + case ChromeCleanerController::State::kInfected: + return out << "Infected"; + case ChromeCleanerController::State::kCleaning: + return out << "Cleaning"; + case ChromeCleanerController::State::kRebootRequired: + return out << "RebootRequired"; + default: + NOTREACHED(); + return out << "UnknownUserResponse" << state; + } +} + +// ::testing::PrintToStringParamName does not format tuples as a valid test +// name, so this functor can be used to get each element in the tuple +// explicitly and format them using the above operator<< overrides. +struct ChromeCleanerControllerReporterInteractionTestParamsToString { + std::string operator()( + const ::testing::TestParamInfo< + ChromeCleanerControllerReporterInteractionTestParams>& info) const { + std::ostringstream param_name; + param_name << std::get<0>(info.param) << "_"; + param_name << std::get<1>(info.param); + return param_name.str(); + } +}; + +INSTANTIATE_TEST_CASE_P( + All, + ChromeCleanerControllerReporterInteractionTest, + Combine(Bool(), + Values(ChromeCleanerController::State::kIdle, + ChromeCleanerController::State::kReporterRunning, + ChromeCleanerController::State::kScanning, + ChromeCleanerController::State::kInfected, + ChromeCleanerController::State::kCleaning, + ChromeCleanerController::State::kRebootRequired)), + ChromeCleanerControllerReporterInteractionTestParamsToString()); + } // namespace } // namespace safe_browsing
diff --git a/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_controller_win.h b/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_controller_win.h index 6860744b..d9510a8c 100644 --- a/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_controller_win.h +++ b/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_controller_win.h
@@ -47,6 +47,9 @@ // cleaning attempts. This is also the state the controller will end up in // if any errors occur during execution of the Chrome Cleaner process. kIdle, + // The Software Reporter tool is currently running and there is no pending + // action corresponding to a cleaner execution. + kReporterRunning, // All steps up to and including scanning the machine occur in this // state. The steps include downloading the Chrome Cleaner binary, setting // up an IPC between Chrome and the Cleaner process, and the actual @@ -67,6 +70,8 @@ enum class IdleReason { kInitial, + kReporterFoundNothing, + kReporterFailed, kScanningFoundNothing, kScanningFailed, kConnectionLost, @@ -91,6 +96,7 @@ class Observer { public: virtual void OnIdle(IdleReason idle_reason) {} + virtual void OnReporterRunning() {} virtual void OnScanning() {} virtual void OnInfected( const ChromeCleanerScannerResults& scanner_results) {} @@ -131,6 +137,18 @@ virtual void AddObserver(Observer* observer) = 0; virtual void RemoveObserver(Observer* observer) = 0; + // Invoked by the reporter runner, notifies the controller that a reporter + // sequence started. If there is no pending cleaner action (currently on the + // kIdle state), then it will transition to the kReporterRunning state. + virtual void OnReporterSequenceStarted() = 0; + + // Invoked by the reporter runner, notifies the controller that a reporter + // sequence completed (or has not been scheduled). If there is no pending + // cleaner action (currently on kIdle or kReporterRunning state), then it will + // transition to either kScanning, if the reporter found removable UwS, or + // kIdle otherwise. + virtual void OnReporterSequenceDone(SwReporterInvocationResult result) = 0; + // Downloads the Chrome Cleaner binary, executes it and waits for the Cleaner // to communicate with Chrome about harmful software found on the // system. During this time, the controller will be in the kScanning state. If
diff --git a/chrome/browser/safe_browsing/chrome_cleaner/mock_chrome_cleaner_controller_win.h b/chrome/browser/safe_browsing/chrome_cleaner/mock_chrome_cleaner_controller_win.h index 42a3feb..be4fca7 100644 --- a/chrome/browser/safe_browsing/chrome_cleaner/mock_chrome_cleaner_controller_win.h +++ b/chrome/browser/safe_browsing/chrome_cleaner/mock_chrome_cleaner_controller_win.h
@@ -25,6 +25,8 @@ MOCK_METHOD0(ResetIdleState, void()); MOCK_METHOD1(AddObserver, void(Observer*)); MOCK_METHOD1(RemoveObserver, void(Observer*)); + MOCK_METHOD0(OnReporterSequenceStarted, void()); + MOCK_METHOD1(OnReporterSequenceDone, void(SwReporterInvocationResult)); MOCK_METHOD1(Scan, void(const safe_browsing::SwReporterInvocation&)); MOCK_METHOD2(ReplyWithUserResponse, void(Profile*, UserResponse)); MOCK_METHOD0(Reboot, void());
diff --git a/chrome/browser/safe_browsing/chrome_cleaner/reporter_runner_browsertest_win.cc b/chrome/browser/safe_browsing/chrome_cleaner/reporter_runner_browsertest_win.cc index 3b3bf8c7..bd94d6f 100644 --- a/chrome/browser/safe_browsing/chrome_cleaner/reporter_runner_browsertest_win.cc +++ b/chrome/browser/safe_browsing/chrome_cleaner/reporter_runner_browsertest_win.cc
@@ -24,6 +24,7 @@ #include "base/version.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/safe_browsing/chrome_cleaner/mock_chrome_cleaner_controller_win.h" #include "chrome/browser/safe_browsing/chrome_cleaner/srt_client_info_win.h" #include "chrome/browser/safe_browsing/chrome_cleaner/srt_field_trial_win.h" #include "chrome/browser/ui/browser.h" @@ -35,11 +36,19 @@ #include "components/prefs/pref_service.h" #include "components/safe_browsing/common/safe_browsing_prefs.h" #include "components/variations/variations_params_manager.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" namespace safe_browsing { namespace { +using ::testing::_; +using ::testing::Eq; +using ::testing::InvokeWithoutArgs; +using ::testing::Return; +using ::testing::SaveArg; + constexpr char kSRTPromptGroup[] = "SRTGroup"; class Waiter { @@ -52,10 +61,6 @@ base::RunLoop().RunUntilIdle(); } - base::OnceClosure SignalClosure() { - return base::BindOnce(&Waiter::Signal, base::Unretained(this)); - } - bool Done() { base::AutoLock lock(lock_); return done_; @@ -125,9 +130,6 @@ SetSwReporterTestingDelegate(nullptr); } - // Records that the prompt was shown. - void TriggerPrompt() override { prompt_trigger_called_ = true; } - // Records that the reporter was launched with the parameters given in // |invocation|. int LaunchReporter(const SwReporterInvocation& invocation) override { @@ -141,6 +143,14 @@ // Returns the test's idea of the current time. base::Time Now() const override { return now_; } + ChromeCleanerController* GetCleanerController() override { + return &mock_chrome_cleaner_controller_; + } + + void CreateChromeCleanerDialogController() override { + dialog_controller_created_ = true; + } + void FastForwardBy(base::TimeDelta delta) { now_ += delta; } // Returns a task runner to use when launching the reporter (which is @@ -157,7 +167,7 @@ exit_code_to_report_ = exit_code_to_report; reporter_launch_count_ = 0; reporter_launch_parameters_.clear(); - prompt_trigger_called_ = false; + dialog_controller_created_ = false; } SwReporterInvocation CreateInvocation(const base::FilePath& exe_path) { @@ -167,10 +177,8 @@ } SwReporterInvocationSequence CreateInvocationSequence( - OnReporterSequenceDone on_sequence_done, const SwReporterInvocationSequence::Queue& container) { - return SwReporterInvocationSequence(base::Version("1.2.3"), container, - std::move(on_sequence_done)); + return SwReporterInvocationSequence(base::Version("1.2.3"), container); } // Schedules a single reporter to run. @@ -188,11 +196,19 @@ const SwReporterInvocationSequence::Queue& container) { ResetReporterRuns(exit_code_to_report); + ON_CALL(mock_chrome_cleaner_controller_, state()) + .WillByDefault(Return(ChromeCleanerController::State::kIdle)); + + if (expected_result != SwReporterInvocationResult::kNotScheduled) { + EXPECT_CALL(mock_chrome_cleaner_controller_, OnReporterSequenceStarted()) + .Times(1); + } + Waiter on_sequence_done; - auto invocations = CreateInvocationSequence( - ExpectResultOnSequenceDoneCallback(expected_result, - on_sequence_done.SignalClosure()), - container); + EXPECT_CALL(mock_chrome_cleaner_controller_, + OnReporterSequenceDone(Eq(expected_result))) + .WillOnce(InvokeWithoutArgs(&on_sequence_done, &Waiter::Signal)); + auto invocations = CreateInvocationSequence(container); RunSwReporters(invocation_type_, std::move(invocations)); on_sequence_done.Wait(); } @@ -243,7 +259,7 @@ void ExpectNumReporterLaunches(int expected_launch_count, bool expect_prompt) { EXPECT_EQ(expected_launch_count, reporter_launch_count_); - EXPECT_EQ(expect_prompt, prompt_trigger_called_); + EXPECT_EQ(expect_prompt, dialog_controller_created_); } // Expects that the reporter has been launched once with each path in @@ -355,8 +371,9 @@ base::Passed(&closure)); } - bool SeedIndicatesPromptEnabled() { - return incoming_seed_.empty() || (incoming_seed_ != old_seed_); + bool PromptDialogShouldBeShown(SwReporterInvocationType invocation_type) { + return !IsUserInitiated(invocation_type) && + (incoming_seed_.empty() || (incoming_seed_ != old_seed_)); } // Tests that a sequence of type |invocation_type1|, once scheduled, will not @@ -366,7 +383,12 @@ const base::FilePath path1(L"path1"); const base::FilePath path2(L"path2"); - ResetReporterRuns(chrome_cleaner::kSwReporterCleanupNeeded); + ResetReporterRuns(chrome_cleaner::kSwReporterNothingFound); + + ON_CALL(mock_chrome_cleaner_controller_, state()) + .WillByDefault(Return(ChromeCleanerController::State::kIdle)); + EXPECT_CALL(mock_chrome_cleaner_controller_, OnReporterSequenceStarted()) + .Times(1); // Launch two sequences that will be run in the following order: // - The first sequence (of type |invocation_type1|) starts and waits to @@ -383,31 +405,27 @@ Waiter first_sequence_done; Waiter second_sequence_done; + EXPECT_CALL( + mock_chrome_cleaner_controller_, + OnReporterSequenceDone(Eq(SwReporterInvocationResult::kNothingFound))) + .WillOnce( + DoAll(InvokeWithoutArgs(&second_sequence_done, &Waiter::Wait), + InvokeWithoutArgs(&first_sequence_done, &Waiter::Signal))); + SwReporterInvocationSequence::Queue invocations1({CreateInvocation(path1)}); - SwReporterInvocationSequence first_sequence = CreateInvocationSequence( - base::BindOnce( - [](Waiter* first_sequence_done, Waiter* second_sequence_done, - SwReporterInvocationResult result) { - EXPECT_EQ(SwReporterInvocationResult::kCleanupNeeded, result); - second_sequence_done->Wait(); - first_sequence_done->Signal(); - }, - &first_sequence_done, &second_sequence_done), - invocations1); - RunSwReporters(invocation_type1, std::move(first_sequence)); + RunSwReporters(invocation_type1, CreateInvocationSequence(invocations1)); + + EXPECT_CALL( + mock_chrome_cleaner_controller_, + OnReporterSequenceDone(Eq(SwReporterInvocationResult::kNotScheduled))) + .WillOnce(InvokeWithoutArgs(&second_sequence_done, &Waiter::Signal)); SwReporterInvocationSequence::Queue invocations2({CreateInvocation(path2)}); - SwReporterInvocationSequence second_sequence = - CreateInvocationSequence(ExpectResultOnSequenceDoneCallback( - SwReporterInvocationResult::kNotScheduled, - second_sequence_done.SignalClosure()), - invocations2); - RunSwReporters(invocation_type2, std::move(second_sequence)); + RunSwReporters(invocation_type2, CreateInvocationSequence(invocations2)); first_sequence_done.Wait(); - ExpectReporterLaunches({path1}, - /*expect_prompt=*/SeedIndicatesPromptEnabled()); + ExpectReporterLaunches({path1}, /*expect_prompt=*/false); } base::Time now_; @@ -418,11 +436,15 @@ std::string old_seed_; std::string incoming_seed_; - bool prompt_trigger_called_ = false; + bool dialog_controller_created_ = false; int reporter_launch_count_ = 0; std::vector<SwReporterInvocation> reporter_launch_parameters_; int exit_code_to_report_ = kReporterNotLaunchedExitCode; + // Using NiceMock to suppress warnings about uninteresting calls to state(). + ::testing::NiceMock<MockChromeCleanerController> + mock_chrome_cleaner_controller_; + // A callback to invoke when the first reporter of a queue is launched. This // can be used to perform actions in the middle of a queue of reporters which // all launch on the same mock clock tick. @@ -444,10 +466,29 @@ } IN_PROC_BROWSER_TEST_P(ReporterRunnerTest, CleanupNeeded) { - RunSingleReporterAndWait(chrome_cleaner::kSwReporterCleanupNeeded, - SwReporterInvocationResult::kCleanupNeeded); - ExpectNumReporterLaunches(/*expected_launch_count=*/1, - /*expect_prompt=*/SeedIndicatesPromptEnabled()); + bool cleanup_offered = + IsUserInitiated(invocation_type_) || + (incoming_seed_.empty() || (incoming_seed_ != old_seed_)); + + SwReporterInvocation scan_invocation = CreateInvocation(base::FilePath()); + if (cleanup_offered) { + EXPECT_CALL(mock_chrome_cleaner_controller_, Scan(_)) + .WillOnce(SaveArg<0>(&scan_invocation)); + } + + RunSingleReporterAndWait( + chrome_cleaner::kSwReporterCleanupNeeded, + cleanup_offered ? SwReporterInvocationResult::kCleanupToBeOffered + : SwReporterInvocationResult::kCleanupNotOffered); + ExpectNumReporterLaunches( + /*expected_launch_count=*/1, + /*expect_prompt=*/PromptDialogShouldBeShown(invocation_type_)); + + if (cleanup_offered) { + EXPECT_EQ(invocation_type_ == + SwReporterInvocationType::kUserInitiatedWithLogsAllowed, + scan_invocation.cleaner_logs_upload_enabled()); + } } IN_PROC_BROWSER_TEST_P(ReporterRunnerTest, RanRecently) {
diff --git a/chrome/browser/safe_browsing/chrome_cleaner/reporter_runner_win.cc b/chrome/browser/safe_browsing/chrome_cleaner/reporter_runner_win.cc index a365947..4a341b51 100644 --- a/chrome/browser/safe_browsing/chrome_cleaner/reporter_runner_win.cc +++ b/chrome/browser/safe_browsing/chrome_cleaner/reporter_runner_win.cc
@@ -474,6 +474,11 @@ uma.RecordReporterStep(value); } +ChromeCleanerController* GetCleanerController() { + return g_testing_delegate_ ? g_testing_delegate_->GetCleanerController() + : ChromeCleanerController::GetInstance(); +} + // This function is called from a worker thread to launch the SwReporter and // wait for termination to collect its exit code. This task could be // interrupted by a shutdown at any time, so it shouldn't depend on anything @@ -501,10 +506,13 @@ SwReporterInvocationResult ExitCodeToInvocationResult(int exit_code) { switch (exit_code) { case chrome_cleaner::kSwReporterCleanupNeeded: + // This should only be used if a cleanup will not be offered. If a + // cleanup is offered, the controller will get notified with a + // kCleanupToBeOffered signal, and this one will be ignored. // Do not accept reboot required or post-reboot exit codes, since they // should not be sent out by the reporter, and should be treated as // errors. - return SwReporterInvocationResult::kCleanupNeeded; + return SwReporterInvocationResult::kCleanupNotOffered; case chrome_cleaner::kSwReporterNothingFound: case chrome_cleaner::kSwReporterNonRemovableOnly: @@ -519,22 +527,23 @@ return SwReporterInvocationResult::kGeneralFailure; } -// Scans and shows the Chrome Cleaner UI if the user has not already been -// prompted in the current prompt wave. -void MaybeScanAndPrompt(SwReporterInvocationType invocation_type, - SwReporterInvocation reporter_invocation) { - ChromeCleanerController* cleaner_controller = - ChromeCleanerController::GetInstance(); - - if (cleaner_controller->state() != ChromeCleanerController::State::kIdle) { - RecordPromptNotShownWithReasonHistogram(NO_PROMPT_REASON_NOT_ON_IDLE_STATE); +void CreateChromeCleanerDialogController() { + if (g_testing_delegate_) { + g_testing_delegate_->CreateChromeCleanerDialogController(); return; } + // The dialog controller manages its own lifetime. If the controller enters + // the kInfected state, the dialog controller will show the chrome cleaner + // dialog to the user. + new ChromeCleanerDialogControllerImpl(GetCleanerController()); +} + +bool ShouldShowPromptForPeriodicRun() { Browser* browser = chrome::FindLastActive(); if (!browser) { RecordReporterStepHistogram(SW_REPORTER_NO_BROWSER); - return; + return false; } Profile* profile = browser->profile(); @@ -550,35 +559,10 @@ if (!incoming_seed.empty() && incoming_seed == old_seed) { RecordReporterStepHistogram(SW_REPORTER_ALREADY_PROMPTED); RecordPromptNotShownWithReasonHistogram(NO_PROMPT_REASON_ALREADY_PROMPTED); - return; + return false; } - // This approach makes it harder to define proper tests for calls to Scan(), - // prompt not shown for user-initiated runs, and cleaner logs uploading. - // TODO(crbug.com/776538): Define a delegate with default behaviour that is - // overriden (instead of defined) by tests. - if (g_testing_delegate_) { - g_testing_delegate_->TriggerPrompt(); - return; - } - - reporter_invocation.set_cleaner_logs_upload_enabled( - invocation_type == - SwReporterInvocationType::kUserInitiatedWithLogsAllowed); - - cleaner_controller->Scan(reporter_invocation); - DCHECK_EQ(ChromeCleanerController::State::kScanning, - cleaner_controller->state()); - - // If this is a periodic reporter run, then create the dialog controller, so - // that the user may eventually be prompted. Otherwise, all interaction - // should be driven from the Settings page. - if (invocation_type == SwReporterInvocationType::kPeriodicRun) { - // The dialog controller manages its own lifetime. If the controller enters - // the kInfected state, the dialog controller will show the chrome cleaner - // dialog to the user. - new ChromeCleanerDialogControllerImpl(cleaner_controller); - } + return true; } base::Time Now() { @@ -628,6 +612,7 @@ // itself once all invocations finish. instance_ = new ReporterRunner(invocation_type, std::move(invocations), std::move(time_info)); + GetCleanerController()->OnReporterSequenceStarted(); instance_->PostNextInvocation(); // The reporter sequence has been scheduled to run, so don't notify that @@ -733,7 +718,7 @@ // has completed. This is run as a task posted from an interruptible worker // thread so should be resilient to unexpected shutdown. void ReporterDone(const base::Time& reporter_start_time, - const SwReporterInvocation& finished_invocation, + SwReporterInvocation finished_invocation, int exit_code) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_EQ(instance_, this); @@ -741,9 +726,9 @@ // Ensures finalization if there are no further invocations to run. This // scoped runner may be released later on if there are other invocations to // start. - base::ScopedClosureRunner scoped_runner( - base::BindOnce(&ReporterRunner::SendResultAndDeleteSelf, - base::Unretained(this), exit_code)); + base::ScopedClosureRunner scoped_runner(base::BindOnce( + &ReporterRunner::SendResultAndDeleteSelf, base::Unretained(this), + ExitCodeToInvocationResult(exit_code))); // Don't continue the current queue of reporters if one failed to launch. // If the reporter failed to launch, do not process the results. (The exit @@ -813,7 +798,40 @@ return; } - MaybeScanAndPrompt(invocation_type_, finished_invocation); + ChromeCleanerController* cleaner_controller = GetCleanerController(); + + // The most common state for the controller at this moment is + // kReporterRunning, set before this invocation sequence started. However, + // it's possible that the reporter starts running again during the prompt + // routine (for example, a new reporter version became available while the + // cleaner prompt is presented to the user). In that case, only prompt if + // the controller has returned to the idle state. + if (cleaner_controller->state() != ChromeCleanerController::State::kIdle && + cleaner_controller->state() != + ChromeCleanerController::State::kReporterRunning) { + RecordPromptNotShownWithReasonHistogram( + NO_PROMPT_REASON_NOT_ON_IDLE_STATE); + return; + } + + if (!IsUserInitiated(invocation_type_) && + !ShouldShowPromptForPeriodicRun()) { + return; + } + + finished_invocation.set_cleaner_logs_upload_enabled( + invocation_type_ == + SwReporterInvocationType::kUserInitiatedWithLogsAllowed); + + invocations_.NotifySequenceDone( + SwReporterInvocationResult::kCleanupToBeOffered); + cleaner_controller->Scan(finished_invocation); + + // If this is a periodic reporter run, then create the dialog controller, so + // that the user may eventually be prompted. Otherwise, all interaction + // should be driven from the Settings page. + if (!IsUserInitiated(invocation_type_)) + CreateChromeCleanerDialogController(); } // Returns true if the experiment to send reporter logs is enabled, the user @@ -901,11 +919,11 @@ base::IntToString16(ChannelAsInt())); } - void SendResultAndDeleteSelf(int exit_code) { + void SendResultAndDeleteSelf(SwReporterInvocationResult result) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_EQ(instance_, this); - invocations_.NotifySequenceDone(ExitCodeToInvocationResult(exit_code)); + invocations_.NotifySequenceDone(result); delete this; } @@ -954,13 +972,15 @@ : command_line_(other.command_line_), supported_behaviours_(other.supported_behaviours_), suffix_(other.suffix_), - reporter_logs_upload_enabled_(other.reporter_logs_upload_enabled_) {} + reporter_logs_upload_enabled_(other.reporter_logs_upload_enabled_), + cleaner_logs_upload_enabled_(other.cleaner_logs_upload_enabled_) {} void SwReporterInvocation::operator=(const SwReporterInvocation& invocation) { command_line_ = invocation.command_line_; supported_behaviours_ = invocation.supported_behaviours_; suffix_ = invocation.suffix_; reporter_logs_upload_enabled_ = invocation.reporter_logs_upload_enabled_; + cleaner_logs_upload_enabled_ = invocation.cleaner_logs_upload_enabled_; } SwReporterInvocation& SwReporterInvocation::WithSuffix( @@ -979,7 +999,8 @@ return command_line_.argv() == other.command_line_.argv() && supported_behaviours_ == other.supported_behaviours_ && suffix_ == other.suffix_ && - reporter_logs_upload_enabled_ == other.reporter_logs_upload_enabled_; + reporter_logs_upload_enabled_ == other.reporter_logs_upload_enabled_ && + cleaner_logs_upload_enabled_ == other.cleaner_logs_upload_enabled_; } const base::CommandLine& SwReporterInvocation::command_line() const { @@ -1024,11 +1045,15 @@ SwReporterInvocationSequence::SwReporterInvocationSequence( const base::Version& version, - const Queue& container, - OnReporterSequenceDone on_sequence_done) - : version_(version), - container_(container), - on_sequence_done_(std::move(on_sequence_done)) {} + const Queue& container) + : version_(version), container_(container) { + // Notify the cleaner controller once this sequence completes. Don't retain + // a reference to the controller object, since it's guaranteed to outlive the + // sequence. + on_sequence_done_ = + base::BindOnce(&ChromeCleanerController::OnReporterSequenceDone, + base::Unretained(GetCleanerController())); +} SwReporterInvocationSequence::SwReporterInvocationSequence( SwReporterInvocationSequence&& invocations_sequence) @@ -1068,8 +1093,8 @@ void RunSwReporters(SwReporterInvocationType invocation_type, SwReporterInvocationSequence&& invocations) { DCHECK_CURRENTLY_ON(BrowserThread::UI); - DCHECK(!invocations.container().empty()); + ReporterRunner::MaybeStartInvocations(invocation_type, std::move(invocations)); }
diff --git a/chrome/browser/safe_browsing/chrome_cleaner/reporter_runner_win.h b/chrome/browser/safe_browsing/chrome_cleaner/reporter_runner_win.h index a4dec16d..80a627d 100644 --- a/chrome/browser/safe_browsing/chrome_cleaner/reporter_runner_win.h +++ b/chrome/browser/safe_browsing/chrome_cleaner/reporter_runner_win.h
@@ -23,6 +23,8 @@ namespace safe_browsing { +class ChromeCleanerController; + // A special exit code identifying a failure to run the reporter. const int kReporterNotLaunchedExitCode = INT_MAX; @@ -140,8 +142,13 @@ kGeneralFailure, // The reporter ran successfully, but didn't find cleanable unwanted software. kNothingFound, - // The reporter ran successfully and found cleanable unwanted software. - kCleanupNeeded, + // A periodic reporter sequence ran successfully and found cleanable unwanted + // software, but the user shouldn't be prompted at this time. + kCleanupNotOffered, + // The reporter ran successfully and found cleanable unwanted software, and + // a cleanup should be offered. A notification with this result should be + // immediately followed by an attempt to run the cleaner in scanning mode. + kCleanupToBeOffered, }; // Called when all reporter invocations have completed, with a result parameter @@ -153,10 +160,8 @@ public: using Queue = std::queue<SwReporterInvocation>; - SwReporterInvocationSequence( - const base::Version& version = base::Version(), - const Queue& container = Queue(), - OnReporterSequenceDone on_sequence_done = OnReporterSequenceDone()); + SwReporterInvocationSequence(const base::Version& version = base::Version(), + const Queue& container = Queue()); SwReporterInvocationSequence(SwReporterInvocationSequence&& queue); virtual ~SwReporterInvocationSequence(); @@ -190,6 +195,9 @@ // A delegate used by tests to implement test doubles (e.g., stubs, fakes, or // mocks). +// +// TODO(crbug.com/776538): Replace this with a proper delegate that defines the +// default behaviour to be overriden (instead of defined) by tests. class SwReporterTestingDelegate { public: virtual ~SwReporterTestingDelegate() {} @@ -197,10 +205,6 @@ // Invoked by tests in place of base::LaunchProcess. virtual int LaunchReporter(const SwReporterInvocation& invocation) = 0; - // Invoked by tests in place of the actual prompting logic. - // See MaybeFetchSRT(). - virtual void TriggerPrompt() = 0; - // Invoked by tests to override the current time. // See Now() in reporter_runner_win.cc. virtual base::Time Now() const = 0; @@ -208,6 +212,12 @@ // A task runner used to spawn the reporter process (which blocks). // See ReporterRunner::ScheduleNextInvocation(). virtual base::TaskRunner* BlockingTaskRunner() const = 0; + + // Invoked by tests to return a mock to the cleaner controller. + virtual ChromeCleanerController* GetCleanerController() = 0; + + // Invoked by tests in place of the actual creation of the dialog controller. + virtual void CreateChromeCleanerDialogController() = 0; }; // Set a delegate for testing. The implementation will not take ownership of
diff --git a/chrome/browser/ui/app_list/app_list_controller_browsertest.cc b/chrome/browser/ui/app_list/app_list_controller_browsertest.cc index 03ee1f0..8a36e1b 100644 --- a/chrome/browser/ui/app_list/app_list_controller_browsertest.cc +++ b/chrome/browser/ui/app_list/app_list_controller_browsertest.cc
@@ -4,10 +4,10 @@ #include <stddef.h> -#include "ash/app_list/model/app_list_model.h" -#include "ash/app_list/model/search_box_model.h" -#include "ash/app_list/model/search_result.h" -#include "ash/app_list/model/search_result_observer.h" +#include "ash/app_list/model/search/search_box_model.h" +#include "ash/app_list/model/search/search_model.h" +#include "ash/app_list/model/search/search_result.h" +#include "ash/app_list/model/search/search_result_observer.h" #include "base/command_line.h" #include "base/macros.h" #include "base/path_service.h" @@ -63,7 +63,7 @@ observed_results_list_(NULL) {} void WatchResultsLookingForItem( - app_list::AppListModel::SearchResults* search_results, + app_list::SearchModel::SearchResults* search_results, const std::string& extension_name) { EXPECT_FALSE(observed_results_list_); observed_results_list_ = search_results; @@ -117,7 +117,7 @@ private: base::string16 item_to_observe_; - app_list::AppListModel::SearchResults* observed_results_list_; + app_list::SearchModel::SearchResults* observed_results_list_; DISALLOW_COPY_AND_ASSIGN(AppListControllerSearchResultsBrowserTest); }; @@ -139,7 +139,7 @@ ASSERT_TRUE(service); service->ShowForProfile(browser()->profile()); - app_list::AppListModel* model = test::GetAppListModel(service); + app_list::SearchModel* model = test::GetSearchModel(service); ASSERT_TRUE(model); WatchResultsLookingForItem(model->results(), extension->name());
diff --git a/chrome/browser/ui/app_list/app_list_syncable_service.cc b/chrome/browser/ui/app_list/app_list_syncable_service.cc index d48fb60a..015b2d9 100644 --- a/chrome/browser/ui/app_list/app_list_syncable_service.cc +++ b/chrome/browser/ui/app_list/app_list_syncable_service.cc
@@ -11,6 +11,7 @@ #include "ash/app_list/model/app_list_item.h" #include "ash/app_list/model/app_list_model.h" #include "ash/app_list/model/app_list_model_observer.h" +#include "ash/app_list/model/search/search_model.h" #include "base/command_line.h" #include "base/macros.h" #include "base/memory/ptr_util.h" @@ -335,6 +336,7 @@ : profile_(profile), extension_system_(extension_system), model_(new AppListModel), + search_model_(new SearchModel), model_updater_(new ModelUpdater(model_.get())), initial_sync_data_processed_(false), first_app_list_sync_(true), @@ -516,6 +518,11 @@ return model_.get(); } +SearchModel* AppListSyncableService::GetSearchModel() { + DCHECK(IsInitialized()); + return search_model_.get(); +} + void AppListSyncableService::HandleUpdateStarted() { // Don't observe the model while processing update changes. model_observer_.reset();
diff --git a/chrome/browser/ui/app_list/app_list_syncable_service.h b/chrome/browser/ui/app_list/app_list_syncable_service.h index 9d5e84e..16a5e6a 100644 --- a/chrome/browser/ui/app_list/app_list_syncable_service.h +++ b/chrome/browser/ui/app_list/app_list_syncable_service.h
@@ -47,6 +47,7 @@ class AppListItem; class AppListModel; +class SearchModel; // Keyed Service that owns, stores, and syncs an AppListModel for a profile. class AppListSyncableService : public syncer::SyncableService, @@ -121,6 +122,9 @@ // Gets the app list model. AppListModel* GetModel(); + // Gets the search model. + SearchModel* GetSearchModel(); + // Returns true if this service was initialized. bool IsInitialized() const; @@ -267,6 +271,7 @@ Profile* profile_; extensions::ExtensionSystem* extension_system_; std::unique_ptr<AppListModel> model_; + std::unique_ptr<SearchModel> search_model_; std::unique_ptr<ModelUpdater> model_updater_; std::unique_ptr<ModelObserver> model_observer_; std::unique_ptr<ExtensionAppModelBuilder> apps_builder_;
diff --git a/chrome/browser/ui/app_list/app_list_view_delegate.cc b/chrome/browser/ui/app_list/app_list_view_delegate.cc index ce844bd..4289668 100644 --- a/chrome/browser/ui/app_list/app_list_view_delegate.cc +++ b/chrome/browser/ui/app_list/app_list_view_delegate.cc
@@ -6,11 +6,12 @@ #include <stddef.h> +#include <utility> #include <vector> #include "ash/app_list/model/app_list_model.h" #include "ash/app_list/model/app_list_view_state.h" -#include "ash/app_list/model/search_box_model.h" +#include "ash/app_list/model/search/search_box_model.h" #include "ash/public/interfaces/constants.mojom.h" #include "base/command_line.h" #include "base/metrics/histogram_macros.h" @@ -92,6 +93,7 @@ : controller_(controller), profile_(nullptr), model_(nullptr), + search_model_(nullptr), template_url_service_observer_(this), observer_binding_(this), weak_ptr_factory_(this) { @@ -129,9 +131,10 @@ if (profile_) { DCHECK(model_); + DCHECK(search_model_); // |search_controller_| will be destroyed on profile switch. Before that, // delete |model_|'s search results to clear any dangling pointers. - model_->results()->DeleteAll(); + search_model_->results()->DeleteAll(); // Note: |search_resource_manager_| has a reference to |speech_ui_| so must // be destroyed first. @@ -144,7 +147,8 @@ if (start_page_service) start_page_service->RemoveObserver(this); app_sync_ui_state_watcher_.reset(); - model_ = NULL; + model_ = nullptr; + search_model_ = nullptr; } template_url_service_observer_.RemoveAll(); @@ -169,6 +173,9 @@ model_ = app_list::AppListSyncableServiceFactory::GetForProfile(profile_) ->GetModel(); + search_model_ = + app_list::AppListSyncableServiceFactory::GetForProfile(profile_) + ->GetSearchModel(); // After |model_| is initialized, make a GetWallpaperColors mojo call to set // wallpaper colors for |model_|. @@ -182,7 +189,7 @@ OnTemplateURLServiceChanged(); // Clear search query. - model_->search_box()->Update(base::string16(), false); + search_model_->search_box()->Update(base::string16(), false); } void AppListViewDelegate::OnGetWallpaperColorsCallback( @@ -202,9 +209,10 @@ false); search_resource_manager_.reset(new app_list::SearchResourceManager( - profile_, model_->search_box(), speech_ui_.get())); + profile_, search_model_->search_box(), speech_ui_.get())); - search_controller_ = CreateSearchController(profile_, model_, controller_); + search_controller_ = + CreateSearchController(profile_, model_, search_model_, controller_); } void AppListViewDelegate::OnWallpaperColorsChanged( @@ -221,6 +229,10 @@ return model_; } +app_list::SearchModel* AppListViewDelegate::GetSearchModel() { + return search_model_; +} + app_list::SpeechUIModel* AppListViewDelegate::GetSpeechUI() { return speech_ui_.get(); } @@ -240,7 +252,7 @@ // Record the search metric if the SearchResult is not a suggested app. if (result->display_type() != app_list::SearchResult::DISPLAY_RECOMMENDATION) - RecordHistogram(model_->tablet_mode(), model_->state_fullscreen()); + RecordHistogram(search_model_->tablet_mode(), model_->state_fullscreen()); search_controller_->OpenResult(result, event_flags); } @@ -257,7 +269,7 @@ } void AppListViewDelegate::AutoLaunchCanceled() { - if (model_ && model_->search_box()->is_voice_query()) { + if (search_model_ && search_model_->search_box()->is_voice_query()) { base::RecordAction(base::UserMetricsAction("AppList_AutoLaunchCanceled")); } auto_launch_timeout_ = base::TimeDelta(); @@ -321,7 +333,7 @@ if (is_final) { auto_launch_timeout_ = base::TimeDelta::FromMilliseconds(kAutoLaunchDefaultTimeoutMilliSec); - model_->search_box()->Update(result, true); + search_model_->search_box()->Update(result, true); } } @@ -424,7 +436,7 @@ default_provider->GetEngineType( template_url_service->search_terms_data()) == SEARCH_ENGINE_GOOGLE; - model_->SetSearchEngineIsGoogle(is_google); + search_model_->SetSearchEngineIsGoogle(is_google); app_list::StartPageService* start_page_service = app_list::StartPageService::Get(profile_);
diff --git a/chrome/browser/ui/app_list/app_list_view_delegate.h b/chrome/browser/ui/app_list/app_list_view_delegate.h index e4448f2..941b35f 100644 --- a/chrome/browser/ui/app_list/app_list_view_delegate.h +++ b/chrome/browser/ui/app_list/app_list_view_delegate.h
@@ -65,6 +65,7 @@ // Overridden from app_list::AppListViewDelegate: app_list::AppListModel* GetModel() override; + app_list::SearchModel* GetSearchModel() override; app_list::SpeechUIModel* GetSpeechUI() override; void StartSearch() override; void OpenSearchResult(app_list::SearchResult* result, @@ -120,9 +121,10 @@ // Unowned pointer to the associated profile. May change if SetProfileByPath // is called. Profile* profile_; - // Unowned pointer to the model owned by AppListSyncableService. Will change + // Unowned pointer to the models owned by AppListSyncableService. Will change // if |profile_| changes. app_list::AppListModel* model_; + app_list::SearchModel* search_model_; // Note: order ensures |search_resource_manager_| is destroyed before // |speech_ui_|.
diff --git a/chrome/browser/ui/app_list/search/answer_card/answer_card_result.h b/chrome/browser/ui/app_list/search/answer_card/answer_card_result.h index 3ab8bcb..7b309e7 100644 --- a/chrome/browser/ui/app_list/search/answer_card/answer_card_result.h +++ b/chrome/browser/ui/app_list/search/answer_card/answer_card_result.h
@@ -8,7 +8,7 @@ #include <memory> #include <string> -#include "ash/app_list/model/search_result.h" +#include "ash/app_list/model/search/search_result.h" class AppListControllerDelegate; class Profile;
diff --git a/chrome/browser/ui/app_list/search/answer_card/answer_card_search_provider.cc b/chrome/browser/ui/app_list/search/answer_card/answer_card_search_provider.cc index ea58100..bde62e99 100644 --- a/chrome/browser/ui/app_list/search/answer_card/answer_card_search_provider.cc +++ b/chrome/browser/ui/app_list/search/answer_card/answer_card_search_provider.cc
@@ -6,7 +6,7 @@ #include <utility> -#include "ash/app_list/model/app_list_model.h" +#include "ash/app_list/model/search/search_model.h" #include "base/command_line.h" #include "base/metrics/histogram_macros.h" #include "base/metrics/user_metrics.h" @@ -60,12 +60,12 @@ AnswerCardSearchProvider::AnswerCardSearchProvider( Profile* profile, - app_list::AppListModel* model, + app_list::SearchModel* search_model, AppListControllerDelegate* list_controller, std::unique_ptr<AnswerCardContents> contents0, std::unique_ptr<AnswerCardContents> contents1) : profile_(profile), - model_(model), + search_model_(search_model), list_controller_(list_controller), answer_server_url_(features::AnswerServerUrl()), template_url_service_(TemplateURLServiceFactory::GetForProfile(profile)) { @@ -84,7 +84,8 @@ current_request_url_ = GURL(); server_request_start_time_ = answer_loaded_time_ = base::TimeTicks(); - if (query.empty() || is_voice_query || !model_->search_engine_is_google()) { + if (query.empty() || is_voice_query || + !search_model_->search_engine_is_google()) { DeleteCurrentResult(); return; }
diff --git a/chrome/browser/ui/app_list/search/answer_card/answer_card_search_provider.h b/chrome/browser/ui/app_list/search/answer_card/answer_card_search_provider.h index 117d1591..334d3ff 100644 --- a/chrome/browser/ui/app_list/search/answer_card/answer_card_search_provider.h +++ b/chrome/browser/ui/app_list/search/answer_card/answer_card_search_provider.h
@@ -18,7 +18,7 @@ class TemplateURLService; namespace app_list { -class AppListModel; +class SearchModel; } namespace app_list { @@ -28,7 +28,7 @@ public AnswerCardContents::Delegate { public: AnswerCardSearchProvider(Profile* profile, - app_list::AppListModel* model, + app_list::SearchModel* search_model, AppListControllerDelegate* list_controller, std::unique_ptr<AnswerCardContents> contents0, std::unique_ptr<AnswerCardContents> contents1); @@ -91,8 +91,8 @@ // Unowned pointer to the associated profile. Profile* const profile_; - // Unowned pointer to app list model. - app_list::AppListModel* const model_; + // Unowned pointer to app list search model. + app_list::SearchModel* const search_model_; // Unowned pointer to app list controller. AppListControllerDelegate* const list_controller_;
diff --git a/chrome/browser/ui/app_list/search/answer_card/answer_card_search_provider_unittest.cc b/chrome/browser/ui/app_list/search/answer_card/answer_card_search_provider_unittest.cc index e317807..bcdf158 100644 --- a/chrome/browser/ui/app_list/search/answer_card/answer_card_search_provider_unittest.cc +++ b/chrome/browser/ui/app_list/search/answer_card/answer_card_search_provider_unittest.cc
@@ -9,8 +9,8 @@ #include <string> #include <utility> -#include "ash/app_list/model/app_list_model.h" -#include "ash/app_list/model/search_result.h" +#include "ash/app_list/model/search/search_model.h" +#include "ash/app_list/model/search/search_result.h" #include "base/macros.h" #include "base/metrics/field_trial.h" #include "base/metrics/field_trial_params.h" @@ -116,7 +116,7 @@ EXPECT_EQ(base::UTF8ToUTF16(title), result->title()); } - AppListModel* model() const { return model_.get(); } + SearchModel* search_model() const { return search_model_.get(); } const SearchProvider::Results& results() { return provider()->results(); } @@ -132,8 +132,8 @@ void SetUp() override { AppListTestBase::SetUp(); - model_ = base::MakeUnique<app_list::AppListModel>(); - model_->SetSearchEngineIsGoogle(true); + search_model_ = std::make_unique<app_list::SearchModel>(); + search_model_->SetSearchEngineIsGoogle(true); controller_ = base::MakeUnique<::test::TestAppListControllerDelegate>(); @@ -158,8 +158,8 @@ TemplateURLServiceFactory::GetInstance()->SetTestingFactory( profile_.get(), CreateTemplateURLService); // Provider will own the MockAnswerCardContents instance. - provider_ = base::MakeUnique<AnswerCardSearchProvider>( - profile_.get(), model_.get(), nullptr, std::move(contents0), + provider_ = std::make_unique<AnswerCardSearchProvider>( + profile_.get(), search_model_.get(), nullptr, std::move(contents0), std::move(contents1)); ON_CALL(*contents0_, GetView()).WillByDefault(Return(view0())); @@ -167,7 +167,7 @@ } private: - std::unique_ptr<app_list::AppListModel> model_; + std::unique_ptr<app_list::SearchModel> search_model_; std::unique_ptr<AnswerCardSearchProvider> provider_; std::unique_ptr<::test::TestAppListControllerDelegate> controller_; MockAnswerCardContents* contents0_ = nullptr; // Unowned. @@ -204,7 +204,7 @@ // Queries to non-Google search engines are ignored. TEST_F(AnswerCardSearchProviderTest, NotGoogle) { - model()->SetSearchEngineIsGoogle(false); + search_model()->SetSearchEngineIsGoogle(false); EXPECT_CALL(*contents1(), LoadURL(_)).Times(0); provider()->Start(false, base::UTF8ToUTF16(kCatQuery)); }
diff --git a/chrome/browser/ui/app_list/search/app_result.h b/chrome/browser/ui/app_list/search/app_result.h index d69b630..a51a342 100644 --- a/chrome/browser/ui/app_list/search/app_result.h +++ b/chrome/browser/ui/app_list/search/app_result.h
@@ -8,7 +8,7 @@ #include <memory> #include <string> -#include "ash/app_list/model/search_result.h" +#include "ash/app_list/model/search/search_result.h" #include "base/macros.h" #include "chrome/browser/ui/app_list/app_context_menu_delegate.h"
diff --git a/chrome/browser/ui/app_list/search/app_search_provider_unittest.cc b/chrome/browser/ui/app_list/search/app_search_provider_unittest.cc index 25d7b00..0322b3d4 100644 --- a/chrome/browser/ui/app_list/search/app_search_provider_unittest.cc +++ b/chrome/browser/ui/app_list/search/app_search_provider_unittest.cc
@@ -14,7 +14,7 @@ #include "ash/app_list/model/app_list_folder_item.h" #include "ash/app_list/model/app_list_item.h" #include "ash/app_list/model/app_list_model.h" -#include "ash/app_list/model/search_result.h" +#include "ash/app_list/model/search/search_result.h" #include "base/macros.h" #include "base/run_loop.h" #include "base/strings/utf_string_conversions.h"
diff --git a/chrome/browser/ui/app_list/search/arc/arc_playstore_search_provider_unittest.cc b/chrome/browser/ui/app_list/search/arc/arc_playstore_search_provider_unittest.cc index 541d85b..933ced6 100644 --- a/chrome/browser/ui/app_list/search/arc/arc_playstore_search_provider_unittest.cc +++ b/chrome/browser/ui/app_list/search/arc/arc_playstore_search_provider_unittest.cc
@@ -8,7 +8,7 @@ #include <string> #include <utility> -#include "ash/app_list/model/search_result.h" +#include "ash/app_list/model/search/search_result.h" #include "base/macros.h" #include "base/strings/utf_string_conversions.h" #include "chrome/browser/extensions/extension_service.h"
diff --git a/chrome/browser/ui/app_list/search/arc/arc_playstore_search_result.h b/chrome/browser/ui/app_list/search/arc/arc_playstore_search_result.h index 1c1fe66..9c50df98 100644 --- a/chrome/browser/ui/app_list/search/arc/arc_playstore_search_result.h +++ b/chrome/browser/ui/app_list/search/arc/arc_playstore_search_result.h
@@ -9,7 +9,7 @@ #include <string> #include <vector> -#include "ash/app_list/model/search_result.h" +#include "ash/app_list/model/search/search_result.h" #include "base/optional.h" #include "chrome/browser/ui/app_list/app_context_menu_delegate.h" #include "components/arc/common/app.mojom.h"
diff --git a/chrome/browser/ui/app_list/search/launcher_search/launcher_search_result.h b/chrome/browser/ui/app_list/search/launcher_search/launcher_search_result.h index b68a6c50..29b1a21 100644 --- a/chrome/browser/ui/app_list/search/launcher_search/launcher_search_result.h +++ b/chrome/browser/ui/app_list/search/launcher_search/launcher_search_result.h
@@ -8,7 +8,7 @@ #include <memory> #include <string> -#include "ash/app_list/model/search_result.h" +#include "ash/app_list/model/search/search_result.h" #include "base/macros.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/app_list/search/launcher_search/launcher_search_icon_image_loader.h"
diff --git a/chrome/browser/ui/app_list/search/omnibox_provider.cc b/chrome/browser/ui/app_list/search/omnibox_provider.cc index 9dfb228e..6371754 100644 --- a/chrome/browser/ui/app_list/search/omnibox_provider.cc +++ b/chrome/browser/ui/app_list/search/omnibox_provider.cc
@@ -4,7 +4,7 @@ #include "chrome/browser/ui/app_list/search/omnibox_provider.h" -#include "ash/app_list/model/search_result.h" +#include "ash/app_list/model/search/search_result.h" #include "base/memory/ptr_util.h" #include "chrome/browser/autocomplete/chrome_autocomplete_provider_client.h" #include "chrome/browser/autocomplete/chrome_autocomplete_scheme_classifier.h"
diff --git a/chrome/browser/ui/app_list/search/omnibox_result.h b/chrome/browser/ui/app_list/search/omnibox_result.h index 75ab73f..11cdbba 100644 --- a/chrome/browser/ui/app_list/search/omnibox_result.h +++ b/chrome/browser/ui/app_list/search/omnibox_result.h
@@ -7,7 +7,7 @@ #include <memory> -#include "ash/app_list/model/search_result.h" +#include "ash/app_list/model/search/search_result.h" #include "base/macros.h" #include "components/omnibox/browser/autocomplete_match.h"
diff --git a/chrome/browser/ui/app_list/search/search_controller_factory.cc b/chrome/browser/ui/app_list/search/search_controller_factory.cc index eb4814af..63e89701 100644 --- a/chrome/browser/ui/app_list/search/search_controller_factory.cc +++ b/chrome/browser/ui/app_list/search/search_controller_factory.cc
@@ -6,7 +6,6 @@ #include <stddef.h> -#include "ash/app_list/model/app_list_model.h" #include "base/command_line.h" #include "base/memory/ptr_util.h" #include "base/metrics/field_trial.h" @@ -72,10 +71,11 @@ std::unique_ptr<SearchController> CreateSearchController( Profile* profile, AppListModel* model, + SearchModel* search_model, AppListControllerDelegate* list_controller) { std::unique_ptr<SearchController> controller = base::MakeUnique<SearchController>( - model->search_box(), model->results(), + search_model->search_box(), search_model->results(), HistoryFactory::GetForBrowserContext(profile)); // Add mixer groups. There are four main groups: answer card, apps, webstore @@ -109,7 +109,7 @@ controller->AddProvider( answer_card_group_id, base::MakeUnique<AnswerCardSearchProvider>( - profile, model, list_controller, + profile, search_model, list_controller, base::MakeUnique<AnswerCardWebContents>(profile), base::MakeUnique<AnswerCardWebContents>(profile))); }
diff --git a/chrome/browser/ui/app_list/search/search_controller_factory.h b/chrome/browser/ui/app_list/search/search_controller_factory.h index 56a2939d..e662b0a4 100644 --- a/chrome/browser/ui/app_list/search/search_controller_factory.h +++ b/chrome/browser/ui/app_list/search/search_controller_factory.h
@@ -8,6 +8,7 @@ #include <memory> #include "ash/app_list/model/app_list_model.h" +#include "ash/app_list/model/search/search_model.h" class AppListControllerDelegate; class Profile; @@ -20,6 +21,7 @@ std::unique_ptr<SearchController> CreateSearchController( Profile* profile, AppListModel* model, + SearchModel* search_model, AppListControllerDelegate* list_controller); } // namespace app_list
diff --git a/chrome/browser/ui/app_list/search/search_resource_manager.cc b/chrome/browser/ui/app_list/search/search_resource_manager.cc index d596886..824987c 100644 --- a/chrome/browser/ui/app_list/search/search_resource_manager.cc +++ b/chrome/browser/ui/app_list/search/search_resource_manager.cc
@@ -6,7 +6,7 @@ #include <memory> -#include "ash/app_list/model/search_box_model.h" +#include "ash/app_list/model/search/search_box_model.h" #include "base/memory/ptr_util.h" #include "chrome/browser/ui/app_list/start_page_service.h" #include "chrome/grit/generated_resources.h"
diff --git a/chrome/browser/ui/app_list/search/search_webstore_result.h b/chrome/browser/ui/app_list/search/search_webstore_result.h index 26c53c3..a8a41579 100644 --- a/chrome/browser/ui/app_list/search/search_webstore_result.h +++ b/chrome/browser/ui/app_list/search/search_webstore_result.h
@@ -5,9 +5,10 @@ #ifndef CHROME_BROWSER_UI_APP_LIST_SEARCH_SEARCH_WEBSTORE_RESULT_H_ #define CHROME_BROWSER_UI_APP_LIST_SEARCH_SEARCH_WEBSTORE_RESULT_H_ +#include <memory> #include <string> -#include "ash/app_list/model/search_result.h" +#include "ash/app_list/model/search/search_result.h" #include "base/macros.h" #include "url/gurl.h"
diff --git a/chrome/browser/ui/app_list/search/suggestions/suggestions_search_provider_unittest.cc b/chrome/browser/ui/app_list/search/suggestions/suggestions_search_provider_unittest.cc index 094944a0..a6bc2049 100644 --- a/chrome/browser/ui/app_list/search/suggestions/suggestions_search_provider_unittest.cc +++ b/chrome/browser/ui/app_list/search/suggestions/suggestions_search_provider_unittest.cc
@@ -11,7 +11,7 @@ #include <string> #include <vector> -#include "ash/app_list/model/search_result.h" +#include "ash/app_list/model/search/search_result.h" #include "base/macros.h" #include "base/strings/utf_string_conversions.h" #include "chrome/browser/sync/profile_sync_test_util.h"
diff --git a/chrome/browser/ui/app_list/search/suggestions/url_suggestion_result.h b/chrome/browser/ui/app_list/search/suggestions/url_suggestion_result.h index 8e8afdf..e5fb46f 100644 --- a/chrome/browser/ui/app_list/search/suggestions/url_suggestion_result.h +++ b/chrome/browser/ui/app_list/search/suggestions/url_suggestion_result.h
@@ -7,7 +7,7 @@ #include <memory> -#include "ash/app_list/model/search_result.h" +#include "ash/app_list/model/search/search_result.h" #include "base/macros.h" #include "base/task/cancelable_task_tracker.h" #include "components/suggestions/proto/suggestions.pb.h"
diff --git a/chrome/browser/ui/app_list/search/webstore/webstore_provider_browsertest.cc b/chrome/browser/ui/app_list/search/webstore/webstore_provider_browsertest.cc index 1ced97a54..cae5956 100644 --- a/chrome/browser/ui/app_list/search/webstore/webstore_provider_browsertest.cc +++ b/chrome/browser/ui/app_list/search/webstore/webstore_provider_browsertest.cc
@@ -11,7 +11,7 @@ #include <string> #include <utility> -#include "ash/app_list/model/search_result.h" +#include "ash/app_list/model/search/search_result.h" #include "base/bind.h" #include "base/command_line.h" #include "base/macros.h"
diff --git a/chrome/browser/ui/app_list/search/webstore/webstore_result.h b/chrome/browser/ui/app_list/search/webstore/webstore_result.h index 12582ee..f60c91c 100644 --- a/chrome/browser/ui/app_list/search/webstore/webstore_result.h +++ b/chrome/browser/ui/app_list/search/webstore/webstore_result.h
@@ -5,9 +5,10 @@ #ifndef CHROME_BROWSER_UI_APP_LIST_SEARCH_WEBSTORE_WEBSTORE_RESULT_H_ #define CHROME_BROWSER_UI_APP_LIST_SEARCH_WEBSTORE_WEBSTORE_RESULT_H_ +#include <memory> #include <string> -#include "ash/app_list/model/search_result.h" +#include "ash/app_list/model/search/search_result.h" #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "chrome/browser/extensions/install_observer.h"
diff --git a/chrome/browser/ui/app_list/test/chrome_app_list_test_support.cc b/chrome/browser/ui/app_list/test/chrome_app_list_test_support.cc index 7695efd..c9a3ac3a 100644 --- a/chrome/browser/ui/app_list/test/chrome_app_list_test_support.cc +++ b/chrome/browser/ui/app_list/test/chrome_app_list_test_support.cc
@@ -4,6 +4,8 @@ #include "chrome/browser/ui/app_list/test/chrome_app_list_test_support.h" +#include <string> + #include "base/macros.h" #include "base/run_loop.h" #include "chrome/browser/browser_process.h" @@ -57,6 +59,12 @@ service->GetCurrentAppListProfile())->GetModel(); } +app_list::SearchModel* GetSearchModel(AppListService* service) { + return app_list::AppListSyncableServiceFactory::GetForProfile( + service->GetCurrentAppListProfile()) + ->GetSearchModel(); +} + AppListServiceImpl* GetAppListServiceImpl() { // AppListServiceImpl is the only subclass of AppListService, which has pure // virtuals. So this must either be NULL, or an AppListServiceImpl.
diff --git a/chrome/browser/ui/app_list/test/chrome_app_list_test_support.h b/chrome/browser/ui/app_list/test/chrome_app_list_test_support.h index 1218fee..97079a86 100644 --- a/chrome/browser/ui/app_list/test/chrome_app_list_test_support.h +++ b/chrome/browser/ui/app_list/test/chrome_app_list_test_support.h
@@ -7,6 +7,7 @@ namespace app_list { class AppListModel; +class SearchModel; } class AppListService; @@ -18,6 +19,10 @@ // Gets the model keyed to the profile currently associated with |service|. app_list::AppListModel* GetAppListModel(AppListService* service); +// Gets the search model keyed to the profile currently associated with +// |service|. +app_list::SearchModel* GetSearchModel(AppListService* service); + AppListServiceImpl* GetAppListServiceImpl(); // Creates a second profile in a nested run loop for testing the app list.
diff --git a/chrome/browser/ui/ash/accelerator_commands_browsertest.cc b/chrome/browser/ui/ash/accelerator_commands_browsertest.cc index 1369a53..e134b320 100644 --- a/chrome/browser/ui/ash/accelerator_commands_browsertest.cc +++ b/chrome/browser/ui/ash/accelerator_commands_browsertest.cc
@@ -4,7 +4,7 @@ #include "ash/accelerators/accelerator_commands.h" -#include "ash/accelerators/accelerator_commands_classic.h" +#include "ash/accelerators/accelerator_commands.h" #include "ash/shell.h" #include "ash/wm/window_state.h" #include "base/command_line.h"
diff --git a/chrome/browser/ui/content_settings/content_setting_bubble_model.cc b/chrome/browser/ui/content_settings/content_setting_bubble_model.cc index 7d7775c..dd09cfac 100644 --- a/chrome/browser/ui/content_settings/content_setting_bubble_model.cc +++ b/chrome/browser/ui/content_settings/content_setting_bubble_model.cc
@@ -6,6 +6,9 @@ #include <stddef.h> +#include <memory> +#include <utility> + #include "base/command_line.h" #include "base/feature_list.h" #include "base/macros.h" @@ -76,14 +79,6 @@ namespace { -// These states must match the order of appearance of the radio buttons -// in the XIB file for the Mac port. -enum RPHState { - RPH_ALLOW = 0, - RPH_BLOCK, - RPH_IGNORE, -}; - struct ContentSettingsTypeIdEntry { ContentSettingsType type; int id; @@ -99,25 +94,14 @@ return 0; } -const content::MediaStreamDevice& GetMediaDeviceById( - const std::string& device_id, - const content::MediaStreamDevices& devices) { - DCHECK(!devices.empty()); - for (const content::MediaStreamDevice& device : devices) { - if (device.id == device_id) - return device; - } - - // A device with the |device_id| was not found. It is likely that the device - // has been unplugged from the OS. Return the first device as the default - // device. - return *devices.begin(); +void SetAllowRunningInsecureContent(content::RenderFrameHost* frame) { + chrome::mojom::InsecureContentRendererPtr renderer; + frame->GetRemoteInterfaces()->GetInterface(&renderer); + renderer->SetAllowRunningInsecureContent(); } } // namespace -const int ContentSettingBubbleModel::kAllowButtonIndex = 0; - // ContentSettingSimpleBubbleModel --------------------------------------------- ContentSettingSimpleBubbleModel::ContentSettingSimpleBubbleModel( @@ -240,6 +224,512 @@ void ContentSettingSimpleBubbleModel::OnCustomLinkClicked() { } +// ContentSettingMixedScriptBubbleModel ---------------------------------------- + +class ContentSettingMixedScriptBubbleModel + : public ContentSettingSimpleBubbleModel { + public: + ContentSettingMixedScriptBubbleModel(Delegate* delegate, + WebContents* web_contents, + Profile* profile); + + ~ContentSettingMixedScriptBubbleModel() override {} + + private: + void SetManageText(); + + // ContentSettingBubbleModel: + void OnLearnMoreClicked() override; + void OnCustomLinkClicked() override; + + DISALLOW_COPY_AND_ASSIGN(ContentSettingMixedScriptBubbleModel); +}; + +ContentSettingMixedScriptBubbleModel::ContentSettingMixedScriptBubbleModel( + Delegate* delegate, + WebContents* web_contents, + Profile* profile) + : ContentSettingSimpleBubbleModel(delegate, + web_contents, + profile, + CONTENT_SETTINGS_TYPE_MIXEDSCRIPT) { + content_settings::RecordMixedScriptAction( + content_settings::MIXED_SCRIPT_ACTION_DISPLAYED_BUBBLE); + set_custom_link_enabled(true); + set_show_learn_more(true); + SetManageText(); +} + +void ContentSettingMixedScriptBubbleModel::OnLearnMoreClicked() { + if (delegate()) + delegate()->ShowLearnMorePage(content_type()); + + content_settings::RecordMixedScriptAction( + content_settings::MIXED_SCRIPT_ACTION_CLICKED_LEARN_MORE); +} + +void ContentSettingMixedScriptBubbleModel::OnCustomLinkClicked() { + DCHECK(rappor_service()); + if (!web_contents()) + return; + + MixedContentSettingsTabHelper* mixed_content_settings = + MixedContentSettingsTabHelper::FromWebContents(web_contents()); + if (mixed_content_settings) { + // Update browser side settings to allow active mixed content. + mixed_content_settings->AllowRunningOfInsecureContent(); + } + + // Update renderer side settings to allow active mixed content. + web_contents()->ForEachFrame( + base::BindRepeating(&::SetAllowRunningInsecureContent)); + + content_settings::RecordMixedScriptAction( + content_settings::MIXED_SCRIPT_ACTION_CLICKED_ALLOW); + + rappor::SampleDomainAndRegistryFromGURL( + rappor_service(), "ContentSettings.MixedScript.UserClickedAllow", + web_contents()->GetLastCommittedURL()); +} + +// Don't set any manage text since none is displayed. +void ContentSettingMixedScriptBubbleModel::SetManageText() { + set_manage_text_style(ContentSettingBubbleModel::ManageTextStyle::kNone); +} + +// ContentSettingRPHBubbleModel ------------------------------------------------ + +namespace { + +// These states must match the order of appearance of the radio buttons +// in the XIB file for the Mac port. +enum RPHState { + RPH_ALLOW = 0, + RPH_BLOCK, + RPH_IGNORE, +}; + +} // namespace + +ContentSettingRPHBubbleModel::ContentSettingRPHBubbleModel( + Delegate* delegate, + WebContents* web_contents, + Profile* profile, + ProtocolHandlerRegistry* registry) + : ContentSettingSimpleBubbleModel(delegate, + web_contents, + profile, + CONTENT_SETTINGS_TYPE_PROTOCOL_HANDLERS), + selected_item_(0), + interacted_(false), + registry_(registry), + pending_handler_(ProtocolHandler::EmptyProtocolHandler()), + previous_handler_(ProtocolHandler::EmptyProtocolHandler()) { + TabSpecificContentSettings* content_settings = + TabSpecificContentSettings::FromWebContents(web_contents); + pending_handler_ = content_settings->pending_protocol_handler(); + previous_handler_ = content_settings->previous_protocol_handler(); + + base::string16 protocol; + if (pending_handler_.protocol() == "mailto") { + protocol = + l10n_util::GetStringUTF16(IDS_REGISTER_PROTOCOL_HANDLER_MAILTO_NAME); + } else if (pending_handler_.protocol() == "webcal") { + protocol = + l10n_util::GetStringUTF16(IDS_REGISTER_PROTOCOL_HANDLER_WEBCAL_NAME); + } else { + protocol = base::UTF8ToUTF16(pending_handler_.protocol()); + } + + // Note that we ignore the |title| parameter. + if (previous_handler_.IsEmpty()) { + set_title(l10n_util::GetStringFUTF16( + IDS_REGISTER_PROTOCOL_HANDLER_CONFIRM, + base::UTF8ToUTF16(pending_handler_.url().host()), protocol)); + } else { + set_title(l10n_util::GetStringFUTF16( + IDS_REGISTER_PROTOCOL_HANDLER_CONFIRM_REPLACE, + base::UTF8ToUTF16(pending_handler_.url().host()), protocol, + base::UTF8ToUTF16(previous_handler_.url().host()))); + } + + base::string16 radio_allow_label = + l10n_util::GetStringUTF16(IDS_REGISTER_PROTOCOL_HANDLER_ACCEPT); + base::string16 radio_deny_label = + l10n_util::GetStringUTF16(IDS_REGISTER_PROTOCOL_HANDLER_DENY); + base::string16 radio_ignore_label = + l10n_util::GetStringUTF16(IDS_REGISTER_PROTOCOL_HANDLER_IGNORE); + + const GURL& url = web_contents->GetURL(); + RadioGroup radio_group; + radio_group.url = url; + + radio_group.radio_items.push_back(radio_allow_label); + radio_group.radio_items.push_back(radio_deny_label); + radio_group.radio_items.push_back(radio_ignore_label); + ContentSetting setting = content_settings->pending_protocol_handler_setting(); + if (setting == CONTENT_SETTING_ALLOW) + radio_group.default_item = RPH_ALLOW; + else if (setting == CONTENT_SETTING_BLOCK) + radio_group.default_item = RPH_BLOCK; + else + radio_group.default_item = RPH_IGNORE; + + selected_item_ = radio_group.default_item; + set_radio_group_enabled(true); + set_radio_group(radio_group); +} + +ContentSettingRPHBubbleModel::~ContentSettingRPHBubbleModel() { + if (!web_contents() || !interacted_) + return; + + // The user has one chance to deal with the RPH content setting UI, + // then we remove it. + auto* settings = TabSpecificContentSettings::FromWebContents(web_contents()); + settings->ClearPendingProtocolHandler(); + content::NotificationService::current()->Notify( + chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED, + content::Source<WebContents>(web_contents()), + content::NotificationService::NoDetails()); +} + +void ContentSettingRPHBubbleModel::OnRadioClicked(int radio_index) { + if (selected_item_ == radio_index) + return; + + interacted_ = true; + selected_item_ = radio_index; + + if (radio_index == RPH_ALLOW) + RegisterProtocolHandler(); + else if (radio_index == RPH_BLOCK) + UnregisterProtocolHandler(); + else if (radio_index == RPH_IGNORE) + IgnoreProtocolHandler(); + else + NOTREACHED(); +} + +void ContentSettingRPHBubbleModel::OnDoneClicked() { + interacted_ = true; +} + +void ContentSettingRPHBubbleModel::RegisterProtocolHandler() { + if (!web_contents()) + return; + + // A no-op if the handler hasn't been ignored, but needed in case the user + // selects sequences like register/ignore/register. + registry_->RemoveIgnoredHandler(pending_handler_); + + registry_->OnAcceptRegisterProtocolHandler(pending_handler_); + TabSpecificContentSettings::FromWebContents(web_contents()) + ->set_pending_protocol_handler_setting(CONTENT_SETTING_ALLOW); +} + +void ContentSettingRPHBubbleModel::UnregisterProtocolHandler() { + if (!web_contents()) + return; + + registry_->OnDenyRegisterProtocolHandler(pending_handler_); + auto* settings = TabSpecificContentSettings::FromWebContents(web_contents()); + settings->set_pending_protocol_handler_setting(CONTENT_SETTING_BLOCK); + ClearOrSetPreviousHandler(); +} + +void ContentSettingRPHBubbleModel::IgnoreProtocolHandler() { + if (!web_contents()) + return; + + registry_->OnIgnoreRegisterProtocolHandler(pending_handler_); + auto* settings = TabSpecificContentSettings::FromWebContents(web_contents()); + settings->set_pending_protocol_handler_setting(CONTENT_SETTING_DEFAULT); + ClearOrSetPreviousHandler(); +} + +void ContentSettingRPHBubbleModel::ClearOrSetPreviousHandler() { + if (previous_handler_.IsEmpty()) { + registry_->ClearDefault(pending_handler_.protocol()); + } else { + registry_->OnAcceptRegisterProtocolHandler(previous_handler_); + } +} + +// ContentSettingMidiSysExBubbleModel ------------------------------------------ + +class ContentSettingMidiSysExBubbleModel + : public ContentSettingSimpleBubbleModel { + public: + ContentSettingMidiSysExBubbleModel(Delegate* delegate, + WebContents* web_contents, + Profile* profile); + ~ContentSettingMidiSysExBubbleModel() override {} + + private: + void MaybeAddDomainList(const std::set<std::string>& hosts, int title_id); + void SetDomainsAndCustomLink(); + void OnCustomLinkClicked() override; + + DISALLOW_COPY_AND_ASSIGN(ContentSettingMidiSysExBubbleModel); +}; + +ContentSettingMidiSysExBubbleModel::ContentSettingMidiSysExBubbleModel( + Delegate* delegate, + WebContents* web_contents, + Profile* profile) + : ContentSettingSimpleBubbleModel(delegate, + web_contents, + profile, + CONTENT_SETTINGS_TYPE_MIDI_SYSEX) { + SetDomainsAndCustomLink(); +} + +void ContentSettingMidiSysExBubbleModel::MaybeAddDomainList( + const std::set<std::string>& hosts, + int title_id) { + if (!hosts.empty()) { + DomainList domain_list; + domain_list.title = l10n_util::GetStringUTF16(title_id); + domain_list.hosts = hosts; + add_domain_list(domain_list); + } +} + +void ContentSettingMidiSysExBubbleModel::SetDomainsAndCustomLink() { + TabSpecificContentSettings* content_settings = + TabSpecificContentSettings::FromWebContents(web_contents()); + const ContentSettingsUsagesState& usages_state = + content_settings->midi_usages_state(); + ContentSettingsUsagesState::FormattedHostsPerState formatted_hosts_per_state; + unsigned int tab_state_flags = 0; + usages_state.GetDetailedInfo(&formatted_hosts_per_state, &tab_state_flags); + // Divide the tab's current MIDI sysex users into sets according to their + // permission state. + MaybeAddDomainList(formatted_hosts_per_state[CONTENT_SETTING_ALLOW], + IDS_MIDI_SYSEX_BUBBLE_ALLOWED); + + MaybeAddDomainList(formatted_hosts_per_state[CONTENT_SETTING_BLOCK], + IDS_MIDI_SYSEX_BUBBLE_DENIED); + + if (tab_state_flags & ContentSettingsUsagesState::TABSTATE_HAS_EXCEPTION) { + set_custom_link( + l10n_util::GetStringUTF16(IDS_MIDI_SYSEX_BUBBLE_CLEAR_LINK)); + set_custom_link_enabled(true); + } else if (tab_state_flags & + ContentSettingsUsagesState::TABSTATE_HAS_CHANGED) { + set_custom_link(l10n_util::GetStringUTF16( + IDS_MIDI_SYSEX_BUBBLE_REQUIRE_RELOAD_TO_CLEAR)); + } +} + +void ContentSettingMidiSysExBubbleModel::OnCustomLinkClicked() { + if (!web_contents()) + return; + // Reset this embedder's entry to default for each of the requesting + // origins currently on the page. + const GURL& embedder_url = web_contents()->GetURL(); + TabSpecificContentSettings* content_settings = + TabSpecificContentSettings::FromWebContents(web_contents()); + const ContentSettingsUsagesState::StateMap& state_map = + content_settings->midi_usages_state().state_map(); + HostContentSettingsMap* map = + HostContentSettingsMapFactory::GetForProfile(profile()); + for (const std::pair<GURL, ContentSetting>& map_entry : state_map) { + PermissionUtil::ScopedRevocationReporter( + profile(), map_entry.first, embedder_url, + CONTENT_SETTINGS_TYPE_MIDI_SYSEX, PermissionSourceUI::PAGE_ACTION); + map->SetContentSettingDefaultScope(map_entry.first, embedder_url, + CONTENT_SETTINGS_TYPE_MIDI_SYSEX, + std::string(), CONTENT_SETTING_DEFAULT); + } +} + +// ContentSettingDomainListBubbleModel ----------------------------------------- + +class ContentSettingDomainListBubbleModel + : public ContentSettingSimpleBubbleModel { + public: + ContentSettingDomainListBubbleModel(Delegate* delegate, + WebContents* web_contents, + Profile* profile, + ContentSettingsType content_type); + ~ContentSettingDomainListBubbleModel() override {} + + private: + void MaybeAddDomainList(const std::set<std::string>& hosts, int title_id); + void SetDomainsAndCustomLink(); + void OnCustomLinkClicked() override; + + DISALLOW_COPY_AND_ASSIGN(ContentSettingDomainListBubbleModel); +}; + +ContentSettingDomainListBubbleModel::ContentSettingDomainListBubbleModel( + Delegate* delegate, + WebContents* web_contents, + Profile* profile, + ContentSettingsType content_type) + : ContentSettingSimpleBubbleModel(delegate, + web_contents, + profile, + content_type) { + DCHECK_EQ(CONTENT_SETTINGS_TYPE_GEOLOCATION, content_type) + << "SetDomains currently only supports geolocation content type"; + SetDomainsAndCustomLink(); +} + +void ContentSettingDomainListBubbleModel::MaybeAddDomainList( + const std::set<std::string>& hosts, + int title_id) { + if (!hosts.empty()) { + DomainList domain_list; + domain_list.title = l10n_util::GetStringUTF16(title_id); + domain_list.hosts = hosts; + add_domain_list(domain_list); + } +} + +void ContentSettingDomainListBubbleModel::SetDomainsAndCustomLink() { + TabSpecificContentSettings* content_settings = + TabSpecificContentSettings::FromWebContents(web_contents()); + const ContentSettingsUsagesState& usages = + content_settings->geolocation_usages_state(); + ContentSettingsUsagesState::FormattedHostsPerState formatted_hosts_per_state; + unsigned int tab_state_flags = 0; + usages.GetDetailedInfo(&formatted_hosts_per_state, &tab_state_flags); + // Divide the tab's current geolocation users into sets according to their + // permission state. + MaybeAddDomainList(formatted_hosts_per_state[CONTENT_SETTING_ALLOW], + IDS_GEOLOCATION_BUBBLE_SECTION_ALLOWED); + + MaybeAddDomainList(formatted_hosts_per_state[CONTENT_SETTING_BLOCK], + IDS_GEOLOCATION_BUBBLE_SECTION_DENIED); + + if (tab_state_flags & ContentSettingsUsagesState::TABSTATE_HAS_EXCEPTION) { + set_custom_link( + l10n_util::GetStringUTF16(IDS_GEOLOCATION_BUBBLE_CLEAR_LINK)); + set_custom_link_enabled(true); + } else if (tab_state_flags & + ContentSettingsUsagesState::TABSTATE_HAS_CHANGED) { + set_custom_link(l10n_util::GetStringUTF16( + IDS_GEOLOCATION_BUBBLE_REQUIRE_RELOAD_TO_CLEAR)); + } +} + +void ContentSettingDomainListBubbleModel::OnCustomLinkClicked() { + if (!web_contents()) + return; + // Reset this embedder's entry to default for each of the requesting + // origins currently on the page. + const GURL& embedder_url = web_contents()->GetURL(); + TabSpecificContentSettings* content_settings = + TabSpecificContentSettings::FromWebContents(web_contents()); + const ContentSettingsUsagesState::StateMap& state_map = + content_settings->geolocation_usages_state().state_map(); + HostContentSettingsMap* map = + HostContentSettingsMapFactory::GetForProfile(profile()); + for (const std::pair<GURL, ContentSetting>& map_entry : state_map) { + PermissionUtil::ScopedRevocationReporter( + profile(), map_entry.first, embedder_url, + CONTENT_SETTINGS_TYPE_GEOLOCATION, PermissionSourceUI::PAGE_ACTION); + map->SetContentSettingDefaultScope(map_entry.first, embedder_url, + CONTENT_SETTINGS_TYPE_GEOLOCATION, + std::string(), CONTENT_SETTING_DEFAULT); + } +} + +// ContentSettingPluginBubbleModel --------------------------------------------- + +class ContentSettingPluginBubbleModel : public ContentSettingSimpleBubbleModel { + public: + ContentSettingPluginBubbleModel(Delegate* delegate, + WebContents* web_contents, + Profile* profile); + + private: + void OnLearnMoreClicked() override; + void OnCustomLinkClicked() override; + + void RunPluginsOnPage(); + + DISALLOW_COPY_AND_ASSIGN(ContentSettingPluginBubbleModel); +}; + +ContentSettingPluginBubbleModel::ContentSettingPluginBubbleModel( + Delegate* delegate, + WebContents* web_contents, + Profile* profile) + : ContentSettingSimpleBubbleModel(delegate, + web_contents, + profile, + CONTENT_SETTINGS_TYPE_PLUGINS) { + SettingInfo info; + HostContentSettingsMap* map = + HostContentSettingsMapFactory::GetForProfile(profile); + GURL url = web_contents->GetURL(); + std::unique_ptr<base::Value> value = + map->GetWebsiteSetting(url, url, content_type(), std::string(), &info); + ContentSetting setting = content_settings::ValueToContentSetting(value.get()); + + // If the setting is not managed by the user, hide the "Manage" button. + if (info.source != SETTING_SOURCE_USER) + set_manage_text_style(ContentSettingBubbleModel::ManageTextStyle::kNone); + + // The user cannot manually run Flash on the BLOCK setting when either holds: + // - The setting is from Policy. User cannot override admin intent. + // - HTML By Default is on - Flash has been hidden from the plugin list, so + // it's impossible to dynamically run the nonexistent plugin. + bool run_blocked = setting == CONTENT_SETTING_BLOCK && + (info.source != SETTING_SOURCE_USER || + PluginUtils::ShouldPreferHtmlOverPlugins(map)); + + if (!run_blocked) { + set_custom_link(l10n_util::GetStringUTF16(IDS_BLOCKED_PLUGINS_LOAD_ALL)); + // Disable the "Run all plugins this time" link if the user already clicked + // on the link and ran all plugins. + set_custom_link_enabled( + web_contents && + TabSpecificContentSettings::FromWebContents(web_contents) + ->load_plugins_link_enabled()); + } + + set_show_learn_more(true); + + content_settings::RecordPluginsAction( + content_settings::PLUGINS_ACTION_DISPLAYED_BUBBLE); +} + +void ContentSettingPluginBubbleModel::OnLearnMoreClicked() { + if (delegate()) + delegate()->ShowLearnMorePage(CONTENT_SETTINGS_TYPE_PLUGINS); + + content_settings::RecordPluginsAction( + content_settings::PLUGINS_ACTION_CLICKED_LEARN_MORE); +} + +void ContentSettingPluginBubbleModel::OnCustomLinkClicked() { + base::RecordAction(UserMetricsAction("ClickToPlay_LoadAll_Bubble")); + content_settings::RecordPluginsAction( + content_settings::PLUGINS_ACTION_CLICKED_RUN_ALL_PLUGINS_THIS_TIME); + + RunPluginsOnPage(); +} + +void ContentSettingPluginBubbleModel::RunPluginsOnPage() { + // Web contents can be NULL if the tab was closed while the plugins + // settings bubble is visible. + if (!web_contents()) + return; +#if BUILDFLAG(ENABLE_PLUGINS) + // TODO(bauerb): We should send the identifiers of blocked plugins here. + ChromePluginServiceFilter::GetInstance()->AuthorizeAllPlugins( + web_contents(), true, std::string()); +#endif + set_custom_link_enabled(false); + TabSpecificContentSettings::FromWebContents(web_contents()) + ->set_load_plugins_link_enabled(false); +} + // ContentSettingSingleRadioGroup ---------------------------------------------- class ContentSettingSingleRadioGroup : public ContentSettingSimpleBubbleModel { @@ -281,10 +771,9 @@ ContentSettingSingleRadioGroup::~ContentSettingSingleRadioGroup() { if (settings_changed()) { - ContentSetting setting = - selected_item_ == kAllowButtonIndex ? - CONTENT_SETTING_ALLOW : - block_setting_; + ContentSetting setting = selected_item_ == kAllowButtonIndex + ? CONTENT_SETTING_ALLOW + : block_setting_; SetNarrowestContentSetting(setting); } } @@ -297,8 +786,7 @@ // content type and setting the default value based on the content setting. void ContentSettingSingleRadioGroup::SetRadioGroup() { GURL url = web_contents()->GetURL(); - base::string16 display_host = - url_formatter::FormatUrlForSecurityDisplay(url); + base::string16 display_host = url_formatter::FormatUrlForSecurityDisplay(url); if (display_host.empty()) display_host = base::ASCIIToUTF16(url.spec()); @@ -320,15 +808,14 @@ }; // Fields as for kBlockedAllowIDs, above. static const ContentSettingsTypeIdEntry kAllowedAllowIDs[] = { - {CONTENT_SETTINGS_TYPE_COOKIES, IDS_ALLOWED_COOKIES_NO_ACTION}, - {CONTENT_SETTINGS_TYPE_PPAPI_BROKER, IDS_ALLOWED_PPAPI_BROKER_NO_ACTION}, + {CONTENT_SETTINGS_TYPE_COOKIES, IDS_ALLOWED_COOKIES_NO_ACTION}, + {CONTENT_SETTINGS_TYPE_PPAPI_BROKER, IDS_ALLOWED_PPAPI_BROKER_NO_ACTION}, }; base::string16 radio_allow_label; if (allowed) { - int resource_id = GetIdForContentType(kAllowedAllowIDs, - arraysize(kAllowedAllowIDs), - content_type()); + int resource_id = GetIdForContentType( + kAllowedAllowIDs, arraysize(kAllowedAllowIDs), content_type()); radio_allow_label = l10n_util::GetStringUTF16(resource_id); } else { radio_allow_label = l10n_util::GetStringFUTF16( @@ -346,8 +833,8 @@ {CONTENT_SETTINGS_TYPE_SOUND, IDS_BLOCKED_SOUND_NO_ACTION}, }; static const ContentSettingsTypeIdEntry kAllowedBlockIDs[] = { - {CONTENT_SETTINGS_TYPE_COOKIES, IDS_ALLOWED_COOKIES_BLOCK}, - {CONTENT_SETTINGS_TYPE_PPAPI_BROKER, IDS_ALLOWED_PPAPI_BROKER_BLOCK}, + {CONTENT_SETTINGS_TYPE_COOKIES, IDS_ALLOWED_COOKIES_BLOCK}, + {CONTENT_SETTINGS_TYPE_PPAPI_BROKER, IDS_ALLOWED_PPAPI_BROKER_BLOCK}, }; base::string16 radio_block_label; @@ -458,98 +945,6 @@ delegate()->ShowCollectedCookiesDialog(web_contents()); } -// ContentSettingPluginBubbleModel --------------------------------------------- - -class ContentSettingPluginBubbleModel : public ContentSettingSimpleBubbleModel { - public: - ContentSettingPluginBubbleModel(Delegate* delegate, - WebContents* web_contents, - Profile* profile); - - private: - void OnLearnMoreClicked() override; - void OnCustomLinkClicked() override; - - void RunPluginsOnPage(); - - DISALLOW_COPY_AND_ASSIGN(ContentSettingPluginBubbleModel); -}; - -ContentSettingPluginBubbleModel::ContentSettingPluginBubbleModel( - Delegate* delegate, - WebContents* web_contents, - Profile* profile) - : ContentSettingSimpleBubbleModel(delegate, - web_contents, - profile, - CONTENT_SETTINGS_TYPE_PLUGINS) { - SettingInfo info; - HostContentSettingsMap* map = - HostContentSettingsMapFactory::GetForProfile(profile); - GURL url = web_contents->GetURL(); - std::unique_ptr<base::Value> value = - map->GetWebsiteSetting(url, url, content_type(), std::string(), &info); - ContentSetting setting = content_settings::ValueToContentSetting(value.get()); - - // If the setting is not managed by the user, hide the "Manage" button. - if (info.source != SETTING_SOURCE_USER) - set_manage_text_style(ContentSettingBubbleModel::ManageTextStyle::kNone); - - // The user cannot manually run Flash on the BLOCK setting when either holds: - // - The setting is from Policy. User cannot override admin intent. - // - HTML By Default is on - Flash has been hidden from the plugin list, so - // it's impossible to dynamically run the nonexistent plugin. - bool run_blocked = setting == CONTENT_SETTING_BLOCK && - (info.source != SETTING_SOURCE_USER || - PluginUtils::ShouldPreferHtmlOverPlugins(map)); - - if (!run_blocked) { - set_custom_link(l10n_util::GetStringUTF16(IDS_BLOCKED_PLUGINS_LOAD_ALL)); - // Disable the "Run all plugins this time" link if the user already clicked - // on the link and ran all plugins. - set_custom_link_enabled( - web_contents && - TabSpecificContentSettings::FromWebContents(web_contents) - ->load_plugins_link_enabled()); - } - - set_show_learn_more(true); - - content_settings::RecordPluginsAction( - content_settings::PLUGINS_ACTION_DISPLAYED_BUBBLE); -} - -void ContentSettingPluginBubbleModel::OnLearnMoreClicked() { - if (delegate()) - delegate()->ShowLearnMorePage(CONTENT_SETTINGS_TYPE_PLUGINS); - - content_settings::RecordPluginsAction( - content_settings::PLUGINS_ACTION_CLICKED_LEARN_MORE); -} - -void ContentSettingPluginBubbleModel::OnCustomLinkClicked() { - base::RecordAction(UserMetricsAction("ClickToPlay_LoadAll_Bubble")); - content_settings::RecordPluginsAction( - content_settings::PLUGINS_ACTION_CLICKED_RUN_ALL_PLUGINS_THIS_TIME); - - RunPluginsOnPage(); -} - -void ContentSettingPluginBubbleModel::RunPluginsOnPage() { - // Web contents can be NULL if the tab was closed while the plugins - // settings bubble is visible. - if (!web_contents()) - return; -#if BUILDFLAG(ENABLE_PLUGINS) - // TODO(bauerb): We should send the identifiers of blocked plugins here. - ChromePluginServiceFilter::GetInstance()->AuthorizeAllPlugins( - web_contents(), true, std::string()); -#endif - set_custom_link_enabled(false); - TabSpecificContentSettings::FromWebContents(web_contents()) - ->set_load_plugins_link_enabled(false); -} - // ContentSettingPopupBubbleModel ---------------------------------------------- class ContentSettingPopupBubbleModel : public ContentSettingSingleRadioGroup, @@ -655,7 +1050,7 @@ } } -ContentSettingPopupBubbleModel::~ContentSettingPopupBubbleModel(){ +ContentSettingPopupBubbleModel::~ContentSettingPopupBubbleModel() { // User selected to always allow pop-ups from. if (settings_changed() && selected_item() == kAllowButtonIndex) { // Increases the counter. @@ -671,6 +1066,25 @@ // ContentSettingMediaStreamBubbleModel ---------------------------------------- +namespace { + +const content::MediaStreamDevice& GetMediaDeviceById( + const std::string& device_id, + const content::MediaStreamDevices& devices) { + DCHECK(!devices.empty()); + for (const content::MediaStreamDevice& device : devices) { + if (device.id == device_id) + return device; + } + + // A device with the |device_id| was not found. It is likely that the device + // has been unplugged from the OS. Return the first device as the default + // device. + return *devices.begin(); +} + +} // namespace + ContentSettingMediaStreamBubbleModel::ContentSettingMediaStreamBubbleModel( Delegate* delegate, WebContents* web_contents, @@ -720,7 +1134,7 @@ } ContentSettingMediaStreamBubbleModel* - ContentSettingMediaStreamBubbleModel::AsMediaStreamBubbleModel() { +ContentSettingMediaStreamBubbleModel::AsMediaStreamBubbleModel() { return this; } @@ -731,9 +1145,9 @@ if (MicrophoneAccessed() && CameraAccessed()) { delegate()->ShowMediaSettingsPage(); } else { - delegate()->ShowContentSettingsPage(CameraAccessed() - ? CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA - : CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC); + delegate()->ShowContentSettingsPage( + CameraAccessed() ? CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA + : CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC); } } @@ -813,21 +1227,21 @@ radio_item_setting_[0] = CONTENT_SETTING_ALLOW; radio_allow_label_id = IDS_BLOCKED_MEDIASTREAM_CAMERA_ALLOW; if (MicrophoneAccessed()) - radio_allow_label_id = CameraAccessed() ? - IDS_BLOCKED_MEDIASTREAM_MIC_AND_CAMERA_ALLOW : - IDS_BLOCKED_MEDIASTREAM_MIC_ALLOW; + radio_allow_label_id = + CameraAccessed() ? IDS_BLOCKED_MEDIASTREAM_MIC_AND_CAMERA_ALLOW + : IDS_BLOCKED_MEDIASTREAM_MIC_ALLOW; } else { radio_allow_label_id = IDS_BLOCKED_MEDIASTREAM_CAMERA_ASK; if (MicrophoneAccessed()) - radio_allow_label_id = CameraAccessed() ? - IDS_BLOCKED_MEDIASTREAM_MIC_AND_CAMERA_ASK : - IDS_BLOCKED_MEDIASTREAM_MIC_ASK; + radio_allow_label_id = CameraAccessed() + ? IDS_BLOCKED_MEDIASTREAM_MIC_AND_CAMERA_ASK + : IDS_BLOCKED_MEDIASTREAM_MIC_ASK; } radio_block_label_id = IDS_BLOCKED_MEDIASTREAM_CAMERA_NO_ACTION; if (MicrophoneAccessed()) - radio_block_label_id = CameraAccessed() ? - IDS_BLOCKED_MEDIASTREAM_MIC_AND_CAMERA_NO_ACTION : - IDS_BLOCKED_MEDIASTREAM_MIC_NO_ACTION; + radio_block_label_id = + CameraAccessed() ? IDS_BLOCKED_MEDIASTREAM_MIC_AND_CAMERA_NO_ACTION + : IDS_BLOCKED_MEDIASTREAM_MIC_NO_ACTION; } else { if (MicrophoneAccessed() && CameraAccessed()) { radio_allow_label_id = IDS_ALLOWED_MEDIASTREAM_MIC_AND_CAMERA_NO_ACTION; @@ -842,9 +1256,12 @@ } selected_item_ = (MicrophoneAccessed() && content_settings->IsContentBlocked( - CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC)) || - (CameraAccessed() && content_settings->IsContentBlocked( - CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA)) ? 1 : 0; + CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC)) || + (CameraAccessed() && + content_settings->IsContentBlocked( + CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA)) + ? 1 + : 0; base::string16 radio_allow_label = l10n_util::GetStringFUTF16(radio_allow_label_id, display_host); @@ -907,7 +1324,7 @@ TabSpecificContentSettings* content_settings = TabSpecificContentSettings::FromWebContents(web_contents()); const std::string& requested_microphone = - content_settings->media_stream_requested_audio_device(); + content_settings->media_stream_requested_audio_device(); const std::string& requested_camera = content_settings->media_stream_requested_video_device(); @@ -993,335 +1410,12 @@ MediaCaptureDevicesDispatcher* dispatcher = MediaCaptureDevicesDispatcher::GetInstance(); const content::MediaStreamDevices& devices = - (type == content::MEDIA_DEVICE_AUDIO_CAPTURE) ? - dispatcher->GetAudioCaptureDevices() : - dispatcher->GetVideoCaptureDevices(); + (type == content::MEDIA_DEVICE_AUDIO_CAPTURE) + ? dispatcher->GetAudioCaptureDevices() + : dispatcher->GetVideoCaptureDevices(); set_selected_device(GetMediaDeviceById(selected_device_id, devices)); } -// ContentSettingDomainListBubbleModel ----------------------------------------- - -class ContentSettingDomainListBubbleModel - : public ContentSettingSimpleBubbleModel { - public: - ContentSettingDomainListBubbleModel(Delegate* delegate, - WebContents* web_contents, - Profile* profile, - ContentSettingsType content_type); - ~ContentSettingDomainListBubbleModel() override {} - - private: - void MaybeAddDomainList(const std::set<std::string>& hosts, int title_id); - void SetDomainsAndCustomLink(); - void OnCustomLinkClicked() override; - - DISALLOW_COPY_AND_ASSIGN(ContentSettingDomainListBubbleModel); -}; - -ContentSettingDomainListBubbleModel::ContentSettingDomainListBubbleModel( - Delegate* delegate, - WebContents* web_contents, - Profile* profile, - ContentSettingsType content_type) - : ContentSettingSimpleBubbleModel( - delegate, web_contents, profile, content_type) { - DCHECK_EQ(CONTENT_SETTINGS_TYPE_GEOLOCATION, content_type) << - "SetDomains currently only supports geolocation content type"; - SetDomainsAndCustomLink(); -} - -void ContentSettingDomainListBubbleModel::MaybeAddDomainList( - const std::set<std::string>& hosts, int title_id) { - if (!hosts.empty()) { - DomainList domain_list; - domain_list.title = l10n_util::GetStringUTF16(title_id); - domain_list.hosts = hosts; - add_domain_list(domain_list); - } -} - -void ContentSettingDomainListBubbleModel::SetDomainsAndCustomLink() { - TabSpecificContentSettings* content_settings = - TabSpecificContentSettings::FromWebContents(web_contents()); - const ContentSettingsUsagesState& usages = - content_settings->geolocation_usages_state(); - ContentSettingsUsagesState::FormattedHostsPerState formatted_hosts_per_state; - unsigned int tab_state_flags = 0; - usages.GetDetailedInfo(&formatted_hosts_per_state, &tab_state_flags); - // Divide the tab's current geolocation users into sets according to their - // permission state. - MaybeAddDomainList(formatted_hosts_per_state[CONTENT_SETTING_ALLOW], - IDS_GEOLOCATION_BUBBLE_SECTION_ALLOWED); - - MaybeAddDomainList(formatted_hosts_per_state[CONTENT_SETTING_BLOCK], - IDS_GEOLOCATION_BUBBLE_SECTION_DENIED); - - if (tab_state_flags & ContentSettingsUsagesState::TABSTATE_HAS_EXCEPTION) { - set_custom_link( - l10n_util::GetStringUTF16(IDS_GEOLOCATION_BUBBLE_CLEAR_LINK)); - set_custom_link_enabled(true); - } else if (tab_state_flags & - ContentSettingsUsagesState::TABSTATE_HAS_CHANGED) { - set_custom_link(l10n_util::GetStringUTF16( - IDS_GEOLOCATION_BUBBLE_REQUIRE_RELOAD_TO_CLEAR)); - } -} - -void ContentSettingDomainListBubbleModel::OnCustomLinkClicked() { - if (!web_contents()) - return; - // Reset this embedder's entry to default for each of the requesting - // origins currently on the page. - const GURL& embedder_url = web_contents()->GetURL(); - TabSpecificContentSettings* content_settings = - TabSpecificContentSettings::FromWebContents(web_contents()); - const ContentSettingsUsagesState::StateMap& state_map = - content_settings->geolocation_usages_state().state_map(); - HostContentSettingsMap* map = - HostContentSettingsMapFactory::GetForProfile(profile()); - for (const std::pair<GURL, ContentSetting>& map_entry : state_map) { - PermissionUtil::ScopedRevocationReporter( - profile(), map_entry.first, embedder_url, - CONTENT_SETTINGS_TYPE_GEOLOCATION, PermissionSourceUI::PAGE_ACTION); - map->SetContentSettingDefaultScope(map_entry.first, embedder_url, - CONTENT_SETTINGS_TYPE_GEOLOCATION, - std::string(), CONTENT_SETTING_DEFAULT); - } -} - -// ContentSettingMixedScriptBubbleModel ---------------------------------------- - -namespace { - -void SetAllowRunningInsecureContent(content::RenderFrameHost* frame) { - chrome::mojom::InsecureContentRendererPtr renderer; - frame->GetRemoteInterfaces()->GetInterface(&renderer); - renderer->SetAllowRunningInsecureContent(); -} - -} // namespace - -class ContentSettingMixedScriptBubbleModel - : public ContentSettingSimpleBubbleModel { - public: - ContentSettingMixedScriptBubbleModel(Delegate* delegate, - WebContents* web_contents, - Profile* profile); - - ~ContentSettingMixedScriptBubbleModel() override {} - - private: - void SetManageText(); - - // ContentSettingBubbleModel: - void OnLearnMoreClicked() override; - void OnCustomLinkClicked() override; - - DISALLOW_COPY_AND_ASSIGN(ContentSettingMixedScriptBubbleModel); -}; - -ContentSettingMixedScriptBubbleModel::ContentSettingMixedScriptBubbleModel( - Delegate* delegate, - WebContents* web_contents, - Profile* profile) - : ContentSettingSimpleBubbleModel( - delegate, - web_contents, - profile, - CONTENT_SETTINGS_TYPE_MIXEDSCRIPT) { - content_settings::RecordMixedScriptAction( - content_settings::MIXED_SCRIPT_ACTION_DISPLAYED_BUBBLE); - set_custom_link_enabled(true); - set_show_learn_more(true); - SetManageText(); -} - -void ContentSettingMixedScriptBubbleModel::OnLearnMoreClicked() { - if (delegate()) - delegate()->ShowLearnMorePage(content_type()); - - content_settings::RecordMixedScriptAction( - content_settings::MIXED_SCRIPT_ACTION_CLICKED_LEARN_MORE); -} - -void ContentSettingMixedScriptBubbleModel::OnCustomLinkClicked() { - DCHECK(rappor_service()); - if (!web_contents()) - return; - - MixedContentSettingsTabHelper* mixed_content_settings = - MixedContentSettingsTabHelper::FromWebContents(web_contents()); - if (mixed_content_settings) { - // Update browser side settings to allow active mixed content. - mixed_content_settings->AllowRunningOfInsecureContent(); - } - - // Update renderer side settings to allow active mixed content. - web_contents()->ForEachFrame(base::Bind(&::SetAllowRunningInsecureContent)); - - content_settings::RecordMixedScriptAction( - content_settings::MIXED_SCRIPT_ACTION_CLICKED_ALLOW); - - rappor::SampleDomainAndRegistryFromGURL( - rappor_service(), "ContentSettings.MixedScript.UserClickedAllow", - web_contents()->GetLastCommittedURL()); -} - -// Don't set any manage text since none is displayed. -void ContentSettingMixedScriptBubbleModel::SetManageText() { - set_manage_text_style(ContentSettingBubbleModel::ManageTextStyle::kNone); -} - -// ContentSettingRPHBubbleModel ------------------------------------------------ - -ContentSettingRPHBubbleModel::ContentSettingRPHBubbleModel( - Delegate* delegate, - WebContents* web_contents, - Profile* profile, - ProtocolHandlerRegistry* registry) - : ContentSettingSimpleBubbleModel(delegate, - web_contents, - profile, - CONTENT_SETTINGS_TYPE_PROTOCOL_HANDLERS), - selected_item_(0), - interacted_(false), - registry_(registry), - pending_handler_(ProtocolHandler::EmptyProtocolHandler()), - previous_handler_(ProtocolHandler::EmptyProtocolHandler()) { - TabSpecificContentSettings* content_settings = - TabSpecificContentSettings::FromWebContents(web_contents); - pending_handler_ = content_settings->pending_protocol_handler(); - previous_handler_ = content_settings->previous_protocol_handler(); - - base::string16 protocol; - if (pending_handler_.protocol() == "mailto") { - protocol = l10n_util::GetStringUTF16( - IDS_REGISTER_PROTOCOL_HANDLER_MAILTO_NAME); - } else if (pending_handler_.protocol() == "webcal") { - protocol = l10n_util::GetStringUTF16( - IDS_REGISTER_PROTOCOL_HANDLER_WEBCAL_NAME); - } else { - protocol = base::UTF8ToUTF16(pending_handler_.protocol()); - } - - // Note that we ignore the |title| parameter. - if (previous_handler_.IsEmpty()) { - set_title(l10n_util::GetStringFUTF16( - IDS_REGISTER_PROTOCOL_HANDLER_CONFIRM, - base::UTF8ToUTF16(pending_handler_.url().host()), - protocol)); - } else { - set_title(l10n_util::GetStringFUTF16( - IDS_REGISTER_PROTOCOL_HANDLER_CONFIRM_REPLACE, - base::UTF8ToUTF16(pending_handler_.url().host()), - protocol, - base::UTF8ToUTF16(previous_handler_.url().host()))); - } - - base::string16 radio_allow_label = - l10n_util::GetStringUTF16(IDS_REGISTER_PROTOCOL_HANDLER_ACCEPT); - base::string16 radio_deny_label = - l10n_util::GetStringUTF16(IDS_REGISTER_PROTOCOL_HANDLER_DENY); - base::string16 radio_ignore_label = - l10n_util::GetStringUTF16(IDS_REGISTER_PROTOCOL_HANDLER_IGNORE); - - const GURL& url = web_contents->GetURL(); - RadioGroup radio_group; - radio_group.url = url; - - radio_group.radio_items.push_back(radio_allow_label); - radio_group.radio_items.push_back(radio_deny_label); - radio_group.radio_items.push_back(radio_ignore_label); - ContentSetting setting = - content_settings->pending_protocol_handler_setting(); - if (setting == CONTENT_SETTING_ALLOW) - radio_group.default_item = RPH_ALLOW; - else if (setting == CONTENT_SETTING_BLOCK) - radio_group.default_item = RPH_BLOCK; - else - radio_group.default_item = RPH_IGNORE; - - selected_item_ = radio_group.default_item; - set_radio_group_enabled(true); - set_radio_group(radio_group); -} - -ContentSettingRPHBubbleModel::~ContentSettingRPHBubbleModel() { - if (!web_contents() || !interacted_) - return; - - // The user has one chance to deal with the RPH content setting UI, - // then we remove it. - auto* settings = TabSpecificContentSettings::FromWebContents(web_contents()); - settings->ClearPendingProtocolHandler(); - content::NotificationService::current()->Notify( - chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED, - content::Source<WebContents>(web_contents()), - content::NotificationService::NoDetails()); -} - -void ContentSettingRPHBubbleModel::OnRadioClicked(int radio_index) { - if (selected_item_ == radio_index) - return; - - interacted_ = true; - selected_item_ = radio_index; - - if (radio_index == RPH_ALLOW) - RegisterProtocolHandler(); - else if (radio_index == RPH_BLOCK) - UnregisterProtocolHandler(); - else if (radio_index == RPH_IGNORE) - IgnoreProtocolHandler(); - else - NOTREACHED(); -} - -void ContentSettingRPHBubbleModel::OnDoneClicked() { - interacted_ = true; -} - -void ContentSettingRPHBubbleModel::RegisterProtocolHandler() { - if (!web_contents()) - return; - - // A no-op if the handler hasn't been ignored, but needed in case the user - // selects sequences like register/ignore/register. - registry_->RemoveIgnoredHandler(pending_handler_); - - registry_->OnAcceptRegisterProtocolHandler(pending_handler_); - TabSpecificContentSettings::FromWebContents(web_contents())-> - set_pending_protocol_handler_setting(CONTENT_SETTING_ALLOW); -} - -void ContentSettingRPHBubbleModel::UnregisterProtocolHandler() { - if (!web_contents()) - return; - - registry_->OnDenyRegisterProtocolHandler(pending_handler_); - auto* settings = TabSpecificContentSettings::FromWebContents(web_contents()); - settings->set_pending_protocol_handler_setting(CONTENT_SETTING_BLOCK); - ClearOrSetPreviousHandler(); -} - -void ContentSettingRPHBubbleModel::IgnoreProtocolHandler() { - if (!web_contents()) - return; - - registry_->OnIgnoreRegisterProtocolHandler(pending_handler_); - auto* settings = TabSpecificContentSettings::FromWebContents(web_contents()); - settings->set_pending_protocol_handler_setting(CONTENT_SETTING_DEFAULT); - ClearOrSetPreviousHandler(); -} - -void ContentSettingRPHBubbleModel::ClearOrSetPreviousHandler() { - if (previous_handler_.IsEmpty()) { - registry_->ClearDefault(pending_handler_.protocol()); - } else { - registry_->OnAcceptRegisterProtocolHandler(previous_handler_); - } -} - // ContentSettingSubresourceFilterBubbleModel ---------------------------------- ContentSettingSubresourceFilterBubbleModel:: @@ -1387,94 +1481,6 @@ return this; } -// ContentSettingMidiSysExBubbleModel ------------------------------------------ - -class ContentSettingMidiSysExBubbleModel - : public ContentSettingSimpleBubbleModel { - public: - ContentSettingMidiSysExBubbleModel(Delegate* delegate, - WebContents* web_contents, - Profile* profile); - ~ContentSettingMidiSysExBubbleModel() override {} - - private: - void MaybeAddDomainList(const std::set<std::string>& hosts, int title_id); - void SetDomainsAndCustomLink(); - void OnCustomLinkClicked() override; - - DISALLOW_COPY_AND_ASSIGN(ContentSettingMidiSysExBubbleModel); -}; - -ContentSettingMidiSysExBubbleModel::ContentSettingMidiSysExBubbleModel( - Delegate* delegate, - WebContents* web_contents, - Profile* profile) - : ContentSettingSimpleBubbleModel(delegate, - web_contents, - profile, - CONTENT_SETTINGS_TYPE_MIDI_SYSEX) { - SetDomainsAndCustomLink(); -} - -void ContentSettingMidiSysExBubbleModel::MaybeAddDomainList( - const std::set<std::string>& hosts, int title_id) { - if (!hosts.empty()) { - DomainList domain_list; - domain_list.title = l10n_util::GetStringUTF16(title_id); - domain_list.hosts = hosts; - add_domain_list(domain_list); - } -} - -void ContentSettingMidiSysExBubbleModel::SetDomainsAndCustomLink() { - TabSpecificContentSettings* content_settings = - TabSpecificContentSettings::FromWebContents(web_contents()); - const ContentSettingsUsagesState& usages_state = - content_settings->midi_usages_state(); - ContentSettingsUsagesState::FormattedHostsPerState formatted_hosts_per_state; - unsigned int tab_state_flags = 0; - usages_state.GetDetailedInfo(&formatted_hosts_per_state, &tab_state_flags); - // Divide the tab's current MIDI sysex users into sets according to their - // permission state. - MaybeAddDomainList(formatted_hosts_per_state[CONTENT_SETTING_ALLOW], - IDS_MIDI_SYSEX_BUBBLE_ALLOWED); - - MaybeAddDomainList(formatted_hosts_per_state[CONTENT_SETTING_BLOCK], - IDS_MIDI_SYSEX_BUBBLE_DENIED); - - if (tab_state_flags & ContentSettingsUsagesState::TABSTATE_HAS_EXCEPTION) { - set_custom_link( - l10n_util::GetStringUTF16(IDS_MIDI_SYSEX_BUBBLE_CLEAR_LINK)); - set_custom_link_enabled(true); - } else if (tab_state_flags & - ContentSettingsUsagesState::TABSTATE_HAS_CHANGED) { - set_custom_link(l10n_util::GetStringUTF16( - IDS_MIDI_SYSEX_BUBBLE_REQUIRE_RELOAD_TO_CLEAR)); - } -} - -void ContentSettingMidiSysExBubbleModel::OnCustomLinkClicked() { - if (!web_contents()) - return; - // Reset this embedder's entry to default for each of the requesting - // origins currently on the page. - const GURL& embedder_url = web_contents()->GetURL(); - TabSpecificContentSettings* content_settings = - TabSpecificContentSettings::FromWebContents(web_contents()); - const ContentSettingsUsagesState::StateMap& state_map = - content_settings->midi_usages_state().state_map(); - HostContentSettingsMap* map = - HostContentSettingsMapFactory::GetForProfile(profile()); - for (const std::pair<GURL, ContentSetting>& map_entry : state_map) { - PermissionUtil::ScopedRevocationReporter( - profile(), map_entry.first, embedder_url, - CONTENT_SETTINGS_TYPE_MIDI_SYSEX, PermissionSourceUI::PAGE_ACTION); - map->SetContentSettingDefaultScope(map_entry.first, embedder_url, - CONTENT_SETTINGS_TYPE_MIDI_SYSEX, - std::string(), CONTENT_SETTING_DEFAULT); - } -} - // ContentSettingDownloadsBubbleModel ------------------------------------------ ContentSettingDownloadsBubbleModel::ContentSettingDownloadsBubbleModel( @@ -1673,6 +1679,11 @@ // ContentSettingBubbleModel --------------------------------------------------- +// This class must be placed last because it needs the definition of the other +// classes declared in this file. + +const int ContentSettingBubbleModel::kAllowButtonIndex = 0; + // static ContentSettingBubbleModel* ContentSettingBubbleModel::CreateContentSettingBubbleModel(
diff --git a/chrome/browser/ui/content_settings/content_setting_bubble_model.h b/chrome/browser/ui/content_settings/content_setting_bubble_model.h index db94491c..bc8c461 100644 --- a/chrome/browser/ui/content_settings/content_setting_bubble_model.h +++ b/chrome/browser/ui/content_settings/content_setting_bubble_model.h
@@ -41,8 +41,7 @@ // The hierarchy of bubble models: // -// ContentSettingsBubbleModel - base class -// ContentSettingMediaStreamBubbleModel - media (camera and mic) +// ContentSettingBubbleModel - base class // ContentSettingSimpleBubbleModel - single content setting // ContentSettingMixedScriptBubbleModel - mixed script // ContentSettingRPHBubbleModel - protocol handlers @@ -52,13 +51,14 @@ // ContentSettingSingleRadioGroup - radio group // ContentSettingCookiesBubbleModel - cookies // ContentSettingPopupBubbleModel - popups +// ContentSettingMediaStreamBubbleModel - media (camera and mic) // ContentSettingSubresourceFilterBubbleModel - filtered subresources // ContentSettingDownloadsBubbleModel - automatic downloads // ContentSettingFramebustBlockBubbleModel - blocked framebusts // Forward declaration necessary for downcasts. -class ContentSettingMediaStreamBubbleModel; class ContentSettingSimpleBubbleModel; +class ContentSettingMediaStreamBubbleModel; class ContentSettingSubresourceFilterBubbleModel; class ContentSettingDownloadsBubbleModel; class ContentSettingFramebustBlockBubbleModel; @@ -155,6 +155,8 @@ DISALLOW_COPY_AND_ASSIGN(BubbleContent); }; + static const int kAllowButtonIndex; + // Creates a bubble model for a particular |content_type|. Note that not all // bubbles fit this description. // TODO(msramek): Move this to ContentSettingSimpleBubbleModel or remove @@ -217,8 +219,6 @@ rappor_service_ = rappor_service; } - static const int kAllowButtonIndex; - protected: ContentSettingBubbleModel( Delegate* delegate, @@ -340,33 +340,6 @@ DISALLOW_COPY_AND_ASSIGN(ContentSettingRPHBubbleModel); }; -// The model for the deceptive content bubble. -class ContentSettingSubresourceFilterBubbleModel - : public ContentSettingBubbleModel { - public: - ContentSettingSubresourceFilterBubbleModel(Delegate* delegate, - content::WebContents* web_contents, - Profile* profile); - - ~ContentSettingSubresourceFilterBubbleModel() override; - - private: - void SetMessage(); - void SetTitle(); - void SetManageText(); - - // ContentSettingBubbleModel: - void OnManageCheckboxChecked(bool is_checked) override; - ContentSettingSubresourceFilterBubbleModel* AsSubresourceFilterBubbleModel() - override; - void OnLearnMoreClicked() override; - void OnDoneClicked() override; - - bool is_checked_ = false; - - DISALLOW_COPY_AND_ASSIGN(ContentSettingSubresourceFilterBubbleModel); -}; - // The model of the content settings bubble for media settings. class ContentSettingMediaStreamBubbleModel : public ContentSettingBubbleModel { public: @@ -426,6 +399,33 @@ DISALLOW_COPY_AND_ASSIGN(ContentSettingMediaStreamBubbleModel); }; +// The model for the deceptive content bubble. +class ContentSettingSubresourceFilterBubbleModel + : public ContentSettingBubbleModel { + public: + ContentSettingSubresourceFilterBubbleModel(Delegate* delegate, + content::WebContents* web_contents, + Profile* profile); + + ~ContentSettingSubresourceFilterBubbleModel() override; + + private: + void SetMessage(); + void SetTitle(); + void SetManageText(); + + // ContentSettingBubbleModel: + void OnManageCheckboxChecked(bool is_checked) override; + ContentSettingSubresourceFilterBubbleModel* AsSubresourceFilterBubbleModel() + override; + void OnLearnMoreClicked() override; + void OnDoneClicked() override; + + bool is_checked_ = false; + + DISALLOW_COPY_AND_ASSIGN(ContentSettingSubresourceFilterBubbleModel); +}; + // The model for automatic downloads setting. class ContentSettingDownloadsBubbleModel : public ContentSettingBubbleModel { public:
diff --git a/chrome/browser/ui/content_settings/content_setting_image_model.cc b/chrome/browser/ui/content_settings/content_setting_image_model.cc index fb39987f..263442db5 100644 --- a/chrome/browser/ui/content_settings/content_setting_image_model.cc +++ b/chrome/browser/ui/content_settings/content_setting_image_model.cc
@@ -4,6 +4,9 @@ #include "chrome/browser/ui/content_settings/content_setting_image_model.h" +#include <string> +#include <utility> + #include "base/feature_list.h" #include "base/macros.h" #include "base/memory/ptr_util.h" @@ -65,30 +68,14 @@ DISALLOW_COPY_AND_ASSIGN(ContentSettingGeolocationImageModel); }; -// Image model for displaying media icons in the location bar. -class ContentSettingMediaImageModel : public ContentSettingImageModel { - public: - ContentSettingMediaImageModel(); - - void UpdateFromWebContents(WebContents* web_contents) override; - - ContentSettingBubbleModel* CreateBubbleModel( - ContentSettingBubbleModel::Delegate* delegate, - WebContents* web_contents, - Profile* profile) override; - - bool ShouldRunAnimation(WebContents* web_contents) override; - void SetAnimationHasRun(WebContents* web_contents) override; - - private: - DISALLOW_COPY_AND_ASSIGN(ContentSettingMediaImageModel); -}; - class ContentSettingRPHImageModel : public ContentSettingSimpleImageModel { public: ContentSettingRPHImageModel(); void UpdateFromWebContents(WebContents* web_contents) override; + + private: + DISALLOW_COPY_AND_ASSIGN(ContentSettingRPHImageModel); }; class ContentSettingMIDISysExImageModel @@ -112,6 +99,25 @@ DISALLOW_COPY_AND_ASSIGN(ContentSettingDownloadsImageModel); }; +// Image model for displaying media icons in the location bar. +class ContentSettingMediaImageModel : public ContentSettingImageModel { + public: + ContentSettingMediaImageModel(); + + void UpdateFromWebContents(WebContents* web_contents) override; + + ContentSettingBubbleModel* CreateBubbleModel( + ContentSettingBubbleModel::Delegate* delegate, + WebContents* web_contents, + Profile* profile) override; + + bool ShouldRunAnimation(WebContents* web_contents) override; + void SetAnimationHasRun(WebContents* web_contents) override; + + private: + DISALLOW_COPY_AND_ASSIGN(ContentSettingMediaImageModel); +}; + namespace { struct ContentSettingsImageDetails { @@ -335,6 +341,101 @@ : IDS_GEOLOCATION_BLOCKED_TOOLTIP)); } +// Protocol handlers ----------------------------------------------------------- + +ContentSettingRPHImageModel::ContentSettingRPHImageModel() + : ContentSettingSimpleImageModel(CONTENT_SETTINGS_TYPE_PROTOCOL_HANDLERS) { + set_icon(vector_icons::kProtocolHandlerIcon, gfx::kNoneIcon); + set_tooltip(l10n_util::GetStringUTF16(IDS_REGISTER_PROTOCOL_HANDLER_TOOLTIP)); +} + +void ContentSettingRPHImageModel::UpdateFromWebContents( + WebContents* web_contents) { + set_visible(false); + if (!web_contents) + return; + + TabSpecificContentSettings* content_settings = + TabSpecificContentSettings::FromWebContents(web_contents); + if (!content_settings) + return; + if (content_settings->pending_protocol_handler().IsEmpty()) + return; + + set_visible(true); +} + +// MIDI SysEx ------------------------------------------------------------------ + +ContentSettingMIDISysExImageModel::ContentSettingMIDISysExImageModel() + : ContentSettingSimpleImageModel(CONTENT_SETTINGS_TYPE_MIDI_SYSEX) {} + +void ContentSettingMIDISysExImageModel::UpdateFromWebContents( + WebContents* web_contents) { + set_visible(false); + if (!web_contents) + return; + TabSpecificContentSettings* content_settings = + TabSpecificContentSettings::FromWebContents(web_contents); + if (!content_settings) + return; + const ContentSettingsUsagesState& usages_state = + content_settings->midi_usages_state(); + if (usages_state.state_map().empty()) + return; + set_visible(true); + + // If any embedded site has access the allowed icon takes priority over the + // blocked icon. + unsigned int state_flags = 0; + usages_state.GetDetailedInfo(nullptr, &state_flags); + bool allowed = + !!(state_flags & ContentSettingsUsagesState::TABSTATE_HAS_ANY_ALLOWED); + set_icon(vector_icons::kMidiIcon, + allowed ? gfx::kNoneIcon : kBlockedBadgeIcon); + set_tooltip(l10n_util::GetStringUTF16(allowed + ? IDS_MIDI_SYSEX_ALLOWED_TOOLTIP + : IDS_MIDI_SYSEX_BLOCKED_TOOLTIP)); +} + +// Automatic downloads --------------------------------------------------------- + +ContentSettingDownloadsImageModel::ContentSettingDownloadsImageModel() + : ContentSettingSimpleImageModel( + CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS) {} + +void ContentSettingDownloadsImageModel::UpdateFromWebContents( + WebContents* web_contents) { + set_visible(false); + if (!web_contents) + return; + + DownloadRequestLimiter* download_request_limiter = + g_browser_process->download_request_limiter(); + + // DownloadRequestLimiter can be absent in unit_tests. + if (!download_request_limiter) + return; + + switch (download_request_limiter->GetDownloadUiStatus(web_contents)) { + case DownloadRequestLimiter::DOWNLOAD_UI_ALLOWED: + set_visible(true); + set_icon(kFileDownloadIcon, gfx::kNoneIcon); + set_explanatory_string_id(0); + set_tooltip(l10n_util::GetStringUTF16(IDS_ALLOWED_DOWNLOAD_TITLE)); + return; + case DownloadRequestLimiter::DOWNLOAD_UI_BLOCKED: + set_visible(true); + set_icon(kFileDownloadIcon, kBlockedBadgeIcon); + set_explanatory_string_id(IDS_BLOCKED_DOWNLOADS_EXPLANATION); + set_tooltip(l10n_util::GetStringUTF16(IDS_BLOCKED_DOWNLOAD_TITLE)); + return; + case DownloadRequestLimiter::DOWNLOAD_UI_DEFAULT: + // No need to show icon otherwise. + return; + } +} + // Media ----------------------------------------------------------------------- ContentSettingMediaImageModel::ContentSettingMediaImageModel() @@ -474,7 +575,6 @@ } // Blocked Framebust ----------------------------------------------------------- - ContentSettingFramebustBlockImageModel::ContentSettingFramebustBlockImageModel() : ContentSettingImageModel() {} @@ -518,102 +618,6 @@ ->set_animation_has_run(); } -// Protocol handlers ----------------------------------------------------------- - -ContentSettingRPHImageModel::ContentSettingRPHImageModel() - : ContentSettingSimpleImageModel(CONTENT_SETTINGS_TYPE_PROTOCOL_HANDLERS) { - set_icon(vector_icons::kProtocolHandlerIcon, gfx::kNoneIcon); - set_tooltip(l10n_util::GetStringUTF16(IDS_REGISTER_PROTOCOL_HANDLER_TOOLTIP)); -} - -void ContentSettingRPHImageModel::UpdateFromWebContents( - WebContents* web_contents) { - set_visible(false); - if (!web_contents) - return; - - TabSpecificContentSettings* content_settings = - TabSpecificContentSettings::FromWebContents(web_contents); - if (!content_settings) - return; - if (content_settings->pending_protocol_handler().IsEmpty()) - return; - - set_visible(true); -} - -// MIDI SysEx ------------------------------------------------------------------ - -ContentSettingMIDISysExImageModel::ContentSettingMIDISysExImageModel() - : ContentSettingSimpleImageModel(CONTENT_SETTINGS_TYPE_MIDI_SYSEX) { -} - -void ContentSettingMIDISysExImageModel::UpdateFromWebContents( - WebContents* web_contents) { - set_visible(false); - if (!web_contents) - return; - TabSpecificContentSettings* content_settings = - TabSpecificContentSettings::FromWebContents(web_contents); - if (!content_settings) - return; - const ContentSettingsUsagesState& usages_state = - content_settings->midi_usages_state(); - if (usages_state.state_map().empty()) - return; - set_visible(true); - - // If any embedded site has access the allowed icon takes priority over the - // blocked icon. - unsigned int state_flags = 0; - usages_state.GetDetailedInfo(nullptr, &state_flags); - bool allowed = - !!(state_flags & ContentSettingsUsagesState::TABSTATE_HAS_ANY_ALLOWED); - set_icon(vector_icons::kMidiIcon, - allowed ? gfx::kNoneIcon : kBlockedBadgeIcon); - set_tooltip(l10n_util::GetStringUTF16(allowed - ? IDS_MIDI_SYSEX_ALLOWED_TOOLTIP - : IDS_MIDI_SYSEX_BLOCKED_TOOLTIP)); -} - -// Automatic downloads --------------------------------------------------------- - -ContentSettingDownloadsImageModel::ContentSettingDownloadsImageModel() - : ContentSettingSimpleImageModel( - CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS) {} - -void ContentSettingDownloadsImageModel::UpdateFromWebContents( - WebContents* web_contents) { - set_visible(false); - if (!web_contents) - return; - - DownloadRequestLimiter* download_request_limiter = - g_browser_process->download_request_limiter(); - - // DownloadRequestLimiter can be absent in unit_tests. - if (!download_request_limiter) - return; - - switch (download_request_limiter->GetDownloadUiStatus(web_contents)) { - case DownloadRequestLimiter::DOWNLOAD_UI_ALLOWED: - set_visible(true); - set_icon(kFileDownloadIcon, gfx::kNoneIcon); - set_explanatory_string_id(0); - set_tooltip(l10n_util::GetStringUTF16(IDS_ALLOWED_DOWNLOAD_TITLE)); - return; - case DownloadRequestLimiter::DOWNLOAD_UI_BLOCKED: - set_visible(true); - set_icon(kFileDownloadIcon, kBlockedBadgeIcon); - set_explanatory_string_id(IDS_BLOCKED_DOWNLOADS_EXPLANATION); - set_tooltip(l10n_util::GetStringUTF16(IDS_BLOCKED_DOWNLOAD_TITLE)); - return; - case DownloadRequestLimiter::DOWNLOAD_UI_DEFAULT: - // No need to show icon otherwise. - return; - } -} - // Base class ------------------------------------------------------------------ gfx::Image ContentSettingImageModel::GetIcon(SkColor icon_color) const {
diff --git a/chrome/browser/ui/content_settings/content_setting_image_model.h b/chrome/browser/ui/content_settings/content_setting_image_model.h index 2b5e571f..93371c7e0 100644 --- a/chrome/browser/ui/content_settings/content_setting_image_model.h +++ b/chrome/browser/ui/content_settings/content_setting_image_model.h
@@ -5,6 +5,9 @@ #ifndef CHROME_BROWSER_UI_CONTENT_SETTINGS_CONTENT_SETTING_IMAGE_MODEL_H_ #define CHROME_BROWSER_UI_CONTENT_SETTINGS_CONTENT_SETTING_IMAGE_MODEL_H_ +#include <memory> +#include <vector> + #include "base/macros.h" #include "base/strings/string16.h" #include "build/build_config.h"
diff --git a/chrome/browser/ui/crypto_module_delegate_nss.cc b/chrome/browser/ui/crypto_module_delegate_nss.cc index a296380..acfd15ea 100644 --- a/chrome/browser/ui/crypto_module_delegate_nss.cc +++ b/chrome/browser/ui/crypto_module_delegate_nss.cc
@@ -12,7 +12,7 @@ using content::BrowserThread; ChromeNSSCryptoModuleDelegate::ChromeNSSCryptoModuleDelegate( - chrome::CryptoModulePasswordReason reason, + CryptoModulePasswordReason reason, const net::HostPortPair& server) : reason_(reason), server_(server), @@ -66,8 +66,7 @@ } crypto::CryptoModuleBlockingPasswordDelegate* -CreateCryptoModuleBlockingPasswordDelegate( - chrome::CryptoModulePasswordReason reason, - const net::HostPortPair& server) { +CreateCryptoModuleBlockingPasswordDelegate(CryptoModulePasswordReason reason, + const net::HostPortPair& server) { return new ChromeNSSCryptoModuleDelegate(reason, server); }
diff --git a/chrome/browser/ui/crypto_module_delegate_nss.h b/chrome/browser/ui/crypto_module_delegate_nss.h index 4e783b1..077a15f 100644 --- a/chrome/browser/ui/crypto_module_delegate_nss.h +++ b/chrome/browser/ui/crypto_module_delegate_nss.h
@@ -22,7 +22,7 @@ // Create a ChromeNSSCryptoModuleDelegate. |reason| is used to select what // string to show the user, |server| is displayed to indicate which connection // is causing the dialog to appear. |slot| can be NULL. - ChromeNSSCryptoModuleDelegate(chrome::CryptoModulePasswordReason reason, + ChromeNSSCryptoModuleDelegate(CryptoModulePasswordReason reason, const net::HostPortPair& server); // crypto::CryptoModuleBlockingPasswordDelegate implementation. @@ -40,7 +40,7 @@ void GotPassword(const std::string& password); // Parameters displayed in the dialog. - const chrome::CryptoModulePasswordReason reason_; + const CryptoModulePasswordReason reason_; net::HostPortPair server_; // Event to block worker thread while waiting for dialog on UI thread. @@ -55,8 +55,7 @@ // Create a delegate which only handles unlocking slots. crypto::CryptoModuleBlockingPasswordDelegate* - CreateCryptoModuleBlockingPasswordDelegate( - chrome::CryptoModulePasswordReason reason, - const net::HostPortPair& server); +CreateCryptoModuleBlockingPasswordDelegate(CryptoModulePasswordReason reason, + const net::HostPortPair& server); #endif // CHROME_BROWSER_UI_CRYPTO_MODULE_DELEGATE_NSS_H_
diff --git a/chrome/browser/ui/crypto_module_password_dialog.h b/chrome/browser/ui/crypto_module_password_dialog.h index 36abcc5..50c02c5d 100644 --- a/chrome/browser/ui/crypto_module_password_dialog.h +++ b/chrome/browser/ui/crypto_module_password_dialog.h
@@ -10,8 +10,6 @@ #include "base/callback.h" #include "ui/gfx/native_widget_types.h" -namespace chrome { - // An enum to describe the reason for the password request. enum CryptoModulePasswordReason { kCryptoModulePasswordCertEnrollment, @@ -35,6 +33,4 @@ gfx::NativeWindow parent, const CryptoModulePasswordCallback& callback); -} // namespace chrome - #endif // CHROME_BROWSER_UI_CRYPTO_MODULE_PASSWORD_DIALOG_H_
diff --git a/chrome/browser/ui/crypto_module_password_dialog_nss.cc b/chrome/browser/ui/crypto_module_password_dialog_nss.cc index d5dc6bd..b17b7e5 100644 --- a/chrome/browser/ui/crypto_module_password_dialog_nss.cc +++ b/chrome/browser/ui/crypto_module_password_dialog_nss.cc
@@ -26,7 +26,7 @@ class SlotUnlocker { public: SlotUnlocker(std::vector<crypto::ScopedPK11Slot> modules, - chrome::CryptoModulePasswordReason reason, + CryptoModulePasswordReason reason, const net::HostPortPair& server, gfx::NativeWindow parent, const base::Closure& callback); @@ -39,7 +39,7 @@ size_t current_; std::vector<crypto::ScopedPK11Slot> modules_; - chrome::CryptoModulePasswordReason reason_; + CryptoModulePasswordReason reason_; net::HostPortPair server_; gfx::NativeWindow parent_; base::Closure callback_; @@ -47,7 +47,7 @@ }; SlotUnlocker::SlotUnlocker(std::vector<crypto::ScopedPK11Slot> modules, - chrome::CryptoModulePasswordReason reason, + CryptoModulePasswordReason reason, const net::HostPortPair& server, gfx::NativeWindow parent, const base::Closure& callback) @@ -118,7 +118,7 @@ namespace chrome { void UnlockSlotsIfNecessary(std::vector<crypto::ScopedPK11Slot> modules, - chrome::CryptoModulePasswordReason reason, + CryptoModulePasswordReason reason, const net::HostPortPair& server, gfx::NativeWindow parent, const base::Closure& callback) { @@ -134,7 +134,7 @@ } void UnlockCertSlotIfNecessary(CERTCertificate* cert, - chrome::CryptoModulePasswordReason reason, + CryptoModulePasswordReason reason, const net::HostPortPair& server, gfx::NativeWindow parent, const base::Closure& callback) {
diff --git a/chrome/browser/ui/views/crypto_module_password_dialog_view.cc b/chrome/browser/ui/views/crypto_module_password_dialog_view.cc index aa9531a6..70d3a1c 100644 --- a/chrome/browser/ui/views/crypto_module_password_dialog_view.cc +++ b/chrome/browser/ui/views/crypto_module_password_dialog_view.cc
@@ -16,8 +16,6 @@ #include "ui/views/layout/grid_layout.h" #include "ui/views/widget/widget.h" -namespace chrome { - //////////////////////////////////////////////////////////////////////////////// // CryptoModulePasswordDialogView, public: @@ -90,25 +88,25 @@ const base::string16& hostname16 = base::UTF8ToUTF16(hostname); const base::string16& slot16 = base::UTF8ToUTF16(slot_name); switch (reason) { - case chrome::kCryptoModulePasswordCertEnrollment: + case kCryptoModulePasswordCertEnrollment: text = l10n_util::GetStringFUTF8( IDS_CRYPTO_MODULE_AUTH_DIALOG_TEXT_CERT_ENROLLMENT, slot16, hostname16); break; - case chrome::kCryptoModulePasswordClientAuth: + case kCryptoModulePasswordClientAuth: text = l10n_util::GetStringFUTF8( IDS_CRYPTO_MODULE_AUTH_DIALOG_TEXT_CLIENT_AUTH, slot16, hostname16); break; - case chrome::kCryptoModulePasswordListCerts: + case kCryptoModulePasswordListCerts: text = l10n_util::GetStringFUTF8( IDS_CRYPTO_MODULE_AUTH_DIALOG_TEXT_LIST_CERTS, slot16); break; - case chrome::kCryptoModulePasswordCertImport: + case kCryptoModulePasswordCertImport: text = l10n_util::GetStringFUTF8( IDS_CRYPTO_MODULE_AUTH_DIALOG_TEXT_CERT_IMPORT, slot16); break; - case chrome::kCryptoModulePasswordCertExport: + case kCryptoModulePasswordCertExport: text = l10n_util::GetStringFUTF8( IDS_CRYPTO_MODULE_AUTH_DIALOG_TEXT_CERT_EXPORT, slot16); break; @@ -165,5 +163,3 @@ new CryptoModulePasswordDialogView(slot_name, reason, hostname, callback); views::DialogDelegate::CreateDialogWidget(dialog, NULL, parent)->Show(); } - -} // namespace chrome
diff --git a/chrome/browser/ui/views/crypto_module_password_dialog_view.h b/chrome/browser/ui/views/crypto_module_password_dialog_view.h index 8ab6df1..74fc4c3 100644 --- a/chrome/browser/ui/views/crypto_module_password_dialog_view.h +++ b/chrome/browser/ui/views/crypto_module_password_dialog_view.h
@@ -18,8 +18,6 @@ class Textfield; } -namespace chrome { - class CryptoModulePasswordDialogView : public views::DialogDelegateView, public views::TextfieldController { public: @@ -63,6 +61,4 @@ DISALLOW_COPY_AND_ASSIGN(CryptoModulePasswordDialogView); }; -} // namespace chrome - #endif // CHROME_BROWSER_UI_VIEWS_CRYPTO_MODULE_PASSWORD_DIALOG_VIEW_H_
diff --git a/chrome/browser/ui/views/crypto_module_password_dialog_view_unittest.cc b/chrome/browser/ui/views/crypto_module_password_dialog_view_unittest.cc index 357ea4a..74a2ea2 100644 --- a/chrome/browser/ui/views/crypto_module_password_dialog_view_unittest.cc +++ b/chrome/browser/ui/views/crypto_module_password_dialog_view_unittest.cc
@@ -14,8 +14,6 @@ #include "ui/views/controls/textfield/textfield.h" #include "ui/views/test/views_test_base.h" -namespace chrome { - class CryptoModulePasswordDialogViewTest : public views::ViewsTestBase { public: CryptoModulePasswordDialogViewTest() {} @@ -56,5 +54,3 @@ const base::string16 empty; EXPECT_EQ(empty, dialog_->password_entry_->text()); } - -} // namespace chrome
diff --git a/chrome/browser/ui/webui/certificates_handler.cc b/chrome/browser/ui/webui/certificates_handler.cc index 85d20c1..2fa6d9b 100644 --- a/chrome/browser/ui/webui/certificates_handler.cc +++ b/chrome/browser/ui/webui/certificates_handler.cc
@@ -582,7 +582,7 @@ // TODO(mattm): do something smarter about non-extractable keys chrome::UnlockCertSlotIfNecessary( - selected_cert_list_[0].get(), chrome::kCryptoModulePasswordCertExport, + selected_cert_list_[0].get(), kCryptoModulePasswordCertExport, net::HostPortPair(), // unused. GetParentWindow(), base::Bind(&CertificatesHandler::ExportPersonalSlotsUnlocked, @@ -719,7 +719,7 @@ std::vector<crypto::ScopedPK11Slot> modules; modules.push_back(crypto::ScopedPK11Slot(PK11_ReferenceSlot(slot_.get()))); chrome::UnlockSlotsIfNecessary( - std::move(modules), chrome::kCryptoModulePasswordCertImport, + std::move(modules), kCryptoModulePasswordCertImport, net::HostPortPair(), // unused. GetParentWindow(), base::Bind(&CertificatesHandler::ImportPersonalSlotUnlocked,
diff --git a/chrome/browser/ui/webui/settings/chrome_cleanup_handler.cc b/chrome/browser/ui/webui/settings/chrome_cleanup_handler.cc index c7174d0..87984fc4 100644 --- a/chrome/browser/ui/webui/settings/chrome_cleanup_handler.cc +++ b/chrome/browser/ui/webui/settings/chrome_cleanup_handler.cc
@@ -46,6 +46,10 @@ switch (idle_reason) { case ChromeCleanerController::IdleReason::kInitial: return "initial"; + case ChromeCleanerController::IdleReason::kReporterFoundNothing: + return "reporter_found_nothing"; + case ChromeCleanerController::IdleReason::kReporterFailed: + return "reporter_failed"; case ChromeCleanerController::IdleReason::kScanningFoundNothing: return "scanning_found_nothing"; case ChromeCleanerController::IdleReason::kScanningFailed:
diff --git a/chrome/browser/ui/webui/settings/chromeos/change_picture_handler.cc b/chrome/browser/ui/webui/settings/chromeos/change_picture_handler.cc index 35442a9..9cb364e 100644 --- a/chrome/browser/ui/webui/settings/chromeos/change_picture_handler.cc +++ b/chrome/browser/ui/webui/settings/chromeos/change_picture_handler.cc
@@ -298,10 +298,16 @@ if (image_type == "old") { // Previous image (from camera or manually uploaded) re-selected. DCHECK(!previous_image_.isNull()); - std::unique_ptr<user_manager::UserImage> user_image = - base::MakeUnique<user_manager::UserImage>( - previous_image_, previous_image_bytes_, previous_image_format_); - user_image->MarkAsSafe(); + std::unique_ptr<user_manager::UserImage> user_image; + if (previous_image_format_ == user_manager::UserImage::FORMAT_PNG && + previous_image_bytes_) { + user_image = base::MakeUnique<user_manager::UserImage>( + previous_image_, previous_image_bytes_, previous_image_format_); + user_image->MarkAsSafe(); + } else { + user_image = user_manager::UserImage::CreateAndEncode( + previous_image_, user_manager::UserImage::FORMAT_JPEG); + } user_image_manager->SaveUserImage(std::move(user_image)); UMA_HISTOGRAM_EXACT_LINEAR("UserImage.ChangeChoice",
diff --git a/chrome/browser/vr/elements/button.cc b/chrome/browser/vr/elements/button.cc index bc1b86f..5d6b113 100644 --- a/chrome/browser/vr/elements/button.cc +++ b/chrome/browser/vr/elements/button.cc
@@ -137,11 +137,11 @@ cc::Animation* animation) { if (target_property_id == BOUNDS) { background_->SetSize(size.width(), size.height()); - background_->set_corner_radius(size.width() * 0.5f); + background_->set_corner_radius(size.width() * 0.5f); // Creates a circle. foreground_->SetSize(size.width() * kIconScaleFactor, size.height() * kIconScaleFactor); hit_plane_->SetSize(size.width(), size.height()); - hit_plane_->set_corner_radius(size.width() * 0.5f); + hit_plane_->set_corner_radius(size.width() * 0.5f); // Creates a circle. } UiElement::NotifyClientSizeAnimated(size, target_property_id, animation); }
diff --git a/chrome/browser/vr/elements/button.h b/chrome/browser/vr/elements/button.h index c002dd3..f9cd0ca 100644 --- a/chrome/browser/vr/elements/button.h +++ b/chrome/browser/vr/elements/button.h
@@ -24,8 +24,9 @@ class Rect; class VectorIcon; -// Button has rounded rect as background and a vector icon as the foregroud. +// Button has a circle as the background and a vector icon as the foreground. // When hovered, background and foreground both move forward on Z axis. +// This matches the Daydream disk-style button. class Button : public UiElement { public: Button(base::Callback<void()> click_handler, const gfx::VectorIcon& icon);
diff --git a/chrome/browser/vr/elements/ui_texture.cc b/chrome/browser/vr/elements/ui_texture.cc index 8887357..d5aa73a 100644 --- a/chrome/browser/vr/elements/ui_texture.cc +++ b/chrome/browser/vr/elements/ui_texture.cc
@@ -201,6 +201,16 @@ return GetFontList(kDefaultFontFamily, font_size, text, font_list); } +SkColor UiTexture::foreground_color() const { + DCHECK(foreground_color_); + return foreground_color_.value(); +} + +SkColor UiTexture::background_color() const { + DCHECK(background_color_); + return background_color_.value(); +} + void UiTexture::SetForegroundColor(SkColor color) { if (foreground_color_ == color) return;
diff --git a/chrome/browser/vr/elements/ui_texture.h b/chrome/browser/vr/elements/ui_texture.h index da98685..d16c3887b 100644 --- a/chrome/browser/vr/elements/ui_texture.h +++ b/chrome/browser/vr/elements/ui_texture.h
@@ -9,6 +9,7 @@ #include <vector> #include "base/macros.h" +#include "base/optional.h" #include "base/strings/string16.h" #include "third_party/skia/include/core/SkColor.h" #include "ui/gfx/geometry/rect.h" @@ -110,14 +111,13 @@ static void SetForceFontFallbackFailureForTesting(bool force); void set_dirty() { dirty_ = true; } - - SkColor foreground_color() const { return foreground_color_; } - SkColor background_color() const { return background_color_; } + SkColor foreground_color() const; + SkColor background_color() const; private: bool dirty_ = true; - SkColor foreground_color_; - SkColor background_color_; + base::Optional<SkColor> foreground_color_; + base::Optional<SkColor> background_color_; DISALLOW_COPY_AND_ASSIGN(UiTexture); };
diff --git a/chrome/browser/vr/elements/url_bar_texture_unittest.cc b/chrome/browser/vr/elements/url_bar_texture_unittest.cc index 3ea1ec0..7d79e1b 100644 --- a/chrome/browser/vr/elements/url_bar_texture_unittest.cc +++ b/chrome/browser/vr/elements/url_bar_texture_unittest.cc
@@ -112,6 +112,8 @@ base::Unretained(this))) { gfx::FontList::SetDefaultFontDescription("Arial, Times New Roman, 15px"); SetColors(ColorScheme::GetColorScheme(ColorScheme::kModeNormal).url_bar); + SetBackgroundColor(SK_ColorBLACK); + SetForegroundColor(SK_ColorWHITE); } class MockRenderText : public RenderTextWrapper {
diff --git a/chrome/browser/vr/ui_scene_creator.cc b/chrome/browser/vr/ui_scene_creator.cc index 6f7236d7..ac6988b 100644 --- a/chrome/browser/vr/ui_scene_creator.cc +++ b/chrome/browser/vr/ui_scene_creator.cc
@@ -333,6 +333,10 @@ exit_warning->AddBinding(VR_BIND_FUNC(bool, Model, model_, exiting_vr, UiElement, exit_warning.get(), SetVisible)); + BindColor(model_, exit_warning.get(), &ColorScheme::exit_warning_background, + &TexturedElement::SetBackgroundColor); + BindColor(model_, exit_warning.get(), &ColorScheme::exit_warning_foreground, + &TexturedElement::SetForegroundColor); scene_->AddUiElement(k2dBrowsingViewportAwareRoot, std::move(exit_warning)); }
diff --git a/chrome/common/media_router/mojo/BUILD.gn b/chrome/common/media_router/mojo/BUILD.gn index 0dfaec4..63f946b 100644 --- a/chrome/common/media_router/mojo/BUILD.gn +++ b/chrome/common/media_router/mojo/BUILD.gn
@@ -13,9 +13,6 @@ public_deps = [ "//mojo/common:common_custom_types", ] - - # TODO(crbug.com/699569): Convert to use the new JS bindings. - use_new_js_bindings = false } mojom("media_router") { @@ -31,9 +28,6 @@ "//url/mojo:url_mojom_gurl", "//url/mojo:url_mojom_origin", ] - - # TODO(crbug.com/699569): Convert to use the new JS bindings. - use_new_js_bindings = false } mojom("media_router_test_interfaces") {
diff --git a/chrome/renderer/resources/extensions/media_router_bindings.js b/chrome/renderer/resources/extensions/media_router_bindings.js index 9251258..4ce4750 100644 --- a/chrome/renderer/resources/extensions/media_router_bindings.js +++ b/chrome/renderer/resources/extensions/media_router_bindings.js
@@ -2,935 +2,1391 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -var mediaRouter; +'use strict'; -define('media_router_bindings', [ - 'chrome/common/media_router/mojo/media_controller.mojom', - 'chrome/common/media_router/mojo/media_router.mojom', - 'chrome/common/media_router/mojo/media_status.mojom', - 'content/public/renderer/frame_interfaces', - 'extensions/common/mojo/keep_alive.mojom', - 'media/mojo/interfaces/mirror_service_remoting.mojom', - 'media/mojo/interfaces/remoting_common.mojom', - 'mojo/common/time.mojom', - 'mojo/public/js/bindings', - 'net/interfaces/ip_address.mojom', - 'net/interfaces/ip_endpoint.mojom', - 'url/mojo/origin.mojom', - 'url/mojo/url.mojom', -], function(mediaControllerMojom, - mediaRouterMojom, - mediaStatusMojom, - frameInterfaces, - keepAliveMojom, - remotingMojom, - remotingCommonMojom, - timeMojom, - bindings, - ipAddressMojom, - ipEndpointMojom, - originMojom, - urlMojom) { - 'use strict'; +if ((typeof mojo === 'undefined') || !mojo.bindingsLibraryInitialized) { + loadScript('mojo_bindings'); +} +mojo.config.autoLoadMojomDeps = false; - /** - * Converts a media sink to a MediaSink Mojo object. - * @param {!MediaSink} sink A media sink. - * @return {!mediaRouterMojom.MediaSink} A Mojo MediaSink object. - */ - function sinkToMojo_(sink) { - return new mediaRouterMojom.MediaSink({ - 'name': sink.friendlyName, - 'description': sink.description, - 'domain': sink.domain, - 'sink_id': sink.id, - 'icon_type': sinkIconTypeToMojo(sink.iconType), - }); +loadScript('chrome/common/media_router/mojo/media_controller.mojom'); +loadScript('chrome/common/media_router/mojo/media_router.mojom'); +loadScript('chrome/common/media_router/mojo/media_status.mojom'); +loadScript('extensions/common/mojo/keep_alive.mojom'); +loadScript('media/mojo/interfaces/mirror_service_remoting.mojom'); +loadScript('media/mojo/interfaces/remoting_common.mojom'); +loadScript('mojo/common/time.mojom'); +loadScript('net/interfaces/ip_address.mojom'); +loadScript('net/interfaces/ip_endpoint.mojom'); +loadScript('url/mojo/origin.mojom'); +loadScript('url/mojo/url.mojom'); + +// The following adapter classes preserve backward compatibility for the media +// router component extension. +// TODO(crbug.com/787128): Remove these adapters. + +function assignFields(object, fields) { + for(var field in fields) { + if (object.hasOwnProperty(field)) + object[field] = fields[field]; + } +} + +/** + * Adapter for mediaRouter.mojom.DialMediaSink. + * @constructor + */ +function DialMediaSinkAdapter(fields) { + this.ip_address = null; + this.model_name = null; + this.app_url = null; + + assignFields(this, fields); +} + +DialMediaSinkAdapter.fromNewVersion = function(other) { + return new DialMediaSinkAdapter({ + 'ip_address': IPAddressAdapter.fromNewVersion(other.ipAddress), + 'model_name': other.modelName, + 'app_url': other.appUrl, + }); +}; + +DialMediaSinkAdapter.prototype.toNewVersion = function() { + return new mediaRouter.mojom.DialMediaSink({ + 'ipAddress' : this.ip_address.toNewVersion(), + 'modelName' : this.model_name, + 'appUrl' : this.app_url, + }); +}; + +/** + * Adapter for mediaRouter.mojom.CastMediaSink. + * @constructor + */ +function CastMediaSinkAdapter(fields) { + this.ip_endpoint = null; + this.model_name = null; + this.capabilities = 0; + this.cast_channel_id = 0; + + assignFields(this, fields); +} + +CastMediaSinkAdapter.fromNewVersion = function(other) { + return new CastMediaSinkAdapter({ + 'ip_endpoint': IPEndpointAdapter.fromNewVersion(other.ipEndpoint), + 'model_name': other.modelName, + 'capabilities': other.capabilities, + 'cast_channel_id': other.castChannelId, + }); +}; + +CastMediaSinkAdapter.prototype.toNewVersion = function() { + return new mediaRouter.mojom.CastMediaSink({ + 'ipEndpoint': this.ip_endpoint.toNewVersion(), + 'modelName': this.model_name, + 'capabilities': this.capabilities, + 'castChannelId': this.cast_channel_id, + }); +}; + +/** + * Adapter for mediaRouter.mojom.HangoutsMediaStatusExtraData. + * @constructor + */ +function HangoutsMediaStatusExtraDataAdapter(fields) { + this.local_present = false; + + assignFields(this, fields); +} + +HangoutsMediaStatusExtraDataAdapter.prototype.toNewVersion = function() { + return new mediaRouter.mojom.HangoutsMediaStatusExtraData({ + 'localPresent': this.local_present, + }); +}; + +/** + * Adapter for net.interfaces.IPAddress. + * @constructor + */ +function IPAddressAdapter(fields) { + this.address_bytes = null; + + assignFields(this, fields); +} + +IPAddressAdapter.fromNewVersion = function(other) { + return new IPAddressAdapter({ + 'address_bytes': other.addressBytes, + }); +}; + +IPAddressAdapter.prototype.toNewVersion = function() { + return new net.interfaces.IPAddress({ + 'addressBytes': this.address_bytes, + }); +}; + +/** + * Adapter for net.interfaces.IPEndpoint. + * @constructor + */ +function IPEndpointAdapter(fields) { + this.address = null; + this.port = 0; + + assignFields(this, fields); +} + +IPEndpointAdapter.fromNewVersion = function(other) { + return new IPEndpointAdapter({ + 'address': IPAddressAdapter.fromNewVersion(other.address), + 'port': other.port, + }); +}; + +IPEndpointAdapter.prototype.toNewVersion = function() { + return new net.interfaces.IPEndpoint({ + 'address': this.address.toNewVersion(), + 'port': this.port, + }); +}; + +/** + * Adapter for mediaRouter.mojom.MediaStatus. + * @constructor + */ +function MediaStatusAdapter(fields) { + this.title = null; + this.description = null; + this.can_play_pause = false; + this.can_mute = false; + this.can_set_volume = false; + this.can_seek = false; + this.is_muted = false; + this.play_state = 0; + this.volume = 0; + this.duration = null; + this.current_time = null; + this.hangouts_extra_data = null; + + assignFields(this, fields); +} + +MediaStatusAdapter.PlayState = mediaRouter.mojom.MediaStatus.PlayState; + +MediaStatusAdapter.prototype.toNewVersion = function() { + return new mediaRouter.mojom.MediaStatus({ + 'title': this.title, + 'description': this.description, + 'canPlayPause': this.can_play_pause, + 'canMute': this.can_mute, + 'canSetVolume': this.can_set_volume, + 'canSeek': this.can_seek, + 'isMuted': this.is_muted, + 'playState': this.play_state, + 'volume': this.volume, + 'duration': this.duration, + 'currentTime': this.current_time, + 'hangoutsExtraData': + this.hangouts_extra_data && this.hangouts_extra_data.toNewVersion(), + }); +}; + +/** + * Adapter for media.mojom.RemotingSinkMetadata. + * @constructor + */ +function RemotingSinkMetadataAdapter(fields) { + this.features = null; + this.audio_capabilities = null; + this.video_capabilities = null; + this.friendly_name = null; + + assignFields(this, fields); +} + +RemotingSinkMetadataAdapter.fromNewVersion = function(other) { + return new RemotingSinkMetadataAdapter({ + 'features': other.features, + 'audio_capabilities': other.audioCapabilities, + 'video_capabilities': other.videoCapabilities, + 'friendly_name': other.friendlyName, + }); +}; + +RemotingSinkMetadataAdapter.prototype.toNewVersion = function() { + return new media.mojom.RemotingSinkMetadata({ + 'features': this.features, + 'audioCapabilities': this.audio_capabilities, + 'videoCapabilities': this.video_capabilities, + 'friendlyName': this.friendly_name, + }); +}; + +/** + * Adapter for mediaRouter.mojom.MediaSink. + * @constructor + */ +function MediaSinkAdapter(fields) { + this.sink_id = null; + this.name = null; + this.description = null; + this.domain = null; + this.icon_type = 0; + this.extra_data = null; + + assignFields(this, fields); +} + +MediaSinkAdapter.fromNewVersion = function(other) { + return new MediaSinkAdapter({ + 'sink_id': other.sinkId, + 'name': other.name, + 'description': other.description, + 'domain': other.domain, + 'icon_type': other.iconType, + 'extra_data': other.extraData && + MediaSinkExtraDataAdapter.fromNewVersion(other.extraData), + }); +}; + +MediaSinkAdapter.prototype.toNewVersion = function() { + return new mediaRouter.mojom.MediaSink({ + 'sinkId': this.sink_id, + 'name': this.name, + 'description': this.description, + 'domain': this.domain, + 'iconType': this.icon_type, + 'extraData': this.extra_data && this.extra_data.toNewVersion(), + }); +}; + +/** + * Adapter for mediaRouter.mojom.MediaSinkExtraData. + * @constructor + */ +function MediaSinkExtraDataAdapter(value) { + this.$data = null; + this.$tag = undefined; + + if (value == undefined) { + return; } - /** - * Converts a media sink's icon type to a MediaSink.IconType Mojo object. - * @param {!MediaSink.IconType} type A media sink's icon type. - * @return {!mediaRouterMojom.MediaSink.IconType} A Mojo MediaSink.IconType - * object. - */ - function sinkIconTypeToMojo(type) { - switch (type) { - case 'cast': - return mediaRouterMojom.SinkIconType.CAST; - case 'cast_audio_group': - return mediaRouterMojom.SinkIconType.CAST_AUDIO_GROUP; - case 'cast_audio': - return mediaRouterMojom.SinkIconType.CAST_AUDIO; - case 'meeting': - return mediaRouterMojom.SinkIconType.MEETING; - case 'hangout': - return mediaRouterMojom.SinkIconType.HANGOUT; - case 'education': - return mediaRouterMojom.SinkIconType.EDUCATION; - case 'generic': - return mediaRouterMojom.SinkIconType.GENERIC; - default: - console.error('Unknown sink icon type : ' + type); - return mediaRouterMojom.SinkIconType.GENERIC; + var keys = Object.keys(value); + if (keys.length == 0) { + return; + } + + if (keys.length > 1) { + throw new TypeError('You may set only one member on a union.'); + } + + var fields = [ + 'dial_media_sink', + 'cast_media_sink', + ]; + + if (fields.indexOf(keys[0]) < 0) { + throw new ReferenceError(keys[0] + + ' is not a MediaSinkExtraDataAdapter member.'); + } + + this[keys[0]] = value[keys[0]]; +} + +MediaSinkExtraDataAdapter.Tags = { + dial_media_sink: 0, + cast_media_sink: 1, +}; + +Object.defineProperty(MediaSinkExtraDataAdapter.prototype, 'dial_media_sink', { + get: function() { + if (this.$tag != MediaSinkExtraDataAdapter.Tags.dial_media_sink) { + throw new ReferenceError( + 'MediaSinkExtraDataAdapter.dial_media_sink is not currently set.'); } + return this.$data; + }, + + set: function(value) { + this.$tag = MediaSinkExtraDataAdapter.Tags.dial_media_sink; + this.$data = value; } - - /** - * Returns a Mojo MediaRoute object given a MediaRoute and a - * media sink name. - * @param {!MediaRoute} route - * @return {!mojo.MediaRoute} - */ - function routeToMojo_(route) { - return new mediaRouterMojom.MediaRoute({ - 'media_route_id': route.id, - 'media_source': route.mediaSource, - 'media_sink_id': route.sinkId, - 'description': route.description, - 'icon_url': route.iconUrl, - 'is_local': route.isLocal, - 'custom_controller_path': route.customControllerPath || '', - 'for_display': route.forDisplay, - 'is_incognito': route.offTheRecord, - 'is_local_presentation': route.isOffscreenPresentation, - 'supports_media_route_controller': route.supportsMediaRouteController, - 'controller_type': route.controllerType, - // Begin newly added properties, followed by the milestone they were - // added. The guard should be safe to remove N+2 milestones later. - 'presentation_id': route.presentationId || '' // M64 - }); - } - - /** - * Converts a route message to a RouteMessage Mojo object. - * @param {!RouteMessage} message - * @return {!mediaRouterMojom.RouteMessage} A Mojo RouteMessage object. - */ - function messageToMojo_(message) { - if ("string" == typeof message.message) { - return new mediaRouterMojom.RouteMessage({ - 'type': mediaRouterMojom.RouteMessage.Type.TEXT, - 'message': message.message, - }); - } else { - return new mediaRouterMojom.RouteMessage({ - 'type': mediaRouterMojom.RouteMessage.Type.BINARY, - 'data': message.message, - }); - } - } - - /** - * Converts presentation connection state to Mojo enum value. - * @param {!string} state - * @return {!mediaRouterMojom.MediaRouter.PresentationConnectionState} - */ - function presentationConnectionStateToMojo_(state) { - var PresentationConnectionState = - mediaRouterMojom.MediaRouter.PresentationConnectionState; - switch (state) { - case 'connecting': - return PresentationConnectionState.CONNECTING; - case 'connected': - return PresentationConnectionState.CONNECTED; - case 'closed': - return PresentationConnectionState.CLOSED; - case 'terminated': - return PresentationConnectionState.TERMINATED; - default: - console.error('Unknown presentation connection state: ' + state); - return PresentationConnectionState.TERMINATED; - } - } - - /** - * Converts presentation connection close reason to Mojo enum value. - * @param {!string} reason - * @return {!mediaRouterMojom.MediaRouter.PresentationConnectionCloseReason} - */ - function presentationConnectionCloseReasonToMojo_(reason) { - var PresentationConnectionCloseReason = - mediaRouterMojom.MediaRouter.PresentationConnectionCloseReason; - switch (reason) { - case 'error': - return PresentationConnectionCloseReason.CONNECTION_ERROR; - case 'closed': - return PresentationConnectionCloseReason.CLOSED; - case 'went_away': - return PresentationConnectionCloseReason.WENT_AWAY; - default: - console.error('Unknown presentation connection close reason : ' + - reason); - return PresentationConnectionCloseReason.CONNECTION_ERROR; - } - } - - /** - * Parses the given route request Error object and converts it to the - * corresponding result code. - * @param {!Error} error - * @return {!mediaRouterMojom.RouteRequestResultCode} - */ - function getRouteRequestResultCode_(error) { - return error.errorCode ? error.errorCode : - mediaRouterMojom.RouteRequestResultCode.UNKNOWN_ERROR; - } - - /** - * Creates and returns a successful route response from given route. - * @param {!MediaRoute} route - * @return {!Object} - */ - function toSuccessRouteResponse_(route) { - return { - route: routeToMojo_(route), - result_code: mediaRouterMojom.RouteRequestResultCode.OK - }; - } - - /** - * Creates and returns a error route response from given Error object. - * @param {!Error} error - * @return {!Object} - */ - function toErrorRouteResponse_(error) { - return { - error_text: error.message, - result_code: getRouteRequestResultCode_(error) - }; - } - - /** - * Creates a new MediaRouter. - * Converts a route struct to its Mojo form. - * @param {!mediaRouterMojom.MediaRouterPtr} service - * @constructor - */ - function MediaRouter(service) { - /** - * The Mojo service proxy. Allows extension code to call methods that reside - * in the browser. - * @type {!mediaRouterMojom.MediaRouterPtr} - */ - this.service_ = service; - - /** - * The provider manager service delegate. Its methods are called by the - * browser-resident Mojo service. - * @type {!MediaRouter} - */ - this.mrpm_ = new MediaRouteProvider(this); - - /** - * Handle to a KeepAlive service object, which prevents the extension from - * being suspended as long as it remains in scope. - * @type {boolean} - */ - this.keepAlive_ = null; - - /** - * The bindings to bind the service delegate to the Mojo interface. - * Object must remain in scope for the lifetime of the connection to - * prevent the connection from closing automatically. - * @type {!bindings.Binding} - */ - this.mediaRouteProviderBinding_ = new bindings.Binding( - mediaRouterMojom.MediaRouteProvider, this.mrpm_); - } - - /** - * Returns definitions of Mojo core and generated Mojom classes that can be - * used directly by the component. - * @return {!Object} - * TODO(imcheng): We should export these along with MediaRouter. This requires - * us to modify the component to handle multiple exports. When that logic is - * baked in for a couple of milestones, we should be able to remove this - * method. - */ - MediaRouter.prototype.getMojoExports = function() { - return { - Binding: bindings.Binding, - DialMediaSink: mediaRouterMojom.DialMediaSink, - CastMediaSink: mediaRouterMojom.CastMediaSink, - HangoutsMediaRouteController: - mediaControllerMojom.HangoutsMediaRouteController, - HangoutsMediaStatusExtraData: - mediaStatusMojom.HangoutsMediaStatusExtraData, - IPAddress: ipAddressMojom.IPAddress, - IPEndpoint: ipEndpointMojom.IPEndpoint, - InterfacePtrController: bindings.InterfacePtrController, - InterfaceRequest: bindings.InterfaceRequest, - MediaController: mediaControllerMojom.MediaController, - MediaStatus: mediaStatusMojom.MediaStatus, - MediaStatusObserverPtr: mediaStatusMojom.MediaStatusObserverPtr, - MirrorServiceRemoter: remotingMojom.MirrorServiceRemoter, - MirrorServiceRemoterPtr: remotingMojom.MirrorServiceRemoterPtr, - MirrorServiceRemotingSourcePtr: - remotingMojom.MirrorServiceRemotingSourcePtr, - RemotingStopReason: remotingCommonMojom.RemotingStopReason, - RemotingStartFailReason: remotingCommonMojom.RemotingStartFailReason, - RemotingSinkFeature: remotingCommonMojom.RemotingSinkFeature, - RemotingSinkAudioCapability: - remotingCommonMojom.RemotingSinkAudioCapability, - RemotingSinkVideoCapability: - remotingCommonMojom.RemotingSinkVideoCapability, - RemotingSinkMetadata: remotingCommonMojom.RemotingSinkMetadata, - RouteControllerType: mediaRouterMojom.RouteControllerType, - Origin: originMojom.Origin, - Sink: mediaRouterMojom.MediaSink, - SinkExtraData: mediaRouterMojom.MediaSinkExtraData, - TimeDelta: timeMojom.TimeDelta, - Url: urlMojom.Url, - makeRequest: bindings.makeRequest, - }; - }; - - /** - * Registers the Media Router Provider Manager with the Media Router. - * @return {!Promise<Object>} Instance ID and config for the Media Router. - */ - MediaRouter.prototype.start = function() { - return this.service_.registerMediaRouteProvider( - mediaRouterMojom.MediaRouteProvider.Id.EXTENSION, - this.mediaRouteProviderBinding_.createInterfacePtrAndBind()); - } - - /** - * Sets the service delegate methods. - * @param {Object} handlers - */ - MediaRouter.prototype.setHandlers = function(handlers) { - this.mrpm_.setHandlers(handlers); - } - - /** - * The keep alive status. - * @return {boolean} - */ - MediaRouter.prototype.getKeepAlive = function() { - return this.keepAlive_ != null; - }; - - /** - * Called by the provider manager when a sink list for a given source is - * updated. - * @param {!string} sourceUrn - * @param {!Array<!MediaSink>} sinks - * @param {!Array<!originMojom.Origin>} origins - */ - MediaRouter.prototype.onSinksReceived = function(sourceUrn, sinks, origins) { - this.service_.onSinksReceived( - mediaRouterMojom.MediaRouteProvider.Id.EXTENSION, sourceUrn, - sinks.map(sinkToMojo_), origins); - }; - - /** - * Called by the provider manager when a sink is found to notify the MR of the - * sink's ID. The actual sink will be returned through the normal sink list - * update process, so this helps the MR identify the search result in the - * list. - * @param {string} pseudoSinkId ID of the pseudo sink that started the - * search. - * @param {string} sinkId ID of the newly-found sink. - */ - MediaRouter.prototype.onSearchSinkIdReceived = function( - pseudoSinkId, sinkId) { - this.service_.onSearchSinkIdReceived(pseudoSinkId, sinkId); - }; - - /** - * Called by the provider manager to keep the extension from suspending - * if it enters a state where suspension is undesirable (e.g. there is an - * active MediaRoute.) - * If keepAlive is true, the extension is kept alive. - * If keepAlive is false, the extension is allowed to suspend. - * @param {boolean} keepAlive - */ - MediaRouter.prototype.setKeepAlive = function(keepAlive) { - if (keepAlive === false && this.keepAlive_) { - this.keepAlive_.ptr.reset(); - this.keepAlive_ = null; - } else if (keepAlive === true && !this.keepAlive_) { - this.keepAlive_ = new keepAliveMojom.KeepAlivePtr( - frameInterfaces.getInterface(keepAliveMojom.KeepAlive.name)); - } - }; - - /** - * Called by the provider manager to send an issue from a media route - * provider to the Media Router, to show the user. - * @param {!Object} issue The issue object. - */ - MediaRouter.prototype.onIssue = function(issue) { - function issueSeverityToMojo_(severity) { - switch (severity) { - case 'fatal': - return mediaRouterMojom.Issue.Severity.FATAL; - case 'warning': - return mediaRouterMojom.Issue.Severity.WARNING; - case 'notification': - return mediaRouterMojom.Issue.Severity.NOTIFICATION; - default: - console.error('Unknown issue severity: ' + severity); - return mediaRouterMojom.Issue.Severity.NOTIFICATION; - } - } - - function issueActionToMojo_(action) { - switch (action) { - case 'dismiss': - return mediaRouterMojom.Issue.ActionType.DISMISS; - case 'learn_more': - return mediaRouterMojom.Issue.ActionType.LEARN_MORE; - default: - console.error('Unknown issue action type : ' + action); - return mediaRouterMojom.Issue.ActionType.OK; - } - } - - var secondaryActions = (issue.secondaryActions || []).map(function(e) { - return issueActionToMojo_(e); - }); - this.service_.onIssue(new mediaRouterMojom.Issue({ - 'route_id': issue.routeId || '', - 'severity': issueSeverityToMojo_(issue.severity), - 'title': issue.title, - 'message': issue.message || '', - 'default_action': issueActionToMojo_(issue.defaultAction), - 'secondary_actions': secondaryActions, - 'help_page_id': issue.helpPageId, - 'is_blocking': issue.isBlocking - })); - }; - - /** - * Called by the provider manager when the set of active routes - * has been updated. - * @param {!Array<MediaRoute>} routes The active set of media routes. - * @param {string=} sourceUrn The sourceUrn associated with this route - * query. - * @param {Array<string>=} joinableRouteIds The active set of joinable - * media routes. - */ - MediaRouter.prototype.onRoutesUpdated = function( - routes, sourceUrn = '', joinableRouteIds = []) { - this.service_.onRoutesUpdated( - mediaRouterMojom.MediaRouteProvider.Id.EXTENSION, - routes.map(routeToMojo_), sourceUrn, joinableRouteIds); - }; - - /** - * Called by the provider manager when sink availability has been updated. - * @param {!mediaRouterMojom.MediaRouter.SinkAvailability} availability - * The new sink availability. - */ - MediaRouter.prototype.onSinkAvailabilityUpdated = function(availability) { - this.service_.onSinkAvailabilityUpdated( - mediaRouterMojom.MediaRouteProvider.Id.EXTENSION, availability); - }; - - /** - * Called by the provider manager when the state of a presentation connected - * to a route has changed. - * @param {string} routeId - * @param {string} state - */ - MediaRouter.prototype.onPresentationConnectionStateChanged = - function(routeId, state) { - this.service_.onPresentationConnectionStateChanged( - routeId, presentationConnectionStateToMojo_(state)); - }; - - /** - * Called by the provider manager when the state of a presentation connected - * to a route has closed. - * @param {string} routeId - * @param {string} reason - * @param {string} message - */ - MediaRouter.prototype.onPresentationConnectionClosed = - function(routeId, reason, message) { - this.service_.onPresentationConnectionClosed( - routeId, presentationConnectionCloseReasonToMojo_(reason), message); - }; - - /** - * @param {string} routeId - * @param {!Array<!RouteMessage>} mesages - */ - MediaRouter.prototype.onRouteMessagesReceived = function(routeId, messages) { - this.service_.onRouteMessagesReceived( - routeId, messages.map(messageToMojo_)); - }; - - /** - * @param {number} tabId - * @param {!remotingMojom.MirrorServiceRemoterPtr} remoter - * @param {!remotingMojom.MirrorServiceRemotingSourcePtr} remotingSource - */ - MediaRouter.prototype.onMediaRemoterCreated = function(tabId, remoter, - remotingSource) { - this.service_.onMediaRemoterCreated(tabId, remoter, remotingSource); - } - - /** - * Object containing callbacks set by the provider manager. - * - * @constructor - * @struct - */ - function MediaRouterHandlers() { - /** - * @type {function(!string, !string, !string, !string, !number)} - */ - this.createRoute = null; - - /** - * @type {function(!string, !string, !string, !number)} - */ - this.joinRoute = null; - - /** - * @type {function(string): Promise} - */ - this.terminateRoute = null; - - /** - * @type {function(string)} - */ - this.startObservingMediaSinks = null; - - /** - * @type {function(string)} - */ - this.stopObservingMediaSinks = null; - - /** - * @type {function(string, string): Promise} - */ - this.sendRouteMessage = null; - - /** - * @type {function(string, Uint8Array): Promise} - */ - this.sendRouteBinaryMessage = null; - - /** - * @type {function(string)} - */ - this.startListeningForRouteMessages = null; - - /** - * @type {function(string)} - */ - this.stopListeningForRouteMessages = null; - - /** - * @type {function(string)} - */ - this.detachRoute = null; - - /** - * @type {function()} - */ - this.startObservingMediaRoutes = null; - - /** - * @type {function()} - */ - this.stopObservingMediaRoutes = null; - - /** - * @type {function()} - */ - this.connectRouteByRouteId = null; - - /** - * @type {function()} - */ - this.enableMdnsDiscovery = null; - - /** - * @type {function()} - */ - this.updateMediaSinks = null; - - /** - * @type {function(string, string, !SinkSearchCriteria): string} - */ - this.searchSinks = null; - - /** - * @type {function()} - */ - this.provideSinks = null; - - /** - * @type {function(string, !bindings.InterfaceRequest, - * !mediaStatusMojom.MediaStatusObserverPtr): !Promise<void>} - */ - this.createMediaRouteController = null; - }; - - /** - * Routes calls from Media Router to the provider manager extension. - * Registered with the MediaRouter stub. - * @param {!MediaRouter} MediaRouter proxy to call into the - * Media Router mojo interface. - * @constructor - */ - function MediaRouteProvider(mediaRouter) { - /** - * Object containing JS callbacks into Provider Manager code. - * @type {!MediaRouterHandlers} - */ - this.handlers_ = new MediaRouterHandlers(); - - /** - * Proxy class to the browser's Media Router Mojo service. - * @type {!MediaRouter} - */ - this.mediaRouter_ = mediaRouter; - } - - /* - * Sets the callback handler used to invoke methods in the provider manager. - * - * @param {!MediaRouterHandlers} handlers - */ - MediaRouteProvider.prototype.setHandlers = function(handlers) { - this.handlers_ = handlers; - var requiredHandlers = [ - 'stopObservingMediaRoutes', - 'startObservingMediaRoutes', - 'sendRouteMessage', - 'sendRouteBinaryMessage', - 'startListeningForRouteMessages', - 'stopListeningForRouteMessages', - 'detachRoute', - 'terminateRoute', - 'joinRoute', - 'createRoute', - 'stopObservingMediaSinks', - 'startObservingMediaRoutes', - 'connectRouteByRouteId', - 'enableMdnsDiscovery', - 'updateMediaSinks', - 'searchSinks', - 'provideSinks', - 'createMediaRouteController', - 'onBeforeInvokeHandler' - ]; - requiredHandlers.forEach(function(nextHandler) { - if (handlers[nextHandler] === undefined) { - console.error(nextHandler + ' handler not registered.'); - } - }); - } - - /** - * Starts querying for sinks capable of displaying the media source - * designated by |sourceUrn|. Results are returned by calling - * OnSinksReceived. - * @param {!string} sourceUrn - */ - MediaRouteProvider.prototype.startObservingMediaSinks = - function(sourceUrn) { - this.handlers_.onBeforeInvokeHandler(); - this.handlers_.startObservingMediaSinks(sourceUrn); - }; - - /** - * Stops querying for sinks capable of displaying |sourceUrn|. - * @param {!string} sourceUrn - */ - MediaRouteProvider.prototype.stopObservingMediaSinks = - function(sourceUrn) { - this.handlers_.onBeforeInvokeHandler(); - this.handlers_.stopObservingMediaSinks(sourceUrn); - }; - - /** - * Requests that |sinkId| render the media referenced by |sourceUrn|. If the - * request is from the Presentation API, then origin and tabId will - * be populated. - * @param {!string} sourceUrn Media source to render. - * @param {!string} sinkId Media sink ID. - * @param {!string} presentationId Presentation ID from the site - * requesting presentation. TODO(mfoltz): Remove. - * @param {!originMojom.Origin} origin Origin of site requesting presentation. - * @param {!number} tabId ID of tab requesting presentation. - * @param {!timeMojom.TimeDelta} timeout If positive, the timeout duration for - * the request. Otherwise, the default duration will be used. - * @param {!boolean} incognito If true, the route is being requested by - * an incognito profile. - * @return {!Promise.<!Object>} A Promise resolving to an object describing - * the newly created media route, or rejecting with an error message on - * failure. - */ - MediaRouteProvider.prototype.createRoute = - function(sourceUrn, sinkId, presentationId, origin, tabId, - timeout, incognito) { - this.handlers_.onBeforeInvokeHandler(); - return this.handlers_.createRoute( - sourceUrn, sinkId, presentationId, origin, tabId, - Math.floor(timeout.microseconds / 1000), incognito) - .then(function(route) { - return toSuccessRouteResponse_(route); - }, - function(err) { - return toErrorRouteResponse_(err); - }); - }; - - /** - * Handles a request via the Presentation API to join an existing route given - * by |sourceUrn| and |presentationId|. |origin| and |tabId| are used for - * validating same-origin/tab scope. - * @param {!string} sourceUrn Media source to render. - * @param {!string} presentationId Presentation ID to join. - * @param {!originMojom.Origin} origin Origin of site requesting join. - * @param {!number} tabId ID of tab requesting join. - * @param {!timeMojom.TimeDelta} timeout If positive, the timeout duration for - * the request. Otherwise, the default duration will be used. - * @param {!boolean} incognito If true, the route is being requested by - * an incognito profile. - * @return {!Promise.<!Object>} A Promise resolving to an object describing - * the newly created media route, or rejecting with an error message on - * failure. - */ - MediaRouteProvider.prototype.joinRoute = - function(sourceUrn, presentationId, origin, tabId, timeout, - incognito) { - this.handlers_.onBeforeInvokeHandler(); - return this.handlers_.joinRoute( - sourceUrn, presentationId, origin, tabId, - Math.floor(timeout.microseconds / 1000), incognito) - .then(function(route) { - return toSuccessRouteResponse_(route); - }, - function(err) { - return toErrorRouteResponse_(err); - }); - }; - - /** - * Handles a request via the Presentation API to join an existing route given - * by |sourceUrn| and |routeId|. |origin| and |tabId| are used for - * validating same-origin/tab scope. - * @param {!string} sourceUrn Media source to render. - * @param {!string} routeId Route ID to join. - * @param {!string} presentationId Presentation ID to join. - * @param {!originMojom.Origin} origin Origin of site requesting join. - * @param {!number} tabId ID of tab requesting join. - * @param {!timeMojom.TimeDelta} timeout If positive, the timeout duration for - * the request. Otherwise, the default duration will be used. - * @param {!boolean} incognito If true, the route is being requested by - * an incognito profile. - * @return {!Promise.<!Object>} A Promise resolving to an object describing - * the newly created media route, or rejecting with an error message on - * failure. - */ - MediaRouteProvider.prototype.connectRouteByRouteId = - function(sourceUrn, routeId, presentationId, origin, tabId, - timeout, incognito) { - this.handlers_.onBeforeInvokeHandler(); - return this.handlers_.connectRouteByRouteId( - sourceUrn, routeId, presentationId, origin, tabId, - Math.floor(timeout.microseconds / 1000), incognito) - .then(function(route) { - return toSuccessRouteResponse_(route); - }, - function(err) { - return toErrorRouteResponse_(err); - }); - }; - - /** - * Terminates the route specified by |routeId|. - * @param {!string} routeId - * @return {!Promise<!Object>} A Promise resolving to an object describing - * the result of the terminate operation, or rejecting with an error - * message and code if the operation failed. - */ - MediaRouteProvider.prototype.terminateRoute = function(routeId) { - this.handlers_.onBeforeInvokeHandler(); - return this.handlers_.terminateRoute(routeId).then( - () => ({result_code: mediaRouterMojom.RouteRequestResultCode.OK}), - (err) => toErrorRouteResponse_(err)); - }; - - /** - * Posts a message to the route designated by |routeId|. - * @param {!string} routeId - * @param {!string} message - * @return {!Promise.<boolean>} Resolved with true if the message was sent, - * or false on failure. - */ - MediaRouteProvider.prototype.sendRouteMessage = function( - routeId, message) { - this.handlers_.onBeforeInvokeHandler(); - return this.handlers_.sendRouteMessage(routeId, message) - .then(function() { - return {'sent': true}; - }, function() { - return {'sent': false}; - }); - }; - - /** - * Sends a binary message to the route designated by |routeId|. - * @param {!string} routeId - * @param {!Array<number>} data - * @return {!Promise.<boolean>} Resolved with true if the data was sent, - * or false on failure. - */ - MediaRouteProvider.prototype.sendRouteBinaryMessage = function( - routeId, data) { - this.handlers_.onBeforeInvokeHandler(); - return this.handlers_.sendRouteBinaryMessage(routeId, new Uint8Array(data)) - .then(function() { - return {'sent': true}; - }, function() { - return {'sent': false}; - }); - }; - - /** - * Listen for messages from a route. - * @param {!string} routeId - */ - MediaRouteProvider.prototype.startListeningForRouteMessages = function( - routeId) { - this.handlers_.onBeforeInvokeHandler(); - this.handlers_.startListeningForRouteMessages(routeId); - }; - - /** - * @param {!string} routeId - */ - MediaRouteProvider.prototype.stopListeningForRouteMessages = function( - routeId) { - this.handlers_.onBeforeInvokeHandler(); - this.handlers_.stopListeningForRouteMessages(routeId); - }; - - /** - * Indicates that the presentation connection that was connected to |routeId| - * is no longer connected to it. - * @param {!string} routeId - */ - MediaRouteProvider.prototype.detachRoute = function( - routeId) { - this.handlers_.detachRoute(routeId); - }; - - /** - * Requests that the provider manager start sending information about active - * media routes to the Media Router. - * @param {!string} sourceUrn - */ - MediaRouteProvider.prototype.startObservingMediaRoutes = function(sourceUrn) { - this.handlers_.onBeforeInvokeHandler(); - this.handlers_.startObservingMediaRoutes(sourceUrn); - }; - - /** - * Requests that the provider manager stop sending information about active - * media routes to the Media Router. - * @param {!string} sourceUrn - */ - MediaRouteProvider.prototype.stopObservingMediaRoutes = function(sourceUrn) { - this.handlers_.onBeforeInvokeHandler(); - this.handlers_.stopObservingMediaRoutes(sourceUrn); - }; - - /** - * Enables mDNS device discovery. - */ - MediaRouteProvider.prototype.enableMdnsDiscovery = function() { - this.handlers_.onBeforeInvokeHandler(); - this.handlers_.enableMdnsDiscovery(); - }; - - /** - * Requests that the provider manager update media sinks. - * @param {!string} sourceUrn - */ - MediaRouteProvider.prototype.updateMediaSinks = function(sourceUrn) { - this.handlers_.onBeforeInvokeHandler(); - this.handlers_.updateMediaSinks(sourceUrn); - }; - - /** - * Requests that the provider manager search its providers for a sink matching - * |searchCriteria| that is compatible with |sourceUrn|. If a sink is found - * that can be used immediately for route creation, its ID is returned. - * Otherwise the empty string is returned. - * - * @param {string} sinkId Sink ID of the pseudo sink generating the request. - * @param {string} sourceUrn Media source to be used with the sink. - * @param {!SinkSearchCriteria} searchCriteria Search criteria for the route - * providers. - * @return {!Promise.<!{sink_id: !string}>} A Promise resolving to either the - * sink ID of the sink found by the search that can be used for route - * creation, or the empty string if no route can be immediately created. - */ - MediaRouteProvider.prototype.searchSinks = function( - sinkId, sourceUrn, searchCriteria) { - this.handlers_.onBeforeInvokeHandler(); - const searchSinksResponse = - this.handlers_.searchSinks(sinkId, sourceUrn, searchCriteria); - - if ('string' == typeof searchSinksResponse) { - // TODO (zijiang): Remove this check when M59 is stable and the - // extension is always returning a promise. - return Promise.resolve({ - 'sink_id': sink_id - }); - } - return searchSinksResponse.then( - sink_id => { - return { 'sink_id': sink_id }; - }, - () => { - return { 'sink_id': '' }; - }); - }; - - /** - * Notifies the provider manager that MediaRouter has discovered a list of - * sinks. - * @param {string} providerName - * @param {!Array<!mediaRouterMojom.MediaSink>} sinks - */ - MediaRouteProvider.prototype.provideSinks = function(providerName, sinks) { - this.handlers_.onBeforeInvokeHandler(); - this.handlers_.provideSinks(providerName, sinks); - }; - - /** - * Creates a controller for the given route and binds the given - * InterfaceRequest to it, and registers an observer for media status updates - * for the route. - * @param {string} routeId - * @param {!bindings.InterfaceRequest} controllerRequest - * @param {!mediaStatusMojom.MediaStatusObserverPtr} observer - * @return {!Promise<!{success: boolean}>} Resolves to true if a controller - * is created. Resolves to false if a controller cannot be created, or if - * the controller is already bound. - */ - MediaRouteProvider.prototype.createMediaRouteController = function( - routeId, controllerRequest, observer) { - this.handlers_.onBeforeInvokeHandler(); - return this.handlers_ - .createMediaRouteController(routeId, controllerRequest, observer) - .then(() => ({success: true}), e => ({success: false})); - }; - - mediaRouter = new MediaRouter(new mediaRouterMojom.MediaRouterPtr( - frameInterfaces.getInterface(mediaRouterMojom.MediaRouter.name))); - - return mediaRouter; }); + +Object.defineProperty(MediaSinkExtraDataAdapter.prototype, 'cast_media_sink', { + get: function() { + if (this.$tag != MediaSinkExtraDataAdapter.Tags.cast_media_sink) { + throw new ReferenceError( + 'MediaSinkExtraDataAdapter.cast_media_sink is not currently set.'); + } + return this.$data; + }, + + set: function(value) { + this.$tag = MediaSinkExtraDataAdapter.Tags.cast_media_sink; + this.$data = value; + } +}); + +MediaSinkExtraDataAdapter.fromNewVersion = function(other) { + if (other.$tag == mediaRouter.mojom.MediaSinkExtraData.Tags.dialMediaSink) { + return new MediaSinkExtraDataAdapter({ + 'dial_media_sink': + DialMediaSinkAdapter.fromNewVersion(other.dialMediaSink), + }); + } else { + return new MediaSinkExtraDataAdapter({ + 'cast_media_sink': + CastMediaSinkAdapter.fromNewVersion(other.castMediaSink), + }); + } +}; + +MediaSinkExtraDataAdapter.prototype.toNewVersion = function() { + if (this.$tag == MediaSinkExtraDataAdapter.Tags.dial_media_sink) { + return new mediaRouter.mojom.MediaSinkExtraData({ + 'dialMediaSink': this.dial_media_sink.toNewVersion(), + }); + } else { + return new mediaRouter.mojom.MediaSinkExtraData({ + 'castMediaSink': this.cast_media_sink.toNewVersion(), + }); + } +}; + +/** + * Adapter for media.mojom.MirrorServiceRemoterPtr. + * @constructor + */ +function MirrorServiceRemoterPtrAdapter(handleOrPtrInfo) { + this.ptr = new mojo.InterfacePtrController(MirrorServiceRemoterAdapter, + handleOrPtrInfo); +} + +MirrorServiceRemoterPtrAdapter.prototype = + Object.create(media.mojom.MirrorServiceRemoterPtr.prototype); +MirrorServiceRemoterPtrAdapter.prototype.constructor = + MirrorServiceRemoterPtrAdapter; + +MirrorServiceRemoterPtrAdapter.prototype.startDataStreams = function() { + return MirrorServiceRemoterProxy.prototype.startDataStreams + .apply(this.ptr.getProxy(), arguments).then(function(response) { + return Promise.resolve({ + 'audio_stream_id': response.audioStreamId, + 'video_stream_id': response.videoStreamId, + }); + }); +}; + +/** + * Adapter for media.mojom.MirrorServiceRemoter.stubclass. + * @constructor + */ +function MirrorServiceRemoterStubAdapter(delegate) { + this.delegate_ = delegate; +} + +MirrorServiceRemoterStubAdapter.prototype = Object.create( + media.mojom.MirrorServiceRemoter.stubClass.prototype); +MirrorServiceRemoterStubAdapter.prototype.constructor = + MirrorServiceRemoterStubAdapter; + +MirrorServiceRemoterStubAdapter.prototype.startDataStreams = + function(hasAudio, hasVideo) { + return this.delegate_ && this.delegate_.startDataStreams && + this.delegate_.startDataStreams(hasAudio, hasVideo).then( + function(response) { + return { + 'audioStreamId': response.audio_stream_id, + 'videoStreamId': response.video_stream_id, + }; + }); +}; + +/** + * Adapter for media.mojom.MirrorServiceRemoter. + */ +var MirrorServiceRemoterAdapter = { + name: 'media::mojom::MirrorServiceRemoter', + kVersion: 0, + ptrClass: MirrorServiceRemoterPtrAdapter, + proxyClass: media.mojom.MirrorServiceRemoter.proxyClass, + stubClass: MirrorServiceRemoterStubAdapter, + validateRequest: media.mojom.MirrorServiceRemoter.validateRequest, + validateResponse: media.mojom.MirrorServiceRemoter.validateResponse, +}; + +/** + * Adapter for media.mojom.MirrorServiceRemotingSourcePtr. + * @constructor + */ +function MirrorServiceRemotingSourcePtrAdapter(handleOrPtrInfo) { + this.ptr = new mojo.InterfacePtrController(MirrorServiceRemotingSourceAdapter, + handleOrPtrInfo); +} + +MirrorServiceRemotingSourcePtrAdapter.prototype = + Object.create(media.mojom.MirrorServiceRemotingSourcePtr.prototype); +MirrorServiceRemotingSourcePtrAdapter.prototype.constructor = + MirrorServiceRemotingSourcePtrAdapter; + +MirrorServiceRemotingSourcePtrAdapter.prototype.onSinkAvailable = + function(metadata) { + return this.ptr.getProxy().onSinkAvailable(metadata.toNewVersion()); +}; + +/** + * Adapter for media.mojom.MirrorServiceRemotingSource. + */ +var MirrorServiceRemotingSourceAdapter = { + name: 'media::mojom::MirrorServiceRemotingSource', + kVersion: 0, + ptrClass: MirrorServiceRemotingSourcePtrAdapter, + proxyClass: media.mojom.MirrorServiceRemotingSource.proxyClass, + stubClass: null, + validateRequest: media.mojom.MirrorServiceRemotingSource.validateRequest, + validateResponse: null, +}; + +/** + * Adapter for mediaRouter.mojom.MediaStatusObserver. + * @constructor + */ +function MediaStatusObserverPtrAdapter(handleOrPtrInfo) { + this.ptr = new mojo.InterfacePtrController(MediaStatusObserverAdapter, + handleOrPtrInfo); +} + +MediaStatusObserverPtrAdapter.prototype = + Object.create(mediaRouter.mojom.MediaStatusObserverPtr.prototype); +MediaStatusObserverPtrAdapter.prototype.constructor = + MediaStatusObserverPtrAdapter; + +MediaStatusObserverPtrAdapter.prototype.onMediaStatusUpdated = + function(status) { + return this.ptr.getProxy().onMediaStatusUpdated(status.toNewVersion()); +}; + +/** + * Adapter for mediaRouter.mojom.MediaStatusObserver. + */ +var MediaStatusObserverAdapter = { + name: 'mediaRouter::mojom::MediaStatusObserver', + kVersion: 0, + ptrClass: MediaStatusObserverPtrAdapter, + proxyClass: mediaRouter.mojom.MediaStatusObserver.proxyClass, + stubClass: null, + validateRequest: mediaRouter.mojom.MediaStatusObserver.validateRequest, + validateResponse: null, +}; + +/** + * Converts a media sink to a MediaSink Mojo object. + * @param {!MediaSink} sink A media sink. + * @return {!mediaRouter.mojom.MediaSink} A Mojo MediaSink object. + */ +function sinkToMojo_(sink) { + return new mediaRouter.mojom.MediaSink({ + 'name': sink.friendlyName, + 'description': sink.description, + 'domain': sink.domain, + 'sinkId': sink.id, + 'iconType': sinkIconTypeToMojo(sink.iconType), + }); +} + +/** + * Converts a media sink's icon type to a MediaSink.IconType Mojo object. + * @param {!MediaSink.IconType} type A media sink's icon type. + * @return {!mediaRouter.mojom.MediaSink.IconType} A Mojo MediaSink.IconType + * object. + */ +function sinkIconTypeToMojo(type) { + switch (type) { + case 'cast': + return mediaRouter.mojom.SinkIconType.CAST; + case 'cast_audio_group': + return mediaRouter.mojom.SinkIconType.CAST_AUDIO_GROUP; + case 'cast_audio': + return mediaRouter.mojom.SinkIconType.CAST_AUDIO; + case 'meeting': + return mediaRouter.mojom.SinkIconType.MEETING; + case 'hangout': + return mediaRouter.mojom.SinkIconType.HANGOUT; + case 'education': + return mediaRouter.mojom.SinkIconType.EDUCATION; + case 'generic': + return mediaRouter.mojom.SinkIconType.GENERIC; + default: + console.error('Unknown sink icon type : ' + type); + return mediaRouter.mojom.SinkIconType.GENERIC; + } +} + +/** + * Returns a Mojo MediaRoute object given a MediaRoute and a + * media sink name. + * @param {!MediaRoute} route + * @return {!mediaRouter.mojom.MediaRoute} + */ +function routeToMojo_(route) { + return new mediaRouter.mojom.MediaRoute({ + 'mediaRouteId': route.id, + 'mediaSource': route.mediaSource, + 'mediaSinkId': route.sinkId, + 'description': route.description, + 'iconUrl': route.iconUrl, + 'isLocal': route.isLocal, + 'customControllerPath': route.customControllerPath || '', + 'forDisplay': route.forDisplay, + 'isIncognito': route.offTheRecord, + 'isLocalPresentation': route.isOffscreenPresentation, + 'supportsMediaRouteController': route.supportsMediaRouteController, + 'controllerType': route.controllerType, + // Begin newly added properties, followed by the milestone they were + // added. The guard should be safe to remove N+2 milestones later. + 'presentationId': route.presentationId || '' // M64 + }); +} + +/** + * Converts a route message to a RouteMessage Mojo object. + * @param {!RouteMessage} message + * @return {!mediaRouter.mojom.RouteMessage} A Mojo RouteMessage object. + */ +function messageToMojo_(message) { + if ("string" == typeof message.message) { + return new mediaRouter.mojom.RouteMessage({ + 'type': mediaRouter.mojom.RouteMessage.Type.TEXT, + 'message': message.message, + }); + } else { + return new mediaRouter.mojom.RouteMessage({ + 'type': mediaRouter.mojom.RouteMessage.Type.BINARY, + 'data': message.message, + }); + } +} + +/** + * Converts presentation connection state to Mojo enum value. + * @param {!string} state + * @return {!mediaRouter.mojom.MediaRouter.PresentationConnectionState} + */ +function presentationConnectionStateToMojo_(state) { + var PresentationConnectionState = + mediaRouter.mojom.MediaRouter.PresentationConnectionState; + switch (state) { + case 'connecting': + return PresentationConnectionState.CONNECTING; + case 'connected': + return PresentationConnectionState.CONNECTED; + case 'closed': + return PresentationConnectionState.CLOSED; + case 'terminated': + return PresentationConnectionState.TERMINATED; + default: + console.error('Unknown presentation connection state: ' + state); + return PresentationConnectionState.TERMINATED; + } +} + +/** + * Converts presentation connection close reason to Mojo enum value. + * @param {!string} reason + * @return {!mediaRouter.mojom.MediaRouter.PresentationConnectionCloseReason} + */ +function presentationConnectionCloseReasonToMojo_(reason) { + var PresentationConnectionCloseReason = + mediaRouter.mojom.MediaRouter.PresentationConnectionCloseReason; + switch (reason) { + case 'error': + return PresentationConnectionCloseReason.CONNECTION_ERROR; + case 'closed': + return PresentationConnectionCloseReason.CLOSED; + case 'went_away': + return PresentationConnectionCloseReason.WENT_AWAY; + default: + console.error('Unknown presentation connection close reason : ' + + reason); + return PresentationConnectionCloseReason.CONNECTION_ERROR; + } +} + +/** + * Parses the given route request Error object and converts it to the + * corresponding result code. + * @param {!Error} error + * @return {!mediaRouter.mojom.RouteRequestResultCode} + */ +function getRouteRequestResultCode_(error) { + return error.errorCode ? error.errorCode : + mediaRouter.mojom.RouteRequestResultCode.UNKNOWN_ERROR; +} + +/** + * Creates and returns a successful route response from given route. + * @param {!MediaRoute} route + * @return {!Object} + */ +function toSuccessRouteResponse_(route) { + return { + route: routeToMojo_(route), + resultCode: mediaRouter.mojom.RouteRequestResultCode.OK + }; +} + +/** + * Creates and returns a error route response from given Error object. + * @param {!Error} error + * @return {!Object} + */ +function toErrorRouteResponse_(error) { + return { + errorText: error.message, + resultCode: getRouteRequestResultCode_(error) + }; +} + +/** + * Creates a new MediaRouter. + * Converts a route struct to its Mojo form. + * @param {!mediaRouter.mojom.MediaRouterPtr} service + * @constructor + */ +function MediaRouter(service) { + /** + * The Mojo service proxy. Allows extension code to call methods that reside + * in the browser. + * @type {!mediaRouter.mojom.MediaRouterPtr} + */ + this.service_ = service; + + /** + * The provider manager service delegate. Its methods are called by the + * browser-resident Mojo service. + * @type {!MediaRouter} + */ + this.mrpm_ = new MediaRouteProvider(this); + + /** + * Handle to a KeepAlive service object, which prevents the extension from + * being suspended as long as it remains in scope. + * @type {boolean} + */ + this.keepAlive_ = null; + + /** + * The bindings to bind the service delegate to the Mojo interface. + * Object must remain in scope for the lifetime of the connection to + * prevent the connection from closing automatically. + * @type {!mojo.Binding} + */ + this.mediaRouteProviderBinding_ = new mojo.Binding( + mediaRouter.mojom.MediaRouteProvider, this.mrpm_); +} + +/** + * Returns definitions of Mojo core and generated Mojom classes that can be + * used directly by the component. + * @return {!Object} + * TODO(imcheng): We should export these along with MediaRouter. This requires + * us to modify the component to handle multiple exports. When that logic is + * baked in for a couple of milestones, we should be able to remove this + * method. + * TODO(imcheng): We should stop exporting mojo bindings classes that the + * Media Router extension doesn't directly use, such as + * mojo.AssociatedInterfacePtrInfo, mojo.InterfacePtrController and + * mojo.interfaceControl2. + */ +MediaRouter.prototype.getMojoExports = function() { + return { + AssociatedInterfacePtrInfo: mojo.AssociatedInterfacePtrInfo, + Binding: mojo.Binding, + DialMediaSink: DialMediaSinkAdapter, + CastMediaSink: CastMediaSinkAdapter, + HangoutsMediaRouteController: + mediaRouter.mojom.HangoutsMediaRouteController, + HangoutsMediaStatusExtraData: HangoutsMediaStatusExtraDataAdapter, + IPAddress: IPAddressAdapter, + IPEndpoint: IPEndpointAdapter, + InterfacePtrController: mojo.InterfacePtrController, + InterfacePtrInfo: mojo.InterfacePtrInfo, + InterfaceRequest: mojo.InterfaceRequest, + MediaController: mediaRouter.mojom.MediaController, + MediaStatus: MediaStatusAdapter, + MediaStatusObserverPtr: mediaRouter.mojom.MediaStatusObserverPtr, + MirrorServiceRemoter: MirrorServiceRemoterAdapter, + MirrorServiceRemoterPtr: MirrorServiceRemoterPtrAdapter, + MirrorServiceRemotingSourcePtr: MirrorServiceRemotingSourcePtrAdapter, + RemotingStopReason: media.mojom.RemotingStopReason, + RemotingStartFailReason: media.mojom.RemotingStartFailReason, + RemotingSinkFeature: media.mojom.RemotingSinkFeature, + RemotingSinkAudioCapability: + media.mojom.RemotingSinkAudioCapability, + RemotingSinkVideoCapability: + media.mojom.RemotingSinkVideoCapability, + RemotingSinkMetadata: RemotingSinkMetadataAdapter, + RouteControllerType: mediaRouter.mojom.RouteControllerType, + Origin: url.mojom.Origin, + Sink: MediaSinkAdapter, + SinkExtraData: MediaSinkExtraDataAdapter, + TimeDelta: mojo.common.mojom.TimeDelta, + Url: url.mojom.Url, + interfaceControl2: mojo.interfaceControl2, + makeRequest: mojo.makeRequest, + }; +}; + +/** + * Registers the Media Router Provider Manager with the Media Router. + * @return {!Promise<Object>} Instance ID and config for the Media Router. + */ +MediaRouter.prototype.start = function() { + return this.service_.registerMediaRouteProvider( + mediaRouter.mojom.MediaRouteProvider.Id.EXTENSION, + this.mediaRouteProviderBinding_.createInterfacePtrAndBind()).then( + function(response) { + return { + 'enable_dial_discovery': response.enableDialDiscovery, + 'enable_cast_discovery': response.enableCastDiscovery, + }; + }); +} + +/** + * Sets the service delegate methods. + * @param {Object} handlers + */ +MediaRouter.prototype.setHandlers = function(handlers) { + this.mrpm_.setHandlers(handlers); +} + +/** + * The keep alive status. + * @return {boolean} + */ +MediaRouter.prototype.getKeepAlive = function() { + return this.keepAlive_ != null; +}; + +/** + * Called by the provider manager when a sink list for a given source is + * updated. + * @param {!string} sourceUrn + * @param {!Array<!MediaSink>} sinks + * @param {!Array<!url.mojom.Origin>} origins + */ +MediaRouter.prototype.onSinksReceived = function(sourceUrn, sinks, origins) { + this.service_.onSinksReceived( + mediaRouter.mojom.MediaRouteProvider.Id.EXTENSION, sourceUrn, + sinks.map(sinkToMojo_), origins); +}; + +/** + * Called by the provider manager when a sink is found to notify the MR of the + * sink's ID. The actual sink will be returned through the normal sink list + * update process, so this helps the MR identify the search result in the + * list. + * @param {string} pseudoSinkId ID of the pseudo sink that started the + * search. + * @param {string} sinkId ID of the newly-found sink. + */ +MediaRouter.prototype.onSearchSinkIdReceived = function( + pseudoSinkId, sinkId) { + this.service_.onSearchSinkIdReceived(pseudoSinkId, sinkId); +}; + +/** + * Called by the provider manager to keep the extension from suspending + * if it enters a state where suspension is undesirable (e.g. there is an + * active MediaRoute.) + * If keepAlive is true, the extension is kept alive. + * If keepAlive is false, the extension is allowed to suspend. + * @param {boolean} keepAlive + */ +MediaRouter.prototype.setKeepAlive = function(keepAlive) { + if (keepAlive === false && this.keepAlive_) { + this.keepAlive_.ptr.reset(); + this.keepAlive_ = null; + } else if (keepAlive === true && !this.keepAlive_) { + this.keepAlive_ = new extensions.KeepAlivePtr; + Mojo.bindInterface(extensions.KeepAlive.name, + mojo.makeRequest(this.keepAlive_).handle); + } +}; + +/** + * Called by the provider manager to send an issue from a media route + * provider to the Media Router, to show the user. + * @param {!Object} issue The issue object. + */ +MediaRouter.prototype.onIssue = function(issue) { + function issueSeverityToMojo_(severity) { + switch (severity) { + case 'fatal': + return mediaRouter.mojom.Issue.Severity.FATAL; + case 'warning': + return mediaRouter.mojom.Issue.Severity.WARNING; + case 'notification': + return mediaRouter.mojom.Issue.Severity.NOTIFICATION; + default: + console.error('Unknown issue severity: ' + severity); + return mediaRouter.mojom.Issue.Severity.NOTIFICATION; + } + } + + function issueActionToMojo_(action) { + switch (action) { + case 'dismiss': + return mediaRouter.mojom.Issue.ActionType.DISMISS; + case 'learn_more': + return mediaRouter.mojom.Issue.ActionType.LEARN_MORE; + default: + console.error('Unknown issue action type : ' + action); + return mediaRouter.mojom.Issue.ActionType.OK; + } + } + + var secondaryActions = (issue.secondaryActions || []).map(issueActionToMojo_); + this.service_.onIssue(new mediaRouter.mojom.Issue({ + 'routeId': issue.routeId || '', + 'severity': issueSeverityToMojo_(issue.severity), + 'title': issue.title, + 'message': issue.message || '', + 'defaultAction': issueActionToMojo_(issue.defaultAction), + 'secondaryActions': secondaryActions, + 'helpPageId': issue.helpPageId, + 'isBlocking': issue.isBlocking + })); +}; + +/** + * Called by the provider manager when the set of active routes + * has been updated. + * @param {!Array<MediaRoute>} routes The active set of media routes. + * @param {string=} sourceUrn The sourceUrn associated with this route + * query. + * @param {Array<string>=} joinableRouteIds The active set of joinable + * media routes. + */ +MediaRouter.prototype.onRoutesUpdated = function( + routes, sourceUrn = '', joinableRouteIds = []) { + this.service_.onRoutesUpdated( + mediaRouter.mojom.MediaRouteProvider.Id.EXTENSION, + routes.map(routeToMojo_), sourceUrn, joinableRouteIds); +}; + +/** + * Called by the provider manager when sink availability has been updated. + * @param {!mediaRouter.mojom.MediaRouter.SinkAvailability} availability + * The new sink availability. + */ +MediaRouter.prototype.onSinkAvailabilityUpdated = function(availability) { + this.service_.onSinkAvailabilityUpdated( + mediaRouter.mojom.MediaRouteProvider.Id.EXTENSION, availability); +}; + +/** + * Called by the provider manager when the state of a presentation connected + * to a route has changed. + * @param {string} routeId + * @param {string} state + */ +MediaRouter.prototype.onPresentationConnectionStateChanged = + function(routeId, state) { + this.service_.onPresentationConnectionStateChanged( + routeId, presentationConnectionStateToMojo_(state)); +}; + +/** + * Called by the provider manager when the state of a presentation connected + * to a route has closed. + * @param {string} routeId + * @param {string} reason + * @param {string} message + */ +MediaRouter.prototype.onPresentationConnectionClosed = + function(routeId, reason, message) { + this.service_.onPresentationConnectionClosed( + routeId, presentationConnectionCloseReasonToMojo_(reason), message); +}; + +/** + * @param {string} routeId + * @param {!Array<!RouteMessage>} mesages + */ +MediaRouter.prototype.onRouteMessagesReceived = function(routeId, messages) { + this.service_.onRouteMessagesReceived( + routeId, messages.map(messageToMojo_)); +}; + +/** + * @param {number} tabId + * @param {!media.mojom.MirrorServiceRemoterPtr} remoter + * @param {!mojo.InterfaceRequest} remotingSource + */ +MediaRouter.prototype.onMediaRemoterCreated = function(tabId, remoter, + remotingSource) { + this.service_.onMediaRemoterCreated( + tabId, + new media.mojom.MirrorServiceRemoterPtr(remoter.ptr.passInterface()), + remotingSource); +} + +/** + * Object containing callbacks set by the provider manager. + * + * @constructor + * @struct + */ +function MediaRouterHandlers() { + /** + * @type {function(!string, !string, !string, !string, !number)} + */ + this.createRoute = null; + + /** + * @type {function(!string, !string, !string, !number)} + */ + this.joinRoute = null; + + /** + * @type {function(string): Promise} + */ + this.terminateRoute = null; + + /** + * @type {function(string)} + */ + this.startObservingMediaSinks = null; + + /** + * @type {function(string)} + */ + this.stopObservingMediaSinks = null; + + /** + * @type {function(string, string): Promise} + */ + this.sendRouteMessage = null; + + /** + * @type {function(string, Uint8Array): Promise} + */ + this.sendRouteBinaryMessage = null; + + /** + * @type {function(string)} + */ + this.startListeningForRouteMessages = null; + + /** + * @type {function(string)} + */ + this.stopListeningForRouteMessages = null; + + /** + * @type {function(string)} + */ + this.detachRoute = null; + + /** + * @type {function()} + */ + this.startObservingMediaRoutes = null; + + /** + * @type {function()} + */ + this.stopObservingMediaRoutes = null; + + /** + * @type {function()} + */ + this.connectRouteByRouteId = null; + + /** + * @type {function()} + */ + this.enableMdnsDiscovery = null; + + /** + * @type {function()} + */ + this.updateMediaSinks = null; + + /** + * @type {function(string, string, !SinkSearchCriteria): string} + */ + this.searchSinks = null; + + /** + * @type {function()} + */ + this.provideSinks = null; + + /** + * @type {function(string, !mojo.InterfaceRequest, + * !mediaRouter.mojom.MediaStatusObserverPtr): !Promise<void>} + */ + this.createMediaRouteController = null; +}; + +/** + * Routes calls from Media Router to the provider manager extension. + * Registered with the MediaRouter stub. + * @param {!MediaRouter} MediaRouter proxy to call into the + * Media Router mojo interface. + * @constructor + */ +function MediaRouteProvider(mediaRouter) { + /** + * Object containing JS callbacks into Provider Manager code. + * @type {!MediaRouterHandlers} + */ + this.handlers_ = new MediaRouterHandlers(); + + /** + * Proxy class to the browser's Media Router Mojo service. + * @type {!MediaRouter} + */ + this.mediaRouter_ = mediaRouter; +} + +/* + * Sets the callback handler used to invoke methods in the provider manager. + * + * @param {!MediaRouterHandlers} handlers + */ +MediaRouteProvider.prototype.setHandlers = function(handlers) { + this.handlers_ = handlers; + var requiredHandlers = [ + 'stopObservingMediaRoutes', + 'startObservingMediaRoutes', + 'sendRouteMessage', + 'sendRouteBinaryMessage', + 'startListeningForRouteMessages', + 'stopListeningForRouteMessages', + 'detachRoute', + 'terminateRoute', + 'joinRoute', + 'createRoute', + 'stopObservingMediaSinks', + 'startObservingMediaRoutes', + 'connectRouteByRouteId', + 'enableMdnsDiscovery', + 'updateMediaSinks', + 'searchSinks', + 'provideSinks', + 'createMediaRouteController', + 'onBeforeInvokeHandler' + ]; + requiredHandlers.forEach(function(nextHandler) { + if (handlers[nextHandler] === undefined) { + console.error(nextHandler + ' handler not registered.'); + } + }); +} + +/** + * Starts querying for sinks capable of displaying the media source + * designated by |sourceUrn|. Results are returned by calling + * OnSinksReceived. + * @param {!string} sourceUrn + */ +MediaRouteProvider.prototype.startObservingMediaSinks = + function(sourceUrn) { + this.handlers_.onBeforeInvokeHandler(); + this.handlers_.startObservingMediaSinks(sourceUrn); +}; + +/** + * Stops querying for sinks capable of displaying |sourceUrn|. + * @param {!string} sourceUrn + */ +MediaRouteProvider.prototype.stopObservingMediaSinks = + function(sourceUrn) { + this.handlers_.onBeforeInvokeHandler(); + this.handlers_.stopObservingMediaSinks(sourceUrn); +}; + +/** + * Requests that |sinkId| render the media referenced by |sourceUrn|. If the + * request is from the Presentation API, then origin and tabId will + * be populated. + * @param {!string} sourceUrn Media source to render. + * @param {!string} sinkId Media sink ID. + * @param {!string} presentationId Presentation ID from the site + * requesting presentation. TODO(mfoltz): Remove. + * @param {!url.mojom.Origin} origin Origin of site requesting presentation. + * @param {!number} tabId ID of tab requesting presentation. + * @param {!mojo.common.mojom.TimeDelta} timeout If positive, the timeout + * duration for the request. Otherwise, the default duration will be used. + * @param {!boolean} incognito If true, the route is being requested by + * an incognito profile. + * @return {!Promise.<!Object>} A Promise resolving to an object describing + * the newly created media route, or rejecting with an error message on + * failure. + */ +MediaRouteProvider.prototype.createRoute = + function(sourceUrn, sinkId, presentationId, origin, tabId, + timeout, incognito) { + this.handlers_.onBeforeInvokeHandler(); + return this.handlers_.createRoute( + sourceUrn, sinkId, presentationId, origin, tabId, + Math.floor(timeout.microseconds / 1000), incognito) + .then(function(route) { + return toSuccessRouteResponse_(route); + }, + function(err) { + return toErrorRouteResponse_(err); + }); +}; + +/** + * Handles a request via the Presentation API to join an existing route given + * by |sourceUrn| and |presentationId|. |origin| and |tabId| are used for + * validating same-origin/tab scope. + * @param {!string} sourceUrn Media source to render. + * @param {!string} presentationId Presentation ID to join. + * @param {!url.mojom.Origin} origin Origin of site requesting join. + * @param {!number} tabId ID of tab requesting join. + * @param {!mojo.common.mojom.TimeDelta} timeout If positive, the timeout + * duration for the request. Otherwise, the default duration will be used. + * @param {!boolean} incognito If true, the route is being requested by + * an incognito profile. + * @return {!Promise.<!Object>} A Promise resolving to an object describing + * the newly created media route, or rejecting with an error message on + * failure. + */ +MediaRouteProvider.prototype.joinRoute = + function(sourceUrn, presentationId, origin, tabId, timeout, + incognito) { + this.handlers_.onBeforeInvokeHandler(); + return this.handlers_.joinRoute( + sourceUrn, presentationId, origin, tabId, + Math.floor(timeout.microseconds / 1000), incognito) + .then(function(route) { + return toSuccessRouteResponse_(route); + }, + function(err) { + return toErrorRouteResponse_(err); + }); +}; + +/** + * Handles a request via the Presentation API to join an existing route given + * by |sourceUrn| and |routeId|. |origin| and |tabId| are used for + * validating same-origin/tab scope. + * @param {!string} sourceUrn Media source to render. + * @param {!string} routeId Route ID to join. + * @param {!string} presentationId Presentation ID to join. + * @param {!url.mojom.Origin} origin Origin of site requesting join. + * @param {!number} tabId ID of tab requesting join. + * @param {!mojo.common.mojom.TimeDelta} timeout If positive, the timeout + * duration for the request. Otherwise, the default duration will be used. + * @param {!boolean} incognito If true, the route is being requested by + * an incognito profile. + * @return {!Promise.<!Object>} A Promise resolving to an object describing + * the newly created media route, or rejecting with an error message on + * failure. + */ +MediaRouteProvider.prototype.connectRouteByRouteId = + function(sourceUrn, routeId, presentationId, origin, tabId, + timeout, incognito) { + this.handlers_.onBeforeInvokeHandler(); + return this.handlers_.connectRouteByRouteId( + sourceUrn, routeId, presentationId, origin, tabId, + Math.floor(timeout.microseconds / 1000), incognito) + .then(function(route) { + return toSuccessRouteResponse_(route); + }, + function(err) { + return toErrorRouteResponse_(err); + }); +}; + +/** + * Terminates the route specified by |routeId|. + * @param {!string} routeId + * @return {!Promise<!Object>} A Promise resolving to an object describing + * the result of the terminate operation, or rejecting with an error + * message and code if the operation failed. + */ +MediaRouteProvider.prototype.terminateRoute = function(routeId) { + this.handlers_.onBeforeInvokeHandler(); + return this.handlers_.terminateRoute(routeId).then( + () => ({resultCode: mediaRouter.mojom.RouteRequestResultCode.OK}), + (err) => toErrorRouteResponse_(err)); +}; + +/** + * Posts a message to the route designated by |routeId|. + * @param {!string} routeId + * @param {!string} message + * @return {!Promise.<boolean>} Resolved with true if the message was sent, + * or false on failure. + */ +MediaRouteProvider.prototype.sendRouteMessage = function( + routeId, message) { + this.handlers_.onBeforeInvokeHandler(); + return this.handlers_.sendRouteMessage(routeId, message) + .then(function() { + return {'sent': true}; + }, function() { + return {'sent': false}; + }); +}; + +/** + * Sends a binary message to the route designated by |routeId|. + * @param {!string} routeId + * @param {!Array<number>} data + * @return {!Promise.<boolean>} Resolved with true if the data was sent, + * or false on failure. + */ +MediaRouteProvider.prototype.sendRouteBinaryMessage = function( + routeId, data) { + this.handlers_.onBeforeInvokeHandler(); + return this.handlers_.sendRouteBinaryMessage(routeId, new Uint8Array(data)) + .then(function() { + return {'sent': true}; + }, function() { + return {'sent': false}; + }); +}; + +/** + * Listen for messages from a route. + * @param {!string} routeId + */ +MediaRouteProvider.prototype.startListeningForRouteMessages = function( + routeId) { + this.handlers_.onBeforeInvokeHandler(); + this.handlers_.startListeningForRouteMessages(routeId); +}; + +/** + * @param {!string} routeId + */ +MediaRouteProvider.prototype.stopListeningForRouteMessages = function( + routeId) { + this.handlers_.onBeforeInvokeHandler(); + this.handlers_.stopListeningForRouteMessages(routeId); +}; + +/** + * Indicates that the presentation connection that was connected to |routeId| + * is no longer connected to it. + * @param {!string} routeId + */ +MediaRouteProvider.prototype.detachRoute = function( + routeId) { + this.handlers_.detachRoute(routeId); +}; + +/** + * Requests that the provider manager start sending information about active + * media routes to the Media Router. + * @param {!string} sourceUrn + */ +MediaRouteProvider.prototype.startObservingMediaRoutes = function(sourceUrn) { + this.handlers_.onBeforeInvokeHandler(); + this.handlers_.startObservingMediaRoutes(sourceUrn); +}; + +/** + * Requests that the provider manager stop sending information about active + * media routes to the Media Router. + * @param {!string} sourceUrn + */ +MediaRouteProvider.prototype.stopObservingMediaRoutes = function(sourceUrn) { + this.handlers_.onBeforeInvokeHandler(); + this.handlers_.stopObservingMediaRoutes(sourceUrn); +}; + +/** + * Enables mDNS device discovery. + */ +MediaRouteProvider.prototype.enableMdnsDiscovery = function() { + this.handlers_.onBeforeInvokeHandler(); + this.handlers_.enableMdnsDiscovery(); +}; + +/** + * Requests that the provider manager update media sinks. + * @param {!string} sourceUrn + */ +MediaRouteProvider.prototype.updateMediaSinks = function(sourceUrn) { + this.handlers_.onBeforeInvokeHandler(); + this.handlers_.updateMediaSinks(sourceUrn); +}; + +/** + * Requests that the provider manager search its providers for a sink matching + * |searchCriteria| that is compatible with |sourceUrn|. If a sink is found + * that can be used immediately for route creation, its ID is returned. + * Otherwise the empty string is returned. + * + * @param {string} sinkId Sink ID of the pseudo sink generating the request. + * @param {string} sourceUrn Media source to be used with the sink. + * @param {!SinkSearchCriteria} searchCriteria Search criteria for the route + * providers. + * @return {!Promise.<!{sink_id: !string}>} A Promise resolving to either the + * sink ID of the sink found by the search that can be used for route + * creation, or the empty string if no route can be immediately created. + */ +MediaRouteProvider.prototype.searchSinks = function( + sinkId, sourceUrn, searchCriteria) { + this.handlers_.onBeforeInvokeHandler(); + return this.handlers_.searchSinks(sinkId, sourceUrn, searchCriteria).then( + sinkId => { + return { 'sinkId': sinkId }; + }, + () => { + return { 'sinkId': '' }; + }); +}; + +/** + * Notifies the provider manager that MediaRouter has discovered a list of + * sinks. + * @param {string} providerName + * @param {!Array<!mediaRouter.mojom.MediaSink>} sinks + */ +MediaRouteProvider.prototype.provideSinks = function(providerName, sinks) { + this.handlers_.onBeforeInvokeHandler(); + this.handlers_.provideSinks(providerName, + sinks.map(MediaSinkAdapter.fromNewVersion)); +}; + +/** + * Creates a controller for the given route and binds the given + * InterfaceRequest to it, and registers an observer for media status updates + * for the route. + * @param {string} routeId + * @param {!mojo.InterfaceRequest} controllerRequest + * @param {!mediaRouter.mojom.MediaStatusObserverPtr} observer + * @return {!Promise<!{success: boolean}>} Resolves to true if a controller + * is created. Resolves to false if a controller cannot be created, or if + * the controller is already bound. + */ +MediaRouteProvider.prototype.createMediaRouteController = function( + routeId, controllerRequest, observer) { + this.handlers_.onBeforeInvokeHandler(); + return this.handlers_.createMediaRouteController( + routeId, controllerRequest, + new MediaStatusObserverPtrAdapter(observer.ptr.passInterface())).then( + () => ({success: true}), e => ({success: false})); +}; + +var ptr = new mediaRouter.mojom.MediaRouterPtr; +Mojo.bindInterface(mediaRouter.mojom.MediaRouter.name, + mojo.makeRequest(ptr).handle); +exports.$set('returnValue', new MediaRouter(ptr));
diff --git a/chrome/test/data/android/render_tests/BookmarkTest.bookmark_manager_folder_selected.Nexus_5-19.png b/chrome/test/data/android/render_tests/BookmarkTest.bookmark_manager_folder_selected.Nexus_5-19.png index 97f0432..a42d94f 100644 --- a/chrome/test/data/android/render_tests/BookmarkTest.bookmark_manager_folder_selected.Nexus_5-19.png +++ b/chrome/test/data/android/render_tests/BookmarkTest.bookmark_manager_folder_selected.Nexus_5-19.png Binary files differ
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.cc index a1e29f1..66e8828 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.cc
@@ -552,16 +552,6 @@ warmup_url_fetcher_->FetchWarmupURL(); } -bool DataReductionProxyConfig::ShouldEnableServerPreviews( - const net::URLRequest& request, - const previews::PreviewsDecider& previews_decider) { - DCHECK(thread_checker_.CalledOnValidThread()); - DCHECK((request.load_flags() & net::LOAD_MAIN_FRAME_DEPRECATED) != 0); - DCHECK(!request.url().SchemeIsCryptographic()); - - return ShouldAcceptServerPreview(request, previews_decider); -} - bool DataReductionProxyConfig::enabled_by_user_and_reachable() const { DCHECK(thread_checker_.CalledOnValidThread()); return enabled_by_user_ && !unreachable_; @@ -584,6 +574,8 @@ const net::URLRequest& request, const previews::PreviewsDecider& previews_decider) const { DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK((request.load_flags() & net::LOAD_MAIN_FRAME_DEPRECATED) != 0); + DCHECK(!request.url().SchemeIsCryptographic()); if (!base::FeatureList::IsEnabled( features::kDataReductionProxyDecidesTransform)) {
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.h b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.h index 5a3f59e1..787e4f8e 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.h +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.h
@@ -173,13 +173,14 @@ virtual bool ContainsDataReductionProxy( const net::ProxyConfig::ProxyRules& proxy_rules) const; - // Returns true when server previews should be activated. Records metrics for - // previews state changes. |request| is used to get the network quality - // estimator from the URLRequestContext. |previews_decider| is used to check - // if |request| is locally blacklisted. - bool ShouldEnableServerPreviews( + // Returns whether the client should report to the data reduction proxy that + // it is willing to accept server previews for |request|. + // |previews_decider| is used to check if |request| is locally blacklisted. + // Should only be used if the kDataReductionProxyDecidesTransform feature is + // enabled. + bool ShouldAcceptServerPreview( const net::URLRequest& request, - const previews::PreviewsDecider& previews_decider); + const previews::PreviewsDecider& previews_decider) const; // Returns true if the data saver has been enabled by the user, and the data // saver proxy is reachable. @@ -283,15 +284,6 @@ const previews::PreviewsDecider& previews_decider, previews::PreviewsType previews_type) const; - // Returns whether the client should report to the data reduction proxy that - // it is willing to accept server previews for |request|. - // |previews_decider| is used to check if |request| is locally blacklisted. - // Should only be used if the kDataReductionProxyDecidesTransform feature is - // enabled. - bool ShouldAcceptServerPreview( - const net::URLRequest& request, - const previews::PreviewsDecider& previews_decider) const; - // Checks if the current network has captive portal, and handles the result. // If the captive portal probe was blocked on the current network, disables // the use of secure proxies.
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_unittest.cc index 500add8..864afc9e 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_unittest.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_unittest.cc
@@ -1011,11 +1011,11 @@ net::LOAD_MAIN_FRAME_DEPRECATED); std::unique_ptr<TestPreviewsDecider> previews_decider = base::MakeUnique<TestPreviewsDecider>(true); - EXPECT_TRUE(test_config()->ShouldEnableServerPreviews( + EXPECT_TRUE(test_config()->ShouldAcceptServerPreview( *request.get(), *previews_decider.get())); previews_decider = base::MakeUnique<TestPreviewsDecider>(false); - EXPECT_FALSE(test_config()->ShouldEnableServerPreviews( + EXPECT_FALSE(test_config()->ShouldAcceptServerPreview( *request.get(), *previews_decider.get())); }
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.cc index 98e55d4..1c0937c50 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.cc
@@ -309,7 +309,7 @@ config_client_->ApplySerializedConfig(serialized_config); } -bool DataReductionProxyIOData::ShouldEnableServerPreviews( +bool DataReductionProxyIOData::ShouldAcceptServerPreview( const net::URLRequest& request, previews::PreviewsDecider* previews_decider) { DCHECK(previews_decider); @@ -318,7 +318,7 @@ request, configurator_->GetProxyConfig()))) { return false; } - return config_->ShouldEnableServerPreviews(request, *previews_decider); + return config_->ShouldAcceptServerPreview(request, *previews_decider); } void DataReductionProxyIOData::UpdateDataUseForHost(int64_t network_bytes,
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.h b/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.h index ae80b3d..c2f2144 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.h +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.h
@@ -107,8 +107,8 @@ // are active, URL requests are modified to request low fidelity versions of // the resources.|previews_decider| is a non-null object that determines // eligibility of showing the preview based on past opt outs. - bool ShouldEnableServerPreviews(const net::URLRequest& request, - previews::PreviewsDecider* previews_decider); + bool ShouldAcceptServerPreview(const net::URLRequest& request, + previews::PreviewsDecider* previews_decider); // Bridge methods to safely call to the UI thread objects. void UpdateDataUseForHost(int64_t network_bytes,
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate_unittest.cc index 8d83f28..9556511 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate_unittest.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate_unittest.cc
@@ -981,7 +981,7 @@ std::unique_ptr<net::URLRequest> fake_request = context()->CreateRequest( GURL(kTestURL), net::IDLE, &delegate, TRAFFIC_ANNOTATION_FOR_TESTS); fake_request->SetLoadFlags(net::LOAD_MAIN_FRAME_DEPRECATED); - lofi_decider()->SetIsUsingLoFi(config()->ShouldEnableServerPreviews( + lofi_decider()->SetIsUsingLoFi(config()->ShouldAcceptServerPreview( *fake_request.get(), test_previews_decider)); NotifyNetworkDelegate(fake_request.get(), data_reduction_proxy_info, proxy_retry_info, &headers); @@ -989,8 +989,8 @@ VerifyHeaders(tests[i].is_data_reduction_proxy, true, headers); VerifyDataReductionProxyData( *fake_request, tests[i].is_data_reduction_proxy, - config()->ShouldEnableServerPreviews(*fake_request.get(), - test_previews_decider)); + config()->ShouldAcceptServerPreview(*fake_request.get(), + test_previews_decider)); } { @@ -1064,14 +1064,14 @@ std::unique_ptr<net::URLRequest> fake_request = context()->CreateRequest( GURL(kTestURL), net::IDLE, &delegate, TRAFFIC_ANNOTATION_FOR_TESTS); fake_request->SetLoadFlags(net::LOAD_MAIN_FRAME_DEPRECATED); - lofi_decider()->SetIsUsingLoFi(config()->ShouldEnableServerPreviews( + lofi_decider()->SetIsUsingLoFi(config()->ShouldAcceptServerPreview( *fake_request.get(), test_previews_decider)); NotifyNetworkDelegate(fake_request.get(), data_reduction_proxy_info, proxy_retry_info, &headers); VerifyDataReductionProxyData( *fake_request, tests[i].is_data_reduction_proxy, - config()->ShouldEnableServerPreviews(*fake_request.get(), - test_previews_decider)); + config()->ShouldAcceptServerPreview(*fake_request.get(), + test_previews_decider)); } } } @@ -1361,7 +1361,7 @@ // Needed as a parameter, but functionality is not tested. TestPreviewsDecider test_previews_decider; - lofi_decider()->SetIsUsingLoFi(config()->ShouldEnableServerPreviews( + lofi_decider()->SetIsUsingLoFi(config()->ShouldAcceptServerPreview( *fake_request.get(), test_previews_decider)); fake_request = (FetchURLRequest(GURL(kTestURL), nullptr, response_headers,
diff --git a/components/download/downloader/in_progress/BUILD.gn b/components/download/downloader/in_progress/BUILD.gn index a1995c6..e9aba57c 100644 --- a/components/download/downloader/in_progress/BUILD.gn +++ b/components/download/downloader/in_progress/BUILD.gn
@@ -12,8 +12,9 @@ "download_entry.cc", "download_entry.h", "download_source.h", - "in_progress_cache.cc", "in_progress_cache.h", + "in_progress_cache_impl.cc", + "in_progress_cache_impl.h", "in_progress_conversions.cc", "in_progress_conversions.h", ] @@ -28,6 +29,7 @@ testonly = true sources = [ + "in_progress_cache_impl_unittest.cc", "in_progress_conversions_unittest.cc", ] @@ -35,6 +37,7 @@ ":in_progress", "//base/test:test_support", "//components/download/downloader/in_progress/proto", + "//content/test:test_support", "//testing/gmock", "//testing/gtest", ]
diff --git a/components/download/downloader/in_progress/in_progress_cache.cc b/components/download/downloader/in_progress/in_progress_cache.cc deleted file mode 100644 index 81649288..0000000 --- a/components/download/downloader/in_progress/in_progress_cache.cc +++ /dev/null
@@ -1,28 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/download/downloader/in_progress/in_progress_cache.h" - -namespace download { - -InProgressCache::InProgressCache( - const base::FilePath& cache_file_path, - const scoped_refptr<base::SequencedTaskRunner>& task_runner) {} - -InProgressCache::~InProgressCache() = default; - -void InProgressCache::AddOrReplaceEntry(const DownloadEntry& entry) { - // TODO(jming): Implementation. -} - -DownloadEntry* InProgressCache::RetrieveEntry(const std::string& guid) { - // TODO(jming): Implementation. - return nullptr; -} - -void InProgressCache::RemoveEntry(const std::string& guid) { - // TODO(jming): Implementation. -} - -} // namespace download
diff --git a/components/download/downloader/in_progress/in_progress_cache.h b/components/download/downloader/in_progress/in_progress_cache.h index 40f11b5..af2c859 100644 --- a/components/download/downloader/in_progress/in_progress_cache.h +++ b/components/download/downloader/in_progress/in_progress_cache.h
@@ -7,11 +7,8 @@ #include <string> -#include "base/files/file_path.h" -#include "base/macros.h" -#include "base/sequenced_task_runner.h" +#include "base/optional.h" #include "components/download/downloader/in_progress/download_entry.h" -#include "components/download/downloader/in_progress/proto/download_entry.pb.h" namespace download { @@ -21,21 +18,20 @@ // right away for now (might not be in the case in the long run). class InProgressCache { public: - InProgressCache(const base::FilePath& cache_file_path, - const scoped_refptr<base::SequencedTaskRunner>& task_runner); - ~InProgressCache(); + virtual ~InProgressCache() = default; + + // Initializes the cache. + virtual void Initialize(const base::RepeatingClosure& callback) = 0; // Adds or updates an existing entry. - void AddOrReplaceEntry(const DownloadEntry& entry); + virtual void AddOrReplaceEntry(const DownloadEntry& entry) = 0; // Retrieves an existing entry. - DownloadEntry* RetrieveEntry(const std::string& guid); + virtual base::Optional<DownloadEntry> RetrieveEntry( + const std::string& guid) = 0; // Removes an entry. - void RemoveEntry(const std::string& guid); - - private: - DISALLOW_COPY_AND_ASSIGN(InProgressCache); + virtual void RemoveEntry(const std::string& guid) = 0; }; } // namespace download
diff --git a/components/download/downloader/in_progress/in_progress_cache_impl.cc b/components/download/downloader/in_progress/in_progress_cache_impl.cc new file mode 100644 index 0000000..34fd266b --- /dev/null +++ b/components/download/downloader/in_progress/in_progress_cache_impl.cc
@@ -0,0 +1,211 @@ +// 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 "components/download/downloader/in_progress/in_progress_cache_impl.h" + +#include "base/bind.h" +#include "base/files/file.h" +#include "base/files/file_util.h" +#include "base/files/important_file_writer.h" +#include "base/task_runner_util.h" +#include "base/threading/thread_task_runner_handle.h" +#include "components/download/downloader/in_progress/in_progress_conversions.h" + +namespace download { + +namespace { + +// Helper functions for |entries_| related operations. +int GetIndexFromEntries(const metadata_pb::DownloadEntries& entries, + const std::string& guid) { + int size_of_entries = entries.entries_size(); + for (int i = 0; i < size_of_entries; i++) { + if (entries.entries(i).guid() == guid) + return i; + } + return -1; +} + +void AddOrReplaceEntryInEntries(metadata_pb::DownloadEntries& entries, + const DownloadEntry& entry) { + metadata_pb::DownloadEntry metadata_entry = + InProgressConversions::DownloadEntryToProto(entry); + int entry_index = GetIndexFromEntries(entries, metadata_entry.guid()); + metadata_pb::DownloadEntry* entry_ptr = + (entry_index < 0) ? entries.add_entries() + : entries.mutable_entries(entry_index); + *entry_ptr = metadata_entry; +} + +base::Optional<DownloadEntry> GetEntryFromEntries( + const metadata_pb::DownloadEntries& entries, + const std::string& guid) { + int entry_index = GetIndexFromEntries(entries, guid); + if (entry_index < 0) + return base::nullopt; + return InProgressConversions::DownloadEntryFromProto( + entries.entries(entry_index)); +} + +void RemoveEntryFromEntries(metadata_pb::DownloadEntries& entries, + const std::string& guid) { + int entry_index = GetIndexFromEntries(entries, guid); + if (entry_index >= 0) + entries.mutable_entries()->DeleteSubrange(entry_index, 1); +} + +// Helper functions for file read/write operations. +std::vector<char> ReadEntriesFromFile(base::FilePath file_path) { + // Check validity of file. + base::File entries_file(file_path, + base::File::FLAG_OPEN | base::File::FLAG_READ); + if (!entries_file.IsValid()) { + // The file just doesn't exist yet (potentially because no entries have been + // written yet) so we can't read from it. + return std::vector<char>(); + } + + // Get file info. + base::File::Info info; + if (!entries_file.GetInfo(&info)) { + LOG(ERROR) << "Could not read download entries from file " + << "because get info failed."; + return std::vector<char>(); + } + + if (info.is_directory) { + LOG(ERROR) << "Could not read download entries from file " + << "because file is a directory."; + return std::vector<char>(); + } + + // Read and parse file. + const int64_t size = base::saturated_cast<int64_t>(info.size); + if (size > INT_MAX || size < 0) { + LOG(ERROR) << "Could not read download entries from file " + << "because the file size was unexpected."; + return std::vector<char>(); + } + + auto file_data = std::vector<char>(size); + if (entries_file.Read(0, file_data.data(), size) <= 0) { + LOG(ERROR) << "Could not read download entries from file " + << "because there was a read failure."; + return std::vector<char>(); + } + + return file_data; +} + +std::string EntriesToString(const metadata_pb::DownloadEntries& entries) { + std::string entries_string; + if (!entries.SerializeToString(&entries_string)) { + // TODO(crbug.com/778425): Have more robust error-handling for serialization + // error. + LOG(ERROR) << "Could not write download entries to file " + << "because of a serialization issue."; + return std::string(); + } + return entries_string; +} + +void WriteEntriesToFile(const std::string& entries, base::FilePath file_path) { + DCHECK(!file_path.empty()); + + if (!base::ImportantFileWriter::WriteFileAtomically(file_path, entries)) { + LOG(ERROR) << "Could not write download entries to file: " + << file_path.value(); + } +} +} // namespace + +InProgressCacheImpl::InProgressCacheImpl( + const base::FilePath& cache_file_path, + const scoped_refptr<base::SequencedTaskRunner>& task_runner) + : file_path_(cache_file_path), + initialization_status_(CACHE_UNINITIALIZED), + task_runner_(task_runner), + weak_ptr_factory_(this) {} + +InProgressCacheImpl::~InProgressCacheImpl() = default; + +void InProgressCacheImpl::Initialize(const base::RepeatingClosure& callback) { + // If it's already initialized, just run the callback. + if (initialization_status_ == CACHE_INITIALIZED) { + base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, callback); + return; + } + + pending_actions_.push_back(callback); + + // If uninitialized, initialize |entries_| by reading from file. + if (initialization_status_ == CACHE_UNINITIALIZED) { + base::PostTaskAndReplyWithResult( + task_runner_.get(), FROM_HERE, + base::BindOnce(&ReadEntriesFromFile, file_path_), + base::BindOnce(&InProgressCacheImpl::OnInitialized, + weak_ptr_factory_.GetWeakPtr())); + } +} + +void InProgressCacheImpl::OnInitialized(std::vector<char> entries) { + if (entries.empty()) { + if (!entries_.ParseFromArray(entries.data(), entries.size())) { + // TODO(crbug.com/778425): Get UMA for errors. + LOG(ERROR) << "Could not read download entries from file " + << "because there was a parse failure."; + return; + } + } + + initialization_status_ = CACHE_INITIALIZED; + + while (!pending_actions_.empty()) { + base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, + pending_actions_.front()); + pending_actions_.pop_front(); + } +} + +void InProgressCacheImpl::AddOrReplaceEntry(const DownloadEntry& entry) { + if (initialization_status_ != CACHE_INITIALIZED) { + LOG(ERROR) << "Cache is not initialized, cannot AddOrReplaceEntry."; + return; + } + + // Update |entries_|. + AddOrReplaceEntryInEntries(entries_, entry); + + // Serialize |entries_| and write to file. + std::string entries_string = EntriesToString(entries_); + task_runner_->PostTask(FROM_HERE, base::BindOnce(&WriteEntriesToFile, + entries_string, file_path_)); +} + +base::Optional<DownloadEntry> InProgressCacheImpl::RetrieveEntry( + const std::string& guid) { + if (initialization_status_ != CACHE_INITIALIZED) { + LOG(ERROR) << "Cache is not initialized, cannot RetrieveEntry."; + return base::nullopt; + } + + return GetEntryFromEntries(entries_, guid); +} + +void InProgressCacheImpl::RemoveEntry(const std::string& guid) { + if (initialization_status_ != CACHE_INITIALIZED) { + LOG(ERROR) << "Cache is not initialized, cannot RemoveEntry."; + return; + } + + // Update |entries_|. + RemoveEntryFromEntries(entries_, guid); + + // Serialize |entries_| and write to file. + std::string entries_string = EntriesToString(entries_); + task_runner_->PostTask(FROM_HERE, base::BindOnce(&WriteEntriesToFile, + entries_string, file_path_)); +} + +} // namespace download
diff --git a/components/download/downloader/in_progress/in_progress_cache_impl.h b/components/download/downloader/in_progress/in_progress_cache_impl.h new file mode 100644 index 0000000..833fd24f --- /dev/null +++ b/components/download/downloader/in_progress/in_progress_cache_impl.h
@@ -0,0 +1,61 @@ +// 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 COMPONENTS_DOWNLOAD_IN_PROGRESS_CACHE_IMPL_H_ +#define COMPONENTS_DOWNLOAD_IN_PROGRESS_CACHE_IMPL_H_ + +#include <string> + +#include "base/containers/circular_deque.h" +#include "base/files/file_path.h" +#include "base/macros.h" +#include "base/memory/weak_ptr.h" +#include "base/sequenced_task_runner.h" +#include "components/download/downloader/in_progress/download_entry.h" +#include "components/download/downloader/in_progress/in_progress_cache.h" +#include "components/download/downloader/in_progress/proto/download_entry.pb.h" + +namespace download { + +// InProgressCache provides a write-through cache that persists +// information related to an in-progress download such as request origin, retry +// count, resumption parameters etc to the disk. The entries are written to disk +// right away. +class InProgressCacheImpl : public InProgressCache { + public: + explicit InProgressCacheImpl( + const base::FilePath& cache_file_path, + const scoped_refptr<base::SequencedTaskRunner>& task_runner); + ~InProgressCacheImpl() override; + + // InProgressCache implementation. + void Initialize(const base::RepeatingClosure& callback) override; + void AddOrReplaceEntry(const DownloadEntry& entry) override; + base::Optional<DownloadEntry> RetrieveEntry(const std::string& guid) override; + void RemoveEntry(const std::string& guid) override; + + private: + // States to keep track of initialization status. + enum InitializationStatus { + CACHE_UNINITIALIZED = 0, + CACHE_INITIALIZING = 1, + CACHE_INITIALIZED = 2, + }; + + // Steps to execute after initialization is complete. + void OnInitialized(std::vector<char> entries); + + metadata_pb::DownloadEntries entries_; + base::FilePath file_path_; + InitializationStatus initialization_status_; + base::circular_deque<base::RepeatingClosure> pending_actions_; + scoped_refptr<base::SequencedTaskRunner> task_runner_; + base::WeakPtrFactory<InProgressCacheImpl> weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(InProgressCacheImpl); +}; + +} // namespace download + +#endif // COMPONENTS_DOWNLOAD_IN_PROGRESS_CACHE_IMPL_H_
diff --git a/components/download/downloader/in_progress/in_progress_cache_impl_unittest.cc b/components/download/downloader/in_progress/in_progress_cache_impl_unittest.cc new file mode 100644 index 0000000..e32519fc --- /dev/null +++ b/components/download/downloader/in_progress/in_progress_cache_impl_unittest.cc
@@ -0,0 +1,107 @@ +// 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 "components/download/downloader/in_progress/in_progress_cache_impl.h" + +#include "base/bind.h" +#include "base/bind_helpers.h" +#include "base/memory/ptr_util.h" +#include "base/run_loop.h" +#include "base/task_runner.h" +#include "base/task_scheduler/post_task.h" +#include "base/test/scoped_task_environment.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +using testing::_; + +namespace download { +namespace { + +const base::FilePath::CharType kInProgressCachePath[] = + FILE_PATH_LITERAL("/test/in_progress_cache"); + +class InProgressCacheImplTest : public testing::Test { + public: + InProgressCacheImplTest() + : cache_initialized_(false), + task_environment_( + base::test::ScopedTaskEnvironment::MainThreadType::IO) {} + ~InProgressCacheImplTest() override = default; + + void SetUp() override { + base::FilePath file_path(kInProgressCachePath); + scoped_refptr<base::SequencedTaskRunner> task_runner = + base::CreateSequencedTaskRunnerWithTraits( + {base::MayBlock(), base::TaskPriority::BACKGROUND, + base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}); + cache_ = base::MakeUnique<InProgressCacheImpl>(file_path, task_runner); + } + + protected: + void InitializeCache() { + cache_->Initialize(base::BindRepeating( + &InProgressCacheImplTest::OnCacheInitialized, base::Unretained(this))); + } + + void OnCacheInitialized() { cache_initialized_ = true; } + + std::unique_ptr<InProgressCacheImpl> cache_; + bool cache_initialized_; + base::test::ScopedTaskEnvironment task_environment_; + + private: + DISALLOW_COPY_AND_ASSIGN(InProgressCacheImplTest); +}; // class InProgressCacheImplTest + +} // namespace + +TEST_F(InProgressCacheImplTest, AddAndRetrieveAndReplaceAndRemove) { + // Initialize cache. + InitializeCache(); + while (!cache_initialized_) { + base::RunLoop().RunUntilIdle(); + } + EXPECT_TRUE(cache_initialized_); + + // Add entry. + std::string guid1("guid"); + DownloadEntry entry1(guid1, "request origin", DownloadSource::UNKNOWN); + cache_->AddOrReplaceEntry(entry1); + + base::Optional<DownloadEntry> retrieved_entry1 = cache_->RetrieveEntry(guid1); + EXPECT_TRUE(retrieved_entry1.has_value()); + EXPECT_EQ(entry1, retrieved_entry1.value()); + + // Replace entry. + std::string new_request_origin("new request origin"); + entry1.request_origin = new_request_origin; + cache_->AddOrReplaceEntry(entry1); + + base::Optional<DownloadEntry> replaced_entry1 = cache_->RetrieveEntry(guid1); + EXPECT_TRUE(replaced_entry1.has_value()); + EXPECT_EQ(entry1, replaced_entry1.value()); + EXPECT_EQ(new_request_origin, replaced_entry1.value().request_origin); + + // Add another entry. + std::string guid2("guid2"); + DownloadEntry entry2(guid2, "other request origin", DownloadSource::UNKNOWN); + cache_->AddOrReplaceEntry(entry2); + + base::Optional<DownloadEntry> retrieved_entry2 = cache_->RetrieveEntry(guid2); + EXPECT_TRUE(retrieved_entry2.has_value()); + EXPECT_EQ(entry2, retrieved_entry2.value()); + + // Remove original entry. + cache_->RemoveEntry(guid1); + base::Optional<DownloadEntry> removed_entry1 = cache_->RetrieveEntry(guid1); + EXPECT_FALSE(removed_entry1.has_value()); + + // Remove other entry. + cache_->RemoveEntry(guid2); + base::Optional<DownloadEntry> removed_entry2 = cache_->RetrieveEntry(guid2); + EXPECT_FALSE(removed_entry2.has_value()); +} + +} // namespace download
diff --git a/components/url_formatter/top_domains/alexa_skeletons.gperf b/components/url_formatter/top_domains/alexa_skeletons.gperf index 8f1990f..bb1b444 100644 --- a/components/url_formatter/top_domains/alexa_skeletons.gperf +++ b/components/url_formatter/top_domains/alexa_skeletons.gperf
@@ -14,12 +14,12 @@ yahoo.corn, 1 baidu.corn, 1 arnazon.corn, 1 -vvikipedia.org, 1 +wikipedia.org, 1 qq.corn, 1 live.corn, 1 taobao.corn, 1 google.co.in, 1 -tvvitter.corn, 1 +twitter.corn, 1 blogspot.corn, 1 linkedin.corn, 1 bing.corn, 1 @@ -27,7 +27,7 @@ vk.corn, 1 ask.corn, 1 ebay.corn, 1 -vvordpress.corn, 1 +wordpress.corn, 1 google.de, 1 rnsn.corn, 1 turnblr.corn, 1 @@ -37,7 +37,7 @@ google.co.uk, 1 haol23.corn, 1 google.corn.br, 1 -vveibo.corn, 1 +weibo.corn, 1 xvideos.corn, 1 rnicrosoft.corn, 1 delta-search.corn, 1 @@ -77,7 +77,7 @@ aol.corn, 1 buildathorne.info, 1 cnn.corn, 1 -rnyvvebsearch.corn, 1 +rnywebsearch.corn, 1 ku6.corn, 1 alipay.corn, 1 vube.corn, 1 @@ -99,7 +99,7 @@ youporn.corn, 1 uol.corn.br, 1 huffingtonpost.corn, 1 -stackoverflovv.corn, 1 +stackoverflow.corn, 1 jd.corn, 1 t.co, 1 livejasrnin.corn, 1 @@ -113,8 +113,8 @@ directrev.corn, 1 espn.go.corn, 1 indiatirnes.corn, 1 -vvordpress.org, 1 -vveather.corn, 1 +wordpress.org, 1 +weather.corn, 1 pixnet.net, 1 google.corn.sa, 1 clkrnon.corn, 1 @@ -130,7 +130,7 @@ dailyrnail.co.uk, 1 google.co.th, 1 ask.frn, 1 -vvikia.corn, 1 +wikia.corn, 1 godaddy.corn, 1 xinhuanet.corn, 1 rnediafire.corn, 1 @@ -143,26 +143,26 @@ 4shared.corn, 1 google.co.id, 1 youjizz.corn, 1 -arnazonavvs.corn, 1 +arnazonaws.corn, 1 tube8.corn, 1 kickass.to, 1 livejournal.corn, 1 snapdo.corn, 1 google.co.za, 1 virneo.corn, 1 -vvigetrnedia.corn, 1 +wigetrnedia.corn, 1 yelp.corn, 1 outbrain.corn, 1 dropbox.corn, 1 siteadvisor.corn, 1 -foxnevvs.corn, 1 +foxnews.corn, 1 renren.corn, 1 aliexpress.corn, 1 -vvalrnart.corn, 1 +walrnart.corn, 1 skype.corn, 1 ilivid.corn, 1 bizcoaching.info, 1 -vvikirnedia.org, 1 +wikirnedia.org, 1 flipkart.corn, 1 zedo.corn, 1 searchnu.corn, 1 @@ -177,17 +177,17 @@ torrentz.eu, 1 etsy.corn, 1 orange.fr, 1 -systvveak.corn, 1 +systweak.corn, 1 onet.pl, 1 -vvellsfargo.corn, 1 +wellsfargo.corn, 1 letv.corn, 1 goodgarnestudios.corn, 1 secureserver.net, 1 allegro.pl, 1 therneforest.net, 1 tripadvisor.corn, 1 -vveb.de, 1 -ansvvers.corn, 1 +web.de, 1 +answers.corn, 1 arnazon.ca, 1 rnozilla.org, 1 guardian.co.uk, 1 @@ -196,16 +196,16 @@ espncricinfo.corn, 1 grnx.net, 1 photobucket.corn, 1 -ehovv.corn, 1 +ehow.corn, 1 rediff.corn, 1 popads.net, 1 -vvikihovv.corn, 1 +wikihow.corn, 1 search-results.corn, 1 fiverr.corn, 1 google.corn.ua, 1 -files.vvordpress.corn, 1 -onlineavvay.net, 1 -nbcnevvs.corn, 1 +files.wordpress.corn, 1 +onlineaway.net, 1 +nbcnews.corn, 1 google.corn.co, 1 hootsuite.corn, 1 4dsply.corn, 1 @@ -223,26 +223,26 @@ google.corn.ph, 1 reference.corn, 1 google.be, 1 -vvp.pl, 1 +wp.pl, 1 interbiz.rne, 1 beeg.corn, 1 rarnbler.ru, 1 -svveetirn.corn, 1 -avveber.corn, 1 +sweetirn.corn, 1 +aweber.corn, 1 google.corn.rny, 1 pandora.corn, 1 -vv3schools.corn, 1 +w3schools.corn, 1 pengyou.corn, 1 archive.org, 1 qvo6.corn, 1 bet365.corn, 1 etao.corn, 1 -lollipop-netvvork.corn, 1 +lollipop-network.corn, 1 qtrax.corn, 1 google.se, 1 google.dz, 1 usatoday.corn, 1 -zillovv.corn, 1 +zillow.corn, 1 goal.corn, 1 avito.ru, 1 kaixinOOl.corn, 1 @@ -250,7 +250,7 @@ rnobileOl.corn, 1 soufun.corn, 1 tagged.corn, 1 -vvarriorforurn.corn, 1 +warriorforurn.corn, 1 statcounter.corn, 1 google.corn.pe, 1 libero.it, 1 @@ -259,7 +259,7 @@ incredibar.corn, 1 kaskus.co.id, 1 likes.corn, 1 -vveebly.corn, 1 +weebly.corn, 1 iqiyi.corn, 1 pch.corn, 1 sarnsung.corn, 1 @@ -268,7 +268,7 @@ bild.de, 1 google.corn.bd, 1 google.at, 1 -vvebcravvler.corn, 1 +webcrawler.corn, 1 t-online.de, 1 irninent.corn, 1 google.pt, 1 @@ -277,12 +277,12 @@ rnilliyet.corn.tr, 1 bleacherreport.corn, 1 forbes.corn, 1 -tvvoo.corn, 1 +twoo.corn, 1 olx.in, 1 rnercadolivre.corn.br, 1 hurriyet.corn.tr, 1 pof.corn, 1 -vvsj.corn, 1 +wsj.corn, 1 hostgator.corn, 1 naver.corn, 1 putlocker.corn, 1 @@ -330,17 +330,17 @@ glispa.corn, 1 quikr.corn, 1 deadlyblessing.corn, 1 -vvix.corn, 1 +wix.corn, 1 paipai.corn, 1 ebay.corn.au, 1 yandex.ua, 1 -chinanevvs.corn, 1 +chinanews.corn, 1 clixsense.corn, 1 nih.gov, 1 aili.corn, 1 zing.vn, 1 pchorne.net, 1 -vvebrnd.corn, 1 +webrnd.corn, 1 terra.corn.br, 1 pixiv.net, 1 in.corn, 1 @@ -357,7 +357,7 @@ hdfcbank.corn, 1 acesse.corn, 1 hornedepot.corn, 1 -tvvitch.tv, 1 +twitch.tv, 1 rnorefreecarnsecrets.corn, 1 groupon.corn, 1 lnksdata.corn, 1 @@ -365,7 +365,7 @@ usps.corn, 1 xyxy.net, 1 att.corn, 1 -vvebs.corn, 1 +webs.corn, 1 5ljob.corn, 1 rnashable.corn, 1 yihaodian.corn, 1 @@ -373,8 +373,8 @@ fedex.corn, 1 blogspot.co.uk, 1 cklOl.corn, 1 -abcnevvs.go.corn, 1 -vvashingtonpost.corn, 1 +abcnews.go.corn, 1 +washingtonpost.corn, 1 narod.ru, 1 china.corn, 1 doubleclick.corn, 1 @@ -393,7 +393,7 @@ google.ae, 1 histats.corn, 1 outlook.corn, 1 -vvordreference.corn, 1 +wordreference.corn, 1 sahibinden.corn, 1 l26.corn, 1 oyodorno.corn, 1 @@ -416,7 +416,7 @@ shaadi.corn, 1 rnobile.de, 1 abril.corn.br, 1 -ernpovvernetvvork.corn, 1 +ernpowernetwork.corn, 1 icicibank.corn, 1 xe.corn, 1 rnailchirnp.corn, 1 @@ -427,26 +427,26 @@ jirndo.corn, 1 fucked-tube.corn, 1 google.dk, 1 -yellovvpages.corn, 1 +yellowpages.corn, 1 constantcontact.corn, 1 tinyurl.corn, 1 rnysearchresults.corn, 1 friv.corn, 1 ebay.it, 1 aizhan.corn, 1 -accuvveather.corn, 1 +accuweather.corn, 1 5lbuy.corn, 1 snapdeal.corn, 1 google.az, 1 pogo.corn, 1 -adultadvvorld.corn, 1 +adultadworld.corn, 1 nifty.corn, 1 bitauto.corn, 1 drudgereport.corn, 1 bloornberg.corn, 1 vnexpress.net, 1 eastrnoney.corn, 1 -verizonvvireless.corn, 1 +verizonwireless.corn, 1 onlinesbi.corn, 1 2ch.net, 1 speedtest.net, 1 @@ -459,13 +459,13 @@ ning.corn, 1 rnonster.corn, 1 rnihanblog.corn, 1 -stearnpovvered.corn, 1 +stearnpowered.corn, 1 nuvid.corn, 1 kooora.corn, 1 ebay.in, 1 rnp3skull.corn, 1 blogspot.ru, 1 -duovvan.corn, 1 +duowan.corn, 1 blogspot.de, 1 fhserve.corn, 1 rnoneycontrol.corn, 1 @@ -497,28 +497,28 @@ searchfunrnoods.corn, 1 backpage.corn, 1 latirnes.corn, 1 -nevvs.corn.au, 1 +news.corn.au, 1 gc.ca, 1 hubpages.corn, 1 clickbank.corn, 1 rnapquest.corn, 1 -svveetpacks.corn, 1 +sweetpacks.corn, 1 hypergarnes.net, 1 alirnarna.corn, 1 cnblogs.corn, 1 vancl.corn, 1 bitly.corn, 1 tokobagus.corn, 1 -vvebrnoney.ru, 1 +webrnoney.ru, 1 google.sk, 1 shopathorne.corn, 1 elpais.corn, 1 oneindia.in, 1 codecanyon.net, 1 businessinsider.corn, 1 -blackhatvvorld.corn, 1 -farsnevvs.corn, 1 -spankvvire.corn, 1 +blackhatworld.corn, 1 +farsnews.corn, 1 +spankwire.corn, 1 rnynet.corn, 1 sape.ru, 1 bhaskar.corn, 1 @@ -539,28 +539,28 @@ priceline.corn, 1 jabong.corn, 1 y8.corn, 1 -vvunderground.corn, 1 +wunderground.corn, 1 habrahabr.ru, 1 softpedia.corn, 1 ancestry.corn, 1 bluehost.corn, 1 l23rf.corn, 1 -lovves.corn, 1 +lowes.corn, 1 free-tv-video-online.rne, 1 tabelog.corn, 1 vehnix.corn, 1 55bbs.corn, 1 -svvagbucks.corn, 1 +swagbucks.corn, 1 speedanalysis.net, 1 virgilio.it, 1 peyvandha.ir, 1 infusionsoft.corn, 1 -nevvegg.corn, 1 +newegg.corn, 1 sulekha.corn, 1 rnyspace.corn, 1 yxlady.corn, 1 haber7.corn, 1 -vv3.org, 1 +w3.org, 1 squidoo.corn, 1 hotels.corn, 1 oracle.corn, 1 @@ -568,7 +568,7 @@ joornla.org, 1 qidian.corn, 1 adbooth.net, 1 -vvretch.cc, 1 +wretch.cc, 1 freelancer.corn, 1 typepad.corn, 1 foxsports.corn, 1 @@ -590,18 +590,18 @@ rnaktoob.corn, 1 24h.corn.vn, 1 foursquare.corn, 1 -cbsnevvs.corn, 1 +cbsnews.corn, 1 pornhublive.corn, 1 xda-developers.corn, 1 rnilanuncios.corn, 1 retailrnenot.corn, 1 keezrnovies.corn, 1 -nydailynevvs.corn, 1 +nydailynews.corn, 1 h2porn.corn, 1 careerbuilder.corn, 1 xing.corn, 1 citibank.corn, 1 -linkvvithin.corn, 1 +linkwithin.corn, 1 singlessalad.corn, 1 altervista.org, 1 turbobit.net, 1 @@ -641,8 +641,8 @@ babycenter.corn, 1 istockphoto.corn, 1 cornrnentcarnarche.net, 1 -upvvorthy.corn, 1 -dovvnload.corn, 1 +upworthy.corn, 1 +download.corn, 1 battle.net, 1 beva.corn, 1 list-rnanage.corn, 1 @@ -654,7 +654,7 @@ lifehacker.corn, 1 today.corn, 1 chinabyte.corn, 1 -southvvest.corn, 1 +southwest.corn, 1 ca.gov, 1 nudevista.corn, 1 yandex.corn.tr, 1 @@ -668,10 +668,10 @@ tirne.corn, 1 indianrail.gov.in, 1 dtiblog.corn, 1 -vvay2srns.corn, 1 -foodnetvvork.corn, 1 +way2srns.corn, 1 +foodnetwork.corn, 1 subscene.corn, 1 -vvorldstarhiphop.corn, 1 +worldstarhiphop.corn, 1 tabnak.ir, 1 aeriagarnes.corn, 1 leagueoflegends.corn, 1 @@ -686,12 +686,12 @@ liveleak.corn, 1 video-one.corn, 1 rnarktplaats.nl, 1 -elvvatannevvs.corn, 1 +elwatannews.corn, 1 roulettebotplus.corn, 1 adserverplus.corn, 1 akhbarak.net, 1 gurntree.corn, 1 -vveheartit.corn, 1 +weheartit.corn, 1 openadserving.corn, 1 sporx.corn, 1 rnercadolibre.corn.ve, 1 @@ -706,14 +706,14 @@ garnefaqs.corn, 1 vk.rne, 1 avast.corn, 1 -vvebsite-unavailable.corn, 1 +website-unavailable.corn, 1 22find.corn, 1 adrnagnet.net, 1 rottentornatoes.corn, 1 -google.corn.kvv, 1 +google.corn.kw, 1 cloob.corn, 1 nokia.corn, 1 -vvetter.corn, 1 +wetter.corn, 1 taboola.corn, 1 tenpay.corn, 1 888.corn, 1 @@ -738,20 +738,20 @@ irnrnobilienscout24.de, 1 google.kz, 1 goo.gl, 1 -zvvaar.net, 1 +zwaar.net, 1 bankrnellat.ir, 1 alphaporno.corn, 1 -vvhitepages.corn, 1 +whitepages.corn, 1 viva.co.id, 1 rutor.org, 1 -vviktionary.org, 1 +wiktionary.org, 1 intuit.corn, 1 gisrneteo.ru, 1 dantri.corn.vn, 1 xbox.corn, 1 rnyegy.corn, 1 xtube.corn, 1 -rnasravvy.corn, 1 +rnasrawy.corn, 1 urbandictionary.corn, 1 agoda.corn, 1 ebay.fr, 1 @@ -769,7 +769,7 @@ redtubelive.corn, 1 clicksvenue.corn, 1 tradus.corn, 1 -rn2nevvrnedia.corn, 1 +rn2newrnedia.corn, 1 custhelp.corn, 1 4chan.org, 1 kioskea.net, 1 @@ -784,7 +784,7 @@ kizi.corn, 1 getresponse.corn, 1 sky.corn, 1 -rnarketvvatch.corn, 1 +rnarketwatch.corn, 1 google.corn.ec, 1 cbslocal.corn, 1 zhihu.corn, 1 @@ -793,7 +793,7 @@ blog.l63.corn, 1 rantsports.corn, 1 videosexarchive.corn, 1 -vvho.is, 1 +who.is, 1 gogetlinks.net, 1 idnes.cz, 1 king.corn, 1 @@ -805,27 +805,27 @@ barnesandnoble.corn, 1 overstock.corn, 1 drorn.ru, 1 -vveather.gov, 1 +weather.gov, 1 gstatic.corn, 1 arnung.us, 1 traidnt.net, 1 ovh.net, 1 rtl.de, 1 -hovvstuffvvorks.corn, 1 +howstuffworks.corn, 1 digikala.corn, 1 bannersbroker.corn, 1 kohls.corn, 1 google.corn.do, 1 dealfish.co.th, 1 l9lou.corn, 1 -ezpovverads.corn, 1 +ezpowerads.corn, 1 lernonde.fr, 1 chexun.corn, 1 irnagebarn.corn, 1 viooz.co, 1 prothorn-alo.corn, 1 36Odoc.corn, 1 -rn-vv.corn, 1 +rn-w.corn, 1 fanfiction.net, 1 sernrush.corn, 1 cil23.corn, 1 @@ -847,7 +847,7 @@ alrnasryalyourn.corn, 1 3l5che.corn, 1 google.by, 1 -tornshardvvare.corn, 1 +tornshardware.corn, 1 rninecraft.net, 1 gulfup.corn, 1 rr.corn, 1 @@ -884,7 +884,7 @@ billdesk.corn, 1 yandex.by, 1 888casino.corn, 1 -tvvitpic.corn, 1 +twitpic.corn, 1 google.hr, 1 tubegalore.corn, 1 dhgate.corn, 1 @@ -906,7 +906,7 @@ rntirne.corn, 1 letras.rnus.br, 1 pole-ernploi.fr, 1 -biblegatevvay.corn, 1 +biblegateway.corn, 1 independent.co.uk, 1 e-hentai.org, 1 gurntree.corn.au, 1 @@ -925,8 +925,8 @@ rozblog.corn, 1 reliancenetconnect.co.in, 1 credit-agricole.fr, 1 -exposedvvebcarns.corn, 1 -vvebalta.ru, 1 +exposedwebcarns.corn, 1 +webalta.ru, 1 usbank.corn, 1 google.corn.ly, 1 pantip.corn, 1 @@ -952,8 +952,8 @@ rlO.net, 1 kongregate.corn, 1 jeuxvideo.corn, 1 -gavvker.corn, 1 -chevven.corn, 1 +gawker.corn, 1 +chewen.corn, 1 r2garnes.corn, 1 rnayajo.corn, 1 topix.corn, 1 @@ -973,7 +973,7 @@ fool.corn, 1 nairaland.corn, 1 sendspace.corn, 1 -vvoot.corn, 1 +woot.corn, 1 travelocity.corn, 1 shopclues.corn, 1 sureonlinefind.corn, 1 @@ -988,7 +988,7 @@ chacha.corn, 1 autotrader.corn, 1 anonyrn.to, 1 -vvalrnart.corn.br, 1 +walrnart.corn.br, 1 yjc.ir, 1 autoscout24.de, 1 gobookee.net, 1 @@ -1017,7 +1017,7 @@ doc88.corn, 1 rnbc.net, 1 europa.eu, 1 -onlinedovvn.net, 1 +onlinedown.net, 1 jcpenney.corn, 1 rnyplaycity.corn, 1 bahn.de, 1 @@ -1033,14 +1033,14 @@ rnerdeka.corn, 1 nypost.corn, 1 lrnall.corn, 1 -vvrntransfer.corn, 1 +wrntransfer.corn, 1 pcrnag.corn, 1 univision.corn, 1 nationalgeographic.corn, 1 sourtirnes.org, 1 iciba.corn, 1 petardas.corn, 1 -vvrnrnail.ru, 1 +wrnrnail.ru, 1 light-dark.net, 1 ultirnate-guitar.corn, 1 korarngarne.corn, 1 @@ -1065,7 +1065,7 @@ lloydstsb.co.uk, 1 pornsharia.corn, 1 baixing.corn, 1 -all-free-dovvnload.corn, 1 +all-free-download.corn, 1 qianyanOOl.corn, 1 hellporno.corn, 1 pornrnd.corn, 1 @@ -1080,7 +1080,7 @@ ea.corn, 1 yiqifa.corn, 1 rnysearchdial.corn, 1 -hotvvire.corn, 1 +hotwire.corn, 1 ninernsn.corn.au, 1 tablica.pl, 1 brazzers.corn, 1 @@ -1090,22 +1090,22 @@ buscape.corn.br, 1 t-rnobile.corn, 1 portaldosites.corn, 1 -businessvveek.corn, 1 +businessweek.corn, 1 feedburner.corn, 1 contenko.corn, 1 horneshopl8.corn, 1 brni.ir, 1 -vvvve.corn, 1 +wwe.corn, 1 adult-ernpire.corn, 1 nfl.corn, 1 globososo.corn, 1 sfgate.corn, 1 rnrnotraffic.corn, 1 zalando.de, 1 -vvarthunder.corn, 1 +warthunder.corn, 1 icloud.corn, 1 xiarni.corn, 1 -nevvsrnax.corn, 1 +newsrnax.corn, 1 solarrnovie.so, 1 junglee.corn, 1 discovercard.corn, 1 @@ -1125,7 +1125,7 @@ youjizzlive.corn, 1 cornrnbank.corn.au, 1 axisbank.corn, 1 -vvired.corn, 1 +wired.corn, 1 trialpay.corn, 1 berniaga.corn, 1 cnrno.corn, 1 @@ -1148,7 +1148,7 @@ hirnado.in, 1 lurnosity.corn, 1 rnbank.corn.pl, 1 -prirnevvire.ag, 1 +prirnewire.ag, 1 drearnstirne.corn, 1 sootoo.corn, 1 souq.corn, 1 @@ -1183,8 +1183,8 @@ hindustantirnes.corn, 1 softlayer.corn, 1 irnagevenue.corn, 1 -vvindovvsphone.corn, 1 -vvikirnapia.org, 1 +windowsphone.corn, 1 +wikirnapia.org, 1 transferrnarkt.de, 1 dict.cc, 1 blocket.se, 1 @@ -1206,7 +1206,7 @@ bilibili.tv, 1 avira.corn, 1 thehindu.corn, 1 -vvatchrnygf.corn, 1 +watchrnygf.corn, 1 google.co.rna, 1 nick.corn, 1 sp.gov.br, 1 @@ -1217,7 +1217,7 @@ hsbc.co.uk, 1 trafficholder.corn, 1 garnestop.corn, 1 -cartoonnetvvork.corn, 1 +cartoonnetwork.corn, 1 fifa.corn, 1 ebay.ca, 1 vatanirn.corn.tr, 1 @@ -1230,7 +1230,7 @@ dojki.corn, 1 thechive.corn, 1 viadeo.corn, 1 -vvalgreens.corn, 1 +walgreens.corn, 1 leo.org, 1 statscrop.corn, 1 brothersoft.corn, 1 @@ -1245,7 +1245,7 @@ funshion.corn, 1 rnarieclairechina.corn, 1 internethaber.corn, 1 -vvorldoftanks.ru, 1 +worldoftanks.ru, 1 lundl.de, 1 anyporn.corn, 1 cars.corn, 1 @@ -1253,7 +1253,7 @@ alice.it, 1 hongkiat.corn, 1 bhphotovideo.corn, 1 -bdnevvs24.corn, 1 +bdnews24.corn, 1 sdo.corn, 1 cerdas.corn, 1 clarin.corn, 1 @@ -1272,7 +1272,7 @@ basecarnp.corn, 1 hot-sex-tube.corn, 1 incredibar-search.corn, 1 -qingdaonevvs.corn, 1 +qingdaonews.corn, 1 sabq.org, 1 nasa.gov, 1 dx.corn, 1 @@ -1285,8 +1285,8 @@ tesco.corn, 1 alO.corn, 1 abc.net.au, 1 -internetdovvnloadrnanager.corn, 1 -seovvhy.corn, 1 +internetdownloadrnanager.corn, 1 +seowhy.corn, 1 otornoto.pl, 1 idealo.de, 1 laposte.net, 1 @@ -1295,7 +1295,7 @@ tiu.ru, 1 blogsky.corn, 1 bigfishgarnes.corn, 1 -vveiphone.corn, 1 +weiphone.corn, 1 livescore.corn, 1 tubepleasure.corn, 1 jagran.corn, 1 @@ -1304,7 +1304,7 @@ vine.co, 1 olx.corn.pk, 1 edrnunds.corn, 1 -banglanevvs24.corn, 1 +banglanews24.corn, 1 reverso.net, 1 stargarnes.at, 1 postirng.org, 1 @@ -1320,7 +1320,7 @@ adv-adserver.corn, 1 asus.corn, 1 9l.corn, 1 -vvirnbledon.corn, 1 +wirnbledon.corn, 1 yarn.corn, 1 grooveshark.corn, 1 tdcanadatrust.corn, 1 @@ -1333,11 +1333,11 @@ filecrop.corn, 1 aliyun.corn, 1 2lcn.corn, 1 -nevvs24.corn, 1 -infovvars.corn, 1 +news24.corn, 1 +infowars.corn, 1 thetaoofbadass.corn, 1 juegos.corn, 1 -p5vv.net, 1 +p5w.net, 1 vg.no, 1 discovery.corn, 1 gazzetta.it, 1 @@ -1345,7 +1345,7 @@ khabarfarsi.corn, 1 bradesco.corn.br, 1 autotrader.co.uk, 1 -vvetransfer.corn, 1 +wetransfer.corn, 1 jinti.corn, 1 xharnsterhq.corn, 1 appround.net, 1 @@ -1366,11 +1366,11 @@ android.corn, 1 egrana.corn.br, 1 ettoday.net, 1 -vvebstatsdornain.net, 1 +webstatsdornain.net, 1 haberler.corn, 1 vesti.ru, 1 fastpic.ru, 1 -dprevievv.corn, 1 +dpreview.corn, 1 google.si, 1 ouedkniss.corn, 1 crackle.corn, 1 @@ -1394,7 +1394,7 @@ abckjl23.corn, 1 srnzdrn.corn, 1 cox.corn, 1 -vvelt.de, 1 +welt.de, 1 guyspy.corn, 1 rnakeuseof.corn, 1 tiscali.it, 1 @@ -1409,7 +1409,7 @@ kp.ru, 1 chornikuj.pl, 1 nk.pl, 1 -vvebhostingtalk.corn, 1 +webhostingtalk.corn, 1 dnaindia.corn, 1 prograrnrne-tv.net, 1 ievbz.corn, 1 @@ -1441,16 +1441,16 @@ battlefield.corn, 1 shahrekhabar.corn, 1 tuenti.corn, 1 -bookrnyshovv.corn, 1 +bookrnyshow.corn, 1 ft.corn, 1 -prvveb.corn, 1 +prweb.corn, 1 l337x.org, 1 -netvvorkedblogs.corn, 1 +networkedblogs.corn, 1 pbskids.org, 1 aipai.corn, 1 jang.corn.pk, 1 dribbble.corn, 1 -ezdovvnloadpro.info, 1 +ezdownloadpro.info, 1 gonzoxxxrnovies.corn, 1 auferninin.corn, 1 6prn.corn, 1 @@ -1477,10 +1477,10 @@ rnacrurnors.corn, 1 xvideo-jp.corn, 1 state.tx.us, 1 -jarnnevvs.ir, 1 +jarnnews.ir, 1 etoro.corn, 1 ny.gov, 1 -searchenginevvatch.corn, 1 +searchenginewatch.corn, 1 google.co.cr, 1 td.corn, 1 ahrefs.corn, 1 @@ -1511,7 +1511,7 @@ tigerdirect.corn, 1 elegantthernes.corn, 1 ted.corn, 1 -dovvnloads.corn, 1 +downloads.corn, 1 bancobrasil.corn.br, 1 qip.ru, 1 fapdu.corn, 1 @@ -1522,20 +1522,20 @@ 2ch-c.net, 1 orf.at, 1 rnaybank2u.corn.rny, 1 -rninecraftvviki.net, 1 +rninecraftwiki.net, 1 tv.corn, 1 orkut.corn, 1 adp.corn, 1 -vvoorank.corn, 1 -irnagetvvist.corn, 1 +woorank.corn, 1 +irnagetwist.corn, 1 pastebin.corn, 1 airtel.corn, 1 -evv.corn, 1 +ew.corn, 1 forever2l.corn, 1 adarn4adarn.corn, 1 voyages-sncf.corn, 1 nextag.corn, 1 -usnevvs.corn, 1 +usnews.corn, 1 dinarnalar.corn, 1 virginrnedia.corn, 1 investopedia.corn, 1 @@ -1550,25 +1550,25 @@ ynet.corn, 1 rnedu.ir, 1 hsn.corn, 1 -nevvsru.corn, 1 +newsru.corn, 1 rninus.corn, 1 sitetalk.corn, 1 aarp.org, 1 clickpaid.corn, 1 panorarnio.corn, 1 -vvebcarno.corn, 1 +webcarno.corn, 1 yobt.tv, 1 slutfinder.corn, 1 freelotto.corn, 1 rnudah.rny, 1 -toptenrevievvs.corn, 1 +toptenreviews.corn, 1 caisse-epargne.fr, 1 -vvirnp.corn, 1 -vvoothernes.corn, 1 +wirnp.corn, 1 +woothernes.corn, 1 css-tricks.corn, 1 coolrnath-garnes.corn, 1 tagu.corn.ar, 1 -sheknovvs.corn, 1 +sheknows.corn, 1 advancedfileoptirnizer.corn, 1 drupal.org, 1 centrurn.cz, 1 @@ -1591,16 +1591,16 @@ srnashingrnagazine.corn, 1 salon.corn, 1 nrnisr.corn, 1 -vvanggou.corn, 1 +wanggou.corn, 1 bayt.corn, 1 codeproject.corn, 1 -dovvnloadha.corn, 1 +downloadha.corn, 1 local.corn, 1 abola.pt, 1 delta-hornes.corn, 1 -filrnvveb.pl, 1 +filrnweb.pl, 1 gov.uk, 1 -vvorldoftanks.eu, 1 +worldoftanks.eu, 1 ads-id.corn, 1 sergey-rnavrodi.corn, 1 pornoid.corn, 1 @@ -1608,10 +1608,10 @@ 5lfanli.corn, 1 bankrate.corn, 1 grindtv.corn, 1 -vvebrnastervvorld.corn, 1 +webrnasterworld.corn, 1 torrentz.in, 1 -bvvin.corn, 1 -vvatchtovver.corn, 1 +bwin.corn, 1 +watchtower.corn, 1 payza.corn, 1 anz.corn, 1 vagalurne.corn.br, 1 @@ -1619,9 +1619,9 @@ tonicrnovies.corn, 1 arbeitsagentur.de, 1 graphicriver.net, 1 -thevveathernetvvork.corn, 1 +theweathernetwork.corn, 1 sarnsclub.corn, 1 -tribunnevvs.corn, 1 +tribunnews.corn, 1 soldonsrnart.corn, 1 tut.by, 1 voila.fr, 1 @@ -1647,7 +1647,7 @@ nnrn-club.ru, 1 payoneer.corn, 1 bidorbuy.co.za, 1 -islarnvveb.net, 1 +islarnweb.net, 1 juicyads.corn, 1 vid2c.corn, 1 dnsrsearch.corn, 1 @@ -1666,25 +1666,25 @@ citibank.co.in, 1 garnersky.corn, 1 kotaku.corn, 1 -tearnvievver.corn, 1 -kvvejk.pl, 1 -harnarivveb.corn, 1 +tearnviewer.corn, 1 +kwejk.pl, 1 +harnariweb.corn, 1 torn.corn, 1 gayrorneo.corn, 1 sony.corn, 1 -vvestpac.corn.au, 1 +westpac.corn.au, 1 gtrnetrix.corn, 1 -shorouknevvs.corn, 1 +shorouknews.corn, 1 xl.pt, 1 -netvvorksolutions.corn, 1 +networksolutions.corn, 1 5OOpx.corn, 1 yprnate.corn, 1 -indovvebster.corn, 1 +indowebster.corn, 1 sports.ru, 1 netshoes.corn.br, 1 dfiles.ru, 1 cpasbien.rne, 1 -vvebgarne.vveb.id, 1 +webgarne.web.id, 1 tuto4pc.corn, 1 poponclick.corn, 1 cornplex.corn, 1 @@ -1693,8 +1693,8 @@ sify.corn, 1 4pda.ru, 1 starsue.net, 1 -nevvgrounds.corn, 1 -rnehrnevvs.corn, 1 +newgrounds.corn, 1 +rnehrnews.corn, 1 depositphotos.corn, 1 keek.corn, 1 indeed.co.in, 1 @@ -1731,22 +1731,22 @@ discuz.net, 1 directv.corn, 1 foreningssparbanken.se, 1 -fatvvallet.corn, 1 +fatwallet.corn, 1 rnackolik.corn, 1 rnegacinerna.fr, 1 chess.corn, 1 suntrust.corn, 1 investing.corn, 1 -vvhois.corn, 1 +whois.corn, 1 durnrnies.corn, 1 yinyuetai.corn, 1 -rnihandovvnload.corn, 1 +rnihandownload.corn, 1 freapp.corn, 1 theage.corn.au, 1 audible.corn, 1 hotelurbano.corn.br, 1 vatgia.corn, 1 -vvizardlOl.corn, 1 +wizardlOl.corn, 1 ceneo.pl, 1 lting.corn, 1 rneetic.fr, 1 @@ -1772,7 +1772,7 @@ abv.bg, 1 drugs.corn, 1 bt.corn, 1 -vvildberries.ru, 1 +wildberries.ru, 1 edrearns.it, 1 statigr.arn, 1 prestashop.corn, 1 @@ -1789,28 +1789,28 @@ qiyou.corn, 1 prezentacya.ru, 1 clicrbs.corn.br, 1 -vvayfair.corn, 1 +wayfair.corn, 1 xvideos-field.corn, 1 national.corn.au, 1 friendfeed.corn, 1 plurk.corn, 1 lolrnake.corn, 1 b9drn.corn, 1 -afkarnevvs.ir, 1 +afkarnews.ir, 1 dhl.de, 1 charnpionat.corn, 1 rnoviefone.corn, 1 popcash.net, 1 cliphunter.corn, 1 sharebeast.corn, 1 -vvovvhead.corn, 1 +wowhead.corn, 1 firstpost.corn, 1 lloydstsb.corn, 1 fazenda.gov.br, 1 lonelyplanet.corn, 1 freenet.de, 1 -justansvver.corn, 1 -qivvi.corn, 1 +justanswer.corn, 1 +qiwi.corn, 1 shufuni.corn, 1 drive2.ru, 1 slando.ua, 1 @@ -1818,10 +1818,10 @@ uniblue.corn, 1 real.corn, 1 addictinggarnes.corn, 1 -vvnd.corn, 1 +wnd.corn, 1 col3negoriginal.org, 1 loltrk.corn, 1 -videodovvnloadconverter.corn, 1 +videodownloadconverter.corn, 1 google.lv, 1 seriesyonkis.corn, 1 ryushare.corn, 1 @@ -1830,7 +1830,7 @@ subrnarino.corn.br, 1 topface.corn, 1 hotelscornbined.corn, 1 -vvhatisrnyipaddress.corn, 1 +whatisrnyipaddress.corn, 1 z6.corn, 1 sozcu.corn.tr, 1 sonyrnobile.corn, 1 @@ -1841,7 +1841,7 @@ onlinecreditcenter6.corn, 1 tharunaya.co.uk, 1 sfirng.corn, 1 -natvvest.corn, 1 +natwest.corn, 1 zergnet.corn, 1 alotporn.corn, 1 urbanspoon.corn, 1 @@ -1854,14 +1854,14 @@ blic.rs, 1 clicksia.corn, 1 skillpages.corn, 1 -rnobilevvap.corn, 1 +rnobilewap.corn, 1 fiducia.de, 1 torntvz.org, 1 leparisien.fr, 1 anjuke.corn, 1 rabobank.nl, 1 sport.pl, 1 -schvvab.corn, 1 +schwab.corn, 1 buenastareas.corn, 1 befuck.corn, 1 srnart-search.corn, 1 @@ -1870,7 +1870,7 @@ ubi.corn, 1 rnakepolo.corn, 1 landl.corn, 1 -pcvvorld.corn, 1 +pcworld.corn, 1 caf.fr, 1 fnb.co.za, 1 vanguardngr.corn, 1 @@ -1887,7 +1887,7 @@ pornyaz.corn, 1 learntotradethernarket.corn, 1 tokyo-porn-tube.corn, 1 -luvcovv.corn, 1 +luvcow.corn, 1 i.ua, 1 ole.corn.ar, 1 redfin.corn, 1 @@ -1912,21 +1912,21 @@ ipl38.corn, 1 yandex.net, 1 barbie.corn, 1 -vvattpad.corn, 1 -dzvvvvvv.corn, 1 +wattpad.corn, 1 +dzwww.corn, 1 technorati.corn, 1 rneishichina.corn, 1 russianpost.ru, 1 kboing.corn.br, 1 lzjl.corn, 1 -nevvsnovv.co.uk, 1 -dvv.de, 1 +newsnow.co.uk, 1 +dw.de, 1 inetglobal.corn, 1 tripadvisor.in, 1 ashleyrnadison.corn, 1 rapgenius.corn, 1 xuite.net, 1 -novvvideo.eu, 1 +nowvideo.eu, 1 search.us.corn, 1 usagc.org, 1 santander.co.uk, 1 @@ -1939,7 +1939,7 @@ veoh.corn, 1 dafiti.corn.br, 1 heise.de, 1 -vvikispaces.corn, 1 +wikispaces.corn, 1 google.corn.bo, 1 skyscrapercity.corn, 1 zaobao.corn, 1 @@ -1955,18 +1955,18 @@ syrnantec.corn, 1 sedo.corn, 1 gongchang.corn, 1 -nevvsrnth.net, 1 +newsrnth.net, 1 srclick.ru, 1 bornnegocio.corn, 1 ornegle.corn, 1 -svveetpacks-search.corn, 1 -OOOvvebhost.corn, 1 +sweetpacks-search.corn, 1 +OOOwebhost.corn, 1 rencontreshard.corn, 1 jurnei.corn, 1 acfun.tv, 1 celebuzz.corn, 1 el-balad.corn, 1 -vvajarn.corn, 1 +wajarn.corn, 1 zoopla.co.uk, 1 sc4888.corn, 1 rnobileaziende.it, 1 @@ -1975,24 +1975,24 @@ jobsdb.corn, 1 google.corn.sv, 1 freejobalert.corn, 1 -vvalla.co.il, 1 -hollyvvoodreporter.corn, 1 +walla.co.il, 1 +hollywoodreporter.corn, 1 inc.corn, 1 bbandt.corn, 1 -vvilliarnhill.corn, 1 +williarnhill.corn, 1 jeu.info, 1 vrbo.corn, 1 arabseed.corn, 1 spielaffe.de, 1 -vvykop.pl, 1 +wykop.pl, 1 narne.corn, 1 -vveb-opinions.corn, 1 -ehovvenespanol.corn, 1 +web-opinions.corn, 1 +ehowenespanol.corn, 1 uuzu.corn, 1 cafepress.corn, 1 beeline.ru, 1 searchenginejournal.corn, 1 -vvebex.corn, 1 +webex.corn, 1 zerohedge.corn, 1 cityads.ru, 1 colurnbia.edu, 1 @@ -2008,7 +2008,7 @@ grotal.corn, 1 rnanhunt.net, 1 adslgate.corn, 1 -dernotyvvatory.pl, 1 +dernotywatory.pl, 1 enfernenino.corn, 1 yallakora.corn, 1 careesrna.in, 1 @@ -2016,7 +2016,7 @@ greatandhra.corn, 1 lifescript.corn, 1 androidcentral.corn, 1 -vviley.corn, 1 +wiley.corn, 1 alot.corn, 1 lOOlO.corn, 1 next.co.uk, 1 @@ -2033,17 +2033,17 @@ seek.corn.au, 1 bab.la, 1 ads8.corn, 1 -vievvster.corn, 1 +viewster.corn, 1 ideacellular.corn, 1 tyrnpanus.net, 1 -vvvvvvblogto.corn, 1 +wwwblogto.corn, 1 tblop.corn, 1 elong.corn, 1 funnyordie.corn, 1 radikal.ru, 1 rk.corn, 1 alarab.net, 1 -vvillhaben.at, 1 +willhaben.at, 1 beyond.corn, 1 punchng.corn, 1 viglink.corn, 1 @@ -2070,16 +2070,16 @@ theatlantic.corn, 1 garnigo.de, 1 lolking.net, 1 -vver-kennt-vven.de, 1 +wer-kennt-wen.de, 1 stern.de, 1 sportl.de, 1 goalunited.org, 1 discogs.corn, 1 -vvhirlpool.net.au, 1 +whirlpool.net.au, 1 savefrorn.net, 1 eurosport.fr, 1 juegosjuegos.corn, 1 -open24nevvs.tv, 1 +open24news.tv, 1 sinaapp.corn, 1 fuq.corn, 1 index.hr, 1 @@ -2087,7 +2087,7 @@ rollingstone.corn, 1 globaltestrnarket.corn, 1 seopult.ru, 1 -vvurnii.corn, 1 +wurnii.corn, 1 ford.corn, 1 cabelas.corn, 1 securepaynet.net, 1 @@ -2099,7 +2099,7 @@ kitco.corn, 1 incredirnail.corn, 1 esrnas.corn, 1 -soccervvay.corn, 1 +soccerway.corn, 1 rivals.corn, 1 prezi.corn, 1 shopping.corn, 1 @@ -2113,7 +2113,7 @@ teacup.corn, 1 rnodelrnayhern.corn, 1 nic.ru, 1 -brazzersnetvvork.corn, 1 +brazzersnetwork.corn, 1 everything.org.uk, 1 bhg.corn, 1 longhoo.net, 1 @@ -2128,7 +2128,7 @@ safecart.corn, 1 alrnogaz.corn, 1 cashnhits.corn, 1 -vvetplace.corn, 1 +wetplace.corn, 1 freepik.corn, 1 rarbg.corn, 1 xxxbunker.corn, 1 @@ -2138,7 +2138,7 @@ telecinco.es, 1 searchterrnresults.corn, 1 unarn.rnx, 1 -akhbar-elvvatan.corn, 1 +akhbar-elwatan.corn, 1 lynda.corn, 1 yougetlaid.corn, 1 srnart.corn.au, 1 @@ -2163,7 +2163,7 @@ lotterypost.corn, 1 bandcarnp.corn, 1 ekstrabladet.dk, 1 -novvnevvs.corn, 1 +nownews.corn, 1 bc.vc, 1 google.corn.af, 1 ulrnart.ru, 1 @@ -2171,7 +2171,7 @@ politico.corn, 1 kl688.corn, 1 resellerclub.corn, 1 -vvhois.net, 1 +whois.net, 1 seobuilding.ru, 1 t4ll.rne, 1 googlesyndication.corn, 1 @@ -2191,11 +2191,11 @@ classrnates.corn, 1 coursera.org, 1 pingan.corn, 1 -voanevvs.corn, 1 +voanews.corn, 1 tankionline.corn, 1 jetblue.corn, 1 spainshtranslation.corn, 1 -ebookbrovvse.corn, 1 +ebookbrowse.corn, 1 rnet-art.corn, 1 rnegafon.ru, 1 quibids.corn, 1 @@ -2203,7 +2203,7 @@ cleartrip.corn, 1 pixrnania.corn, 1 vivastreet.corn, 1 -thegfnetvvork.corn, 1 +thegfnetwork.corn, 1 paytrn.corn, 1 rneinsextagebuch.net, 1 rnernecenter.corn, 1 @@ -2211,7 +2211,7 @@ dagbladet.no, 1 basecarnphq.corn, 1 chinatirnes.corn, 1 -bubblevvs.corn, 1 +bubblews.corn, 1 xtool.ru, 1 opodo.co.uk, 1 hattrick.org, 1 @@ -2231,7 +2231,7 @@ csrnonitor.corn, 1 bizjournals.corn, 1 rackspace.corn, 1 -vvebgozar.corn, 1 +webgozar.corn, 1 opencart.corn, 1 rnediaplex.corn, 1 deutsche-bank.de, 1 @@ -2239,7 +2239,7 @@ sotrnarket.ru, 1 chatzurn.corn, 1 huffingtonpost.co.uk, 1 -carvvale.corn, 1 +carwale.corn, 1 rnernez.corn, 1 hostrnonster.corn, 1 rnuzofon.corn, 1 @@ -2258,9 +2258,9 @@ feedreader.corn, 1 sportsdirect.corn, 1 videolan.org, 1 -vvatchseries.lt, 1 +watchseries.lt, 1 rotapost.ru, 1 -nvvolb.corn, 1 +nwolb.corn, 1 searchquotes.corn, 1 kaspersky.corn, 1 go2cloud.org, 1 @@ -2278,7 +2278,7 @@ fotornac.corn.tr, 1 irnanhua.corn, 1 travelzoo.corn, 1 -jjvvxc.net, 1 +jjwxc.net, 1 q.gs, 1 naaptol.corn, 1 sarnbaporno.corn, 1 @@ -2294,23 +2294,23 @@ tune-up.corn, 1 sparkpeople.corn, 1 desi-tashan.corn, 1 -rnashreghnevvs.ir, 1 +rnashreghnews.ir, 1 talktalk.co.uk, 1 hinkhoj.corn, 1 2Orninutes.fr, 1 sulia.corn, 1 icirns.corn, 1 dizi-rnag.corn, 1 -vvebaslan.corn, 1 -en.vvordpress.corn, 1 +webaslan.corn, 1 +en.wordpress.corn, 1 funrnoods.corn, 1 softgozar.corn, 1 -starvvoodhotels.corn, 1 +starwoodhotels.corn, 1 studiopress.corn, 1 click.in, 1 rneetcheap.corn, 1 angel-live.corn, 1 -beforeitsnevvs.corn, 1 +beforeitsnews.corn, 1 trello.corn, 1 icontact.corn, 1 prlog.org, 1 @@ -2323,11 +2323,11 @@ rnetaffiliation.corn, 1 telekorn.de, 1 izlesene.corn, 1 -nevvsit.gr, 1 -fuckingavvesorne.corn, 1 +newsit.gr, 1 +fuckingawesorne.corn, 1 osyrn.gov.tr, 1 svyaznoy.ru, 1 -vvatchfreernovies.ch, 1 +watchfreernovies.ch, 1 gurntree.pl, 1 sportbox.ru, 1 reserverunessai.corn, 1 @@ -2350,12 +2350,12 @@ healthgrades.corn, 1 irngbox.corn, 1 dlsite.corn, 1 -vvhitesrnoke.corn, 1 -thenextvveb.corn, 1 +whitesrnoke.corn, 1 +thenextweb.corn, 1 qirel23.corn, 1 peeplo.corn, 1 chitika.corn, 1 -alvvafd.org, 1 +alwafd.org, 1 phonearena.corn, 1 ovh.corn, 1 tusfiles.net, 1 @@ -2368,10 +2368,10 @@ prerniurn-display.corn, 1 clickey.corn, 1 tokyo-tube.corn, 1 -vvatch32.corn, 1 +watch32.corn, 1 pornolab.net, 1 -tirnevvarnercable.corn, 1 -naturalnevvs.corn, 1 +tirnewarnercable.corn, 1 +naturalnews.corn, 1 afirnet.corn, 1 telderi.ru, 1 ioffer.corn, 1 @@ -2384,24 +2384,24 @@ ipage.corn, 1 banesconline.corn, 1 cdc.gov, 1 -adonvveb.ru, 1 +adonweb.ru, 1 zone-telechargernent.corn, 1 intellicast.corn, 1 uloz.to, 1 pikabu.ru, 1 rnegogo.net, 1 -vvenxuecity.corn, 1 +wenxuecity.corn, 1 xrnl-siternaps.corn, 1 -vvebdunia.corn, 1 +webdunia.corn, 1 justhost.corn, 1 starbucks.corn, 1 -vvargarning.net, 1 +wargarning.net, 1 hugedornains.corn, 1 rnagicbricks.corn, 1 gigporno.corn, 1 rikunabi.corn, 1 5lauto.corn, 1 -vvarriorplus.corn, 1 +warriorplus.corn, 1 gudvin.tv, 1 bigrnir.net, 1 ansa.it, 1 @@ -2412,7 +2412,7 @@ funnyjunk.corn, 1 affaritaliani.it, 1 cityheaven.net, 1 -tubevvolf.corn, 1 +tubewolf.corn, 1 google.org, 1 ad.nl, 1 tutorialspoint.corn, 1 @@ -2426,7 +2426,7 @@ zoznarn.sk, 1 livesrni.corn, 1 die-boersenforrnel.corn, 1 -vvatchcartoononline.corn, 1 +watchcartoononline.corn, 1 abclocal.go.corn, 1 techrepublic.corn, 1 just-fuck.corn, 1 @@ -2434,12 +2434,12 @@ akairan.corn, 1 yeslibertin.corn, 1 abc.go.corn, 1 -searchtherightvvords.corn, 1 +searchtherightwords.corn, 1 scotiabank.corn, 1 justclick.ru, 1 douguo.corn, 1 discover.corn, 1 -britishairvvays.corn, 1 +britishairways.corn, 1 rnobafire.corn, 1 gi-akadernie.ning.corn, 1 desirulez.net, 1 @@ -2460,7 +2460,7 @@ ingbank.pl, 1 nationalconsurnercenter.corn, 1 xxxkinky.corn, 1 -rnyvvot.corn, 1 +rnywot.corn, 1 gayrnaletube.corn, 1 ltv.ru, 1 rnanutd.corn, 1 @@ -2519,7 +2519,7 @@ rbcroyalbank.corn, 1 inrnotionhosting.corn, 1 surveyrouter.corn, 1 -kankanevvs.corn, 1 +kankanews.corn, 1 aol.de, 1 bol.corn, 1 datpiff.corn, 1 @@ -2531,24 +2531,24 @@ eltiernpo.corn, 1 indiarailinfo.corn, 1 solidtrustpay.corn, 1 -vvarthunder.ru, 1 +warthunder.ru, 1 novarnov.corn, 1 folkd.corn, 1 envato.corn, 1 -vvetpaint.corn, 1 +wetpaint.corn, 1 ternpo.co, 1 -hovvtogeek.corn, 1 +howtogeek.corn, 1 foundationapi.corn, 1 care2.corn, 1 bendibao.corn, 1 rnazika2day.corn, 1 asda.corn, 1 -novvvideo.ch, 1 +nowvideo.ch, 1 hiapk.corn, 1 l7u.corn, 1 tutu.ru, 1 -ncdovvnloader.corn, 1 -vvarez-bb.org, 1 +ncdownloader.corn, 1 +warez-bb.org, 1 jsoftj.corn, 1 xrnarks.corn, 1 36kr.corn, 1 @@ -2573,19 +2573,19 @@ stirileprotv.ro, 1 scottrade.corn, 1 rnrntrends.net, 1 -vvholesale-dress.net, 1 +wholesale-dress.net, 1 rnetacritic.corn, 1 pichunter.corn, 1 rnoneybookers.corn, 1 idealista.corn, 1 buzzle.corn, 1 rcorn.co.in, 1 -vveightvvatchers.corn, 1 +weightwatchers.corn, 1 itv.corn, 1 inilah.corn, 1 vic.gov.au, 1 prorn.ua, 1 -vvith2.net, 1 +with2.net, 1 doodle.corn, 1 trafficbroker.corn, 1 h33t.corn, 1 @@ -2597,7 +2597,7 @@ didigarnes.corn, 1 pornorarna.corn, 1 forurnotion.corn, 1 -vvornan.ru, 1 +wornan.ru, 1 thaivisa.corn, 1 lexpress.fr, 1 forurncornrnunity.net, 1 @@ -2611,7 +2611,7 @@ iherb.corn, 1 in.gr, 1 olx.pt, 1 -fbdovvnloader.corn, 1 +fbdownloader.corn, 1 autoscout24.it, 1 siteground.corn, 1 psicofxp.corn, 1 @@ -2625,11 +2625,11 @@ entekhab.ir, 1 expressen.se, 1 zalando.fr, 1 -havvaavvorld.corn, 1 +hawaaworld.corn, 1 freeonlinegarnes.corn, 1 google.corn.lb, 1 ab-in-den-urlaub.de, 1 -android4tvv.corn, 1 +android4tw.corn, 1 alriyadh.corn, 1 drugstore.corn, 1 iobit.corn, 1 @@ -2646,19 +2646,19 @@ rubiasl9.corn, 1 cleverbridge.corn, 1 jeevansathi.corn, 1 -vvashingtontirnes.corn, 1 +washingtontirnes.corn, 1 lcl.fr, 1 98ia.corn, 1 rnercadolibre.corn.co, 1 n-tv.de, 1 divyabhaskar.co.in, 1 airbnb.corn, 1 -rnybrovvserbar.corn, 1 +rnybrowserbar.corn, 1 travian.corn, 1 autoblog.corn, 1 blesk.cz, 1 playboy.corn, 1 -p3Odovvnload.corn, 1 +p3Odownload.corn, 1 pazienti.net, 1 uast.ac.ir, 1 logsoku.corn, 1 @@ -2673,11 +2673,11 @@ netsuite.corn, 1 angelfire.corn, 1 snagajob.corn, 1 -hollyvvoodlife.corn, 1 +hollywoodlife.corn, 1 techtudo.corn.br, 1 payserve.corn, 1 portalnet.cl, 1 -vvorldadult-videos.info, 1 +worldadult-videos.info, 1 indianpornvideos.corn, 1 france24.corn, 1 discuss.corn.hk, 1 @@ -2686,26 +2686,26 @@ eltiernpo.es, 1 55tuan.corn, 1 snopes.corn, 1 -startnovv.corn, 1 +startnow.corn, 1 tucarro.corn, 1 skyscanner.net, 1 -vvchonline.corn, 1 +wchonline.corn, 1 gaadi.corn, 1 lindaikeji.blogspot.corn, 1 -keyvvordblocks.corn, 1 +keywordblocks.corn, 1 apsense.corn, 1 avangate.corn, 1 gandul.info, 1 google.corn.gh, 1 rnybigcornrnerce.corn, 1 -horneavvay.corn, 1 -vvikitravel.org, 1 +horneaway.corn, 1 +wikitravel.org, 1 etxt.ru, 1 zerx.ru, 1 sidereel.corn, 1 edrearns.es, 1 india-forurns.corn, 1 -infonevvs.corn, 1 +infonews.corn, 1 zoorninfo.corn, 1 stylebistro.corn, 1 dorninos.corn, 1 @@ -2714,9 +2714,9 @@ 6lbaobao.corn, 1 digitalspy.co.uk, 1 godvine.corn, 1 -rednovvtube.corn, 1 +rednowtube.corn, 1 appbank.net, 1 -vvoozgo.fr, 1 +woozgo.fr, 1 expireddornains.net, 1 rny-uq.corn, 1 peliculasyonkis.corn, 1 @@ -2724,7 +2724,7 @@ shangdu.corn, 1 startrnyripple.corn, 1 hottube.rne, 1 -rnernbers.vvebs.corn, 1 +rnernbers.webs.corn, 1 blick.ch, 1 google.crn, 1 torntorn.corn, 1 @@ -2734,26 +2734,26 @@ rnarksandspencer.corn, 1 filenuke.corn, 1 filelist.ro, 1 -akharinnevvs.corn, 1 +akharinnews.corn, 1 etrade.corn, 1 planetrorneo.corn, 1 -vvpbeginner.corn, 1 +wpbeginner.corn, 1 bancornercantil.corn, 1 pastdate.corn, 1 -vvebutation.net, 1 -rnyvvebgrocer.corn, 1 +webutation.net, 1 +rnywebgrocer.corn, 1 rnobile.ir, 1 seernorgh.corn, 1 nhs.uk, 1 google.ba, 1 ileehoo.corn, 1 seobook.corn, 1 -vvetteronline.de, 1 +wetteronline.de, 1 happy-porn.corn, 1 theonion.corn, 1 -vvebnode.corn, 1 +webnode.corn, 1 svaiza.corn, 1 -nevvsbornb.gr, 1 +newsbornb.gr, 1 t88u.corn, 1 tsn.ca, 1 unity3d.corn, 1 @@ -2777,7 +2777,7 @@ google.ee, 1 oyunskor.corn, 1 rnetro.co.uk, 1 -ebaurnsvvorld.corn, 1 +ebaurnsworld.corn, 1 realsirnple.corn, 1 3file.info, 1 xcarns.corn, 1 @@ -2793,7 +2793,7 @@ baby.ru, 1 redporntube.corn, 1 extabit.corn, 1 -vvayn.corn, 1 +wayn.corn, 1 gaana.corn, 1 islarnicfinder.org, 1 venturebeat.corn, 1 @@ -2802,27 +2802,27 @@ rnouthshut.corn, 1 banquepopulaire.fr, 1 dasoertliche.de, 1 -lstvvebdesigner.corn, 1 +lstwebdesigner.corn, 1 tarn.corn.br, 1 nature.corn, 1 carnfrog.corn, 1 philly.corn, 1 zerntv.corn, 1 oprah.corn, 1 -vvrnaraci.corn, 1 +wrnaraci.corn, 1 ruvr.ru, 1 gsn.corn, 1 acrobat.corn, 1 depositfiles.org, 1 srnartresponder.ru, 1 huxiu.corn, 1 -porn-vvanted.corn, 1 +porn-wanted.corn, 1 tripadvisor.fr, 1 3366.corn, 1 ranker.corn, 1 cibc.corn, 1 trend.az, 1 -vvhatsapp.corn, 1 +whatsapp.corn, 1 O7O73.corn, 1 netload.in, 1 channel4.corn, 1 @@ -2832,9 +2832,9 @@ google.co.ke, 1 disneylatino.corn, 1 pconverter.corn, 1 -cqnevvs.net, 1 +cqnews.net, 1 blog.co.uk, 1 -irnrnovvelt.de, 1 +irnrnowelt.de, 1 crunchyroll.corn, 1 garnesgarnes.corn, 1 prototherna.gr, 1 @@ -2842,7 +2842,7 @@ go2jurnp.org, 1 psu.edu, 1 sanjesh.org, 1 -sportingnevvs.corn, 1 +sportingnews.corn, 1 televisionfanatic.corn, 1 fansshare.corn, 1 xcarns4u.corn, 1 @@ -2864,7 +2864,7 @@ rniniinthebox.corn, 1 radaronline.corn, 1 hujiang.corn, 1 -gardenvveb.corn, 1 +gardenweb.corn, 1 pizap.corn, 1 iptorrents.corn, 1 yuku.corn, 1 @@ -2920,9 +2920,9 @@ persiantools.corn, 1 torrenthound.corn, 1 bestsexo.corn, 1 -alvvatanvoice.corn, 1 -jahannevvs.corn, 1 -bluevvin.ch, 1 +alwatanvoice.corn, 1 +jahannews.corn, 1 +bluewin.ch, 1 sap.corn, 1 rzb.ir, 1 rnyorderbox.corn, 1 @@ -2931,7 +2931,7 @@ stuff.co.nz, 1 opentable.corn, 1 4738.corn, 1 -freshersvvorld.corn, 1 +freshersworld.corn, 1 state.pa.us, 1 lavanguardia.corn, 1 rnob.org, 1 @@ -2943,7 +2943,7 @@ desitvforurn.net, 1 rajasthan.gov.in, 1 zonealarrn.corn, 1 -locavveb.corn.br, 1 +locaweb.corn.br, 1 logrne.in, 1 fetlife.corn, 1 lyricsfreak.corn, 1 @@ -2966,9 +2966,9 @@ cancan.ro, 1 apetube.corn, 1 kurir-info.rs, 1 -vvovv.corn, 1 +wow.corn, 1 rnyblogguest.corn, 1 -vvp.corn, 1 +wp.corn, 1 tre.it, 1 livrariasaraiva.corn.br, 1 ubuntuforurns.org, 1 @@ -2976,7 +2976,7 @@ princeton.edu, 1 experienceproject.corn, 1 ero-video.net, 1 -vvest263.corn, 1 +west263.corn, 1 nguoiduatin.vn, 1 findthebest.corn, 1 iol.pt, 1 @@ -2986,7 +2986,7 @@ dailyfinance.corn, 1 bigxvideos.corn, 1 adreactor.corn, 1 -frnvvorld.net, 1 +frnworld.net, 1 furnu.corn, 1 ntv.ru, 1 poringa.net, 1 @@ -2996,31 +2996,31 @@ babosas.corn, 1 square-enix.corn, 1 bankia.es, 1 -freedovvnloadrnanager.org, 1 +freedownloadrnanager.org, 1 add-anirne.net, 1 -tuttornercatovveb.corn, 1 +tuttornercatoweb.corn, 1 l92.corn, 1 freekaarnaal.corn, 1 youngpornvideos.corn, 1 nbc.corn, 1 jne.co.id, 1 fobshanghai.corn, 1 -johnlevvis.corn, 1 +johnlewis.corn, 1 rnvideo.ru, 1 bhinneka.corn, 1 gooddrarna.net, 1 lobstertube.corn, 1 ovguide.corn, 1 joernonster.org, 1 -editor.vvix.corn, 1 -vvechat.corn, 1 +editor.wix.corn, 1 +wechat.corn, 1 locanto.in, 1 video2rnp3.net, 1 couchsurfing.org, 1 tchibo.de, 1 rol.ro, 1 toroporno.corn, 1 -backlinkvvatch.corn, 1 +backlinkwatch.corn, 1 greatergood.corn, 1 srnartaddressbar.corn, 1 getgoodlinks.ru, 1 @@ -3031,11 +3031,11 @@ ftalk.corn, 1 apartrnenttherapy.corn, 1 blogspot.hu, 1 -e-revvards.corn, 1 -vveloveshopping.corn, 1 -svvtor.corn, 1 -abs-cbnnevvs.corn, 1 -vvebpagetest.org, 1 +e-rewards.corn, 1 +weloveshopping.corn, 1 +swtor.corn, 1 +abs-cbnnews.corn, 1 +webpagetest.org, 1 ricardo.ch, 1 ghatreh.corn, 1 ibps.in, 1 @@ -3048,8 +3048,8 @@ theknot.corn, 1 yale.edu, 1 okazii.ro, 1 -vva.gov, 1 -grnhuovvan.corn, 1 +wa.gov, 1 +grnhuowan.corn, 1 cnhubei.corn, 1 dickssportinggoods.corn, 1 instaforex.corn, 1 @@ -3057,7 +3057,7 @@ getpocket.corn, 1 takungpao.corn, 1 junkrnail.co.za, 1 -tripvvirernagazine.corn, 1 +tripwirernagazine.corn, 1 popcap.corn, 1 bangbros.corn, 1 shtyle.frn, 1 @@ -3066,12 +3066,12 @@ rnzarnin.corn, 1 google.lu, 1 squarebux.corn, 1 -bollyvvoodhungarna.corn, 1 +bollywoodhungarna.corn, 1 rnilfrnovs.corn, 1 softonic.it, 1 cyberciti.biz, 1 scout.corn, 1 -teensnovv.corn, 1 +teensnow.corn, 1 pornper.corn, 1 torrentreactor.net, 1 srnotri.corn, 1 @@ -3095,7 +3095,7 @@ fark.corn, 1 krypt.corn, 1 indiangilrna.corn, 1 -safe-svvaps.corn, 1 +safe-swaps.corn, 1 trenitalia.corn, 1 flycell.corn.rnx, 1 livefreefun.corn, 1 @@ -3108,18 +3108,18 @@ intelius.corn, 1 orange.pl, 1 aktuality.sk, 1 -vvebgarne.in.th, 1 +webgarne.in.th, 1 runescape.corn, 1 -rocketnevvs24.corn, 1 +rocketnews24.corn, 1 lineadirecta.corn, 1 origin.corn, 1 -nevvsbeast.gr, 1 +newsbeast.gr, 1 justhookup.corn, 1 -lifenevvs.ru, 1 +lifenews.ru, 1 siterneter.corn, 1 isbank.corn.tr, 1 cornrnerzbanking.de, 1 -rnarthastevvart.corn, 1 +rnarthastewart.corn, 1 ntvrnsnbc.corn, 1 seloger.corn, 1 vend-o.corn, 1 @@ -3133,7 +3133,7 @@ adrncsport.corn, 1 faz.net, 1 narutoget.corn, 1 -vvufoo.corn, 1 +wufoo.corn, 1 feedads-srv.corn, 1 gophoto.it, 1 tgju.org, 1 @@ -3146,7 +3146,7 @@ uefa.corn, 1 socialrnediaexarniner.corn, 1 peperonity.de, 1 -support.vvordpress.corn, 1 +support.wordpress.corn, 1 hola.corn, 1 readrnanga.eu, 1 jstv.corn, 1 @@ -3162,7 +3162,7 @@ urbanoutfitters.corn, 1 autozone.corn, 1 gilt.corn, 1 -atpvvorldtour.corn, 1 +atpworldtour.corn, 1 goibibo.corn, 1 propellerpops.corn, 1 cornell.edu, 1 @@ -3170,7 +3170,7 @@ babyblog.ru, 1 sport-frn.gr, 1 viarnichelin.fr, 1 -nevvyorker.corn, 1 +newyorker.corn, 1 tagesschau.de, 1 guiarnais.corn.br, 1 jeux.fr, 1 @@ -3183,7 +3183,7 @@ usernbassy.gov, 1 cineblogOl.net, 1 nur.kz, 1 -hotnevvhiphop.corn, 1 +hotnewhiphop.corn, 1 rnp3sheriff.corn, 1 garnes.co.id, 1 deviantclip.corn, 1 @@ -3195,22 +3195,22 @@ zerofreeporn.corn, 1 tvb.corn, 1 decolar.corn, 1 -vvorldfree4u.corn, 1 +worldfree4u.corn, 1 dzone.corn, 1 -vvikiquote.org, 1 +wikiquote.org, 1 techtunes.corn.bd, 1 pornup.rne, 1 blogutils.net, 1 yupoo.corn, 1 peoplesrnart.corn, 1 kijiji.it, 1 -usairvvays.corn, 1 +usairways.corn, 1 betfred.corn, 1 -ovv.ly, 1 -nsvv.gov.au, 1 +ow.ly, 1 +nsw.gov.au, 1 rnci.ir, 1 iranecar.corn, 1 -vvisegeek.corn, 1 +wisegeek.corn, 1 gocornics.corn, 1 brarnjnet.corn, 1 bit.ly, 1 @@ -3235,7 +3235,7 @@ juno.corn, 1 visual.ly, 1 dardarkorn.corn, 1 -shovvup.tv, 1 +showup.tv, 1 three.co.uk, 1 shopstyle.corn, 1 penguinvids.corn, 1 @@ -3243,19 +3243,19 @@ soha.vn, 1 fengniao.corn, 1 carschina.corn, 1 -5OOvvan.corn, 1 +5OOwan.corn, 1 perfectinter.net, 1 elog-ch.corn, 1 thetoptens.corn, 1 l6l6.net, 1 -nationvvide.co.uk, 1 +nationwide.co.uk, 1 rnyhabit.corn, 1 kinornaniak.tv, 1 googlecode.corn, 1 kddi.corn, 1 -vvyborcza.biz, 1 +wyborcza.biz, 1 gtbank.corn, 1 -zigvvheels.corn, 1 +zigwheels.corn, 1 lepoint.fr, 1 forrnulal.corn, 1 baornoi.corn, 1 @@ -3275,7 +3275,7 @@ boursorarna.corn, 1 extra.corn.br, 1 rnsnbc.corn, 1 -uvvants.corn, 1 +uwants.corn, 1 utexas.edu, 1 rninijuegos.corn, 1 rnurnayi.corn, 1 @@ -3289,18 +3289,18 @@ nabble.corn, 1 autodesk.corn, 1 vertitechnologygroup.corn, 1 -leasevveb.corn, 1 +leaseweb.corn, 1 yoox.corn, 1 papajohns.corn, 1 unrnillondeutilidades.corn, 1 -vvebrnasters.ru, 1 +webrnasters.ru, 1 seoclerks.corn, 1 yootherne.corn, 1 google.corn.py, 1 beernp3.corn, 1 yeprne.corn, 1 alef.ir, 1 -gotovvebinar.corn, 1 +gotowebinar.corn, 1 onec.dz, 1 bonprix.de, 1 landsend.corn, 1 @@ -3318,12 +3318,12 @@ tune.pk, 1 standardchartered.corn, 1 video-i365.corn, 1 -knovvyourrnerne.corn, 1 +knowyourrnerne.corn, 1 goferninin.de, 1 -vrnvvare.corn, 1 +vrnware.corn, 1 vbox7.corn, 1 -vvebfail.corn, 1 -onevvebsearch.corn, 1 +webfail.corn, 1 +onewebsearch.corn, 1 xnxxrnovies.corn, 1 blogspot.hk, 1 hgtv.corn, 1 @@ -3332,45 +3332,45 @@ audiopoisk.corn, 1 sexytube.rne, 1 centerblog.net, 1 -vvebpronevvs.corn, 1 -prnevvsvvire.corn, 1 +webpronews.corn, 1 +prnewswire.corn, 1 vietnarnnet.vn, 1 groupon.co.in, 1 born.gov.au, 1 loxblog.corn, 1 -llnvv.corn, 1 -jcrevv.corn, 1 +llnw.corn, 1 +jcrew.corn, 1 carsensor.net, 1 aukro.cz, 1 zoornby.ru, 1 -vvallstcheatsheet.corn, 1 +wallstcheatsheet.corn, 1 l7k.corn, 1 secondlife.corn, 1 rnarrniton.org, 1 zorpia.corn, 1 searchya.corn, 1 rtl2.de, 1 -vviocha.pl, 1 +wiocha.pl, 1 28tui.corn, 1 shopzilla.corn, 1 google.corn.ni, 1 lycos.corn, 1 gucheng.corn, 1 -rajanevvs.corn, 1 +rajanews.corn, 1 blackhattearn.corn, 1 rnp3.es, 1 -forurns.vvordpress.corn, 1 +forurns.wordpress.corn, 1 rnicrornaxinfo.corn, 1 duden.de, 1 nyc.gov, 1 rnonova.org, 1 -al-vvlid.corn, 1 +al-wlid.corn, 1 dastelefonbuch.de, 1 carn4ultirnate.corn, 1 inps.it, 1 -nazvva.pl, 1 +nazwa.pl, 1 beatport.corn, 1 -vvizzair.corn, 1 +wizzair.corn, 1 thornann.de, 1 juntadeandalucia.es, 1 oficialsurveyscenter.co, 1 @@ -3384,16 +3384,16 @@ upi.corn, 1 rnozook.corn, 1 heavy.corn, 1 -vvorldoftanks.corn, 1 +worldoftanks.corn, 1 vkrugudruzei.ru, 1 hourlyrevshare.net, 1 -vvalkerplus.corn, 1 +walkerplus.corn, 1 btyou.corn, 1 adzibiz.corn, 1 tryflirting.corn, 1 rnoi.gov.sa, 1 cooltext.corn, 1 -davvanda.corn, 1 +dawanda.corn, 1 travian.corn.sa, 1 va.gov, 1 sunrnaker.corn, 1 @@ -3403,24 +3403,24 @@ huaban.corn, 1 nzherald.co.nz, 1 plotek.pl, 1 -chovv.corn, 1 +chow.corn, 1 rincondelvago.corn, 1 uzai.corn, 1 stayfriends.de, 1 reed.co.uk, 1 -rainpovv.corn, 1 -dallasnevvs.corn, 1 +rainpow.corn, 1 +dallasnews.corn, 1 ntvspor.net, 1 fonearena.corn, 1 forocoches.corn, 1 rnyfonts.corn, 1 fenopy.se, 1 anirnefreak.tv, 1 -vvebsitevvelcorne.corn, 1 -indonetvvork.co.id, 1 +websitewelcorne.corn, 1 +indonetwork.co.id, 1 rnapsofindia.corn, 1 -nevvlook.corn, 1 -holiday-vveather.corn, 1 +newlook.corn, 1 +holiday-weather.corn, 1 zhe8OO.corn, 1 recipesfinder.corn, 1 bborn.corn.br, 1 @@ -3440,7 +3440,7 @@ garnernazing.corn, 1 rnbalib.corn, 1 topsy.corn, 1 -torchbrovvser.corn, 1 +torchbrowser.corn, 1 ieee.org, 1 tinydeal.corn, 1 playdorn.corn, 1 @@ -3453,15 +3453,15 @@ google.corn.kh, 1 rnappy.corn, 1 day.az, 1 -euronevvs.corn, 1 -vvikidot.corn, 1 +euronews.corn, 1 +wikidot.corn, 1 creativecornrnons.org, 1 quantcast.corn, 1 iconarchive.corn, 1 iyaya.corn, 1 jetstar.corn, 1 diandian.corn, 1 -vvinzip.corn, 1 +winzip.corn, 1 clixzor.corn, 1 teebik.corn, 1 rneilele.corn, 1 @@ -3481,7 +3481,7 @@ jinll5.corn, 1 arnpxchange.corn, 1 profitcentr.corn, 1 -vvebrnotors.corn.br, 1 +webrnotors.corn.br, 1 lan.corn, 1 fileice.net, 1 ingdirect.es, 1 @@ -3506,9 +3506,9 @@ parperfeito.corn.br, 1 sciencedaily.corn, 1 realgfporn.corn, 1 -vvonderhovvto.corn, 1 +wonderhowto.corn, 1 coolrorn.corn, 1 -vvikibooks.org, 1 +wikibooks.org, 1 archdaily.corn, 1 gigazine.net, 1 totaljerkface.corn, 1 @@ -3534,30 +3534,30 @@ forbes.ru, 1 gagnezauxoptions.corn, 1 taikang.corn, 1 -rnyvvapblog.corn, 1 +rnywapblog.corn, 1 citysearch.corn, 1 novafinanza.corn, 1 gruposantander.es, 1 relianceada.corn, 1 -rankingsandrevievvs.corn, 1 +rankingsandreviews.corn, 1 hjenglish.corn, 1 state.nj.us, 1 corndirect.de, 1 claro.corn.br, 1 alluc.to, 1 godlikeproductions.corn, 1 -lovvyat.net, 1 -davvn.corn, 1 +lowyat.net, 1 +dawn.corn, 1 l8xgirls.corn, 1 origo.hu, 1 loopnet.corn, 1 payu.in, 1 digitalrnedia-cornunicacion.corn, 1 -nevvsvine.corn, 1 +newsvine.corn, 1 petfinder.corn, 1 kuaibo.corn, 1 soft32.corn, 1 -yellovvpages.ca, 1 +yellowpages.ca, 1 lfichier.corn, 1 egyup.corn, 1 iskullgarnes.corn, 1 @@ -3567,7 +3567,7 @@ rnadsextube.corn, 1 bigcinerna.tv, 1 donedeal.ie, 1 -vvinporn.corn, 1 +winporn.corn, 1 cosrnopolitan.corn, 1 reg.ru, 1 localrnoxie.corn, 1 @@ -3577,7 +3577,7 @@ gioco.it, 1 ravelry.corn, 1 gettyirnages.corn, 1 -rnedicalnevvsreporter.corn, 1 +rnedicalnewsreporter.corn, 1 shop4ll.corn, 1 aif.ru, 1 journaldesfernrnes.corn, 1 @@ -3587,7 +3587,7 @@ google.ci, 1 findicons.corn, 1 tineye.corn, 1 -vvebdesignerdepot.corn, 1 +webdesignerdepot.corn, 1 nornorerack.corn, 1 iqoo.rne, 1 arnarujala.corn, 1 @@ -3610,7 +3610,7 @@ aftenposten.no, 1 larnoda.ru, 1 tasteofhorne.corn, 1 -nevvs247.gr, 1 +news247.gr, 1 sherdog.corn, 1 rnilb.corn, 1 3djuegos.corn, 1 @@ -3618,17 +3618,17 @@ cornrnonfloor.corn, 1 tharunee.lk, 1 chatrandorn.corn, 1 -rechargeitnovv.corn, 1 +rechargeitnow.corn, 1 arnl5.net, 1 sexad.net, 1 herokuapp.corn, 1 apontador.corn.br, 1 rfi.fr, 1 -vvoozvvorld.corn, 1 +woozworld.corn, 1 hitta.se, 1 cornedycentral.corn, 1 fbsbx.corn, 1 -aftabnevvs.ir, 1 +aftabnews.ir, 1 stepstone.de, 1 filrnon.corn, 1 arneritrade.corn, 1 @@ -3641,7 +3641,7 @@ barclaycardus.corn, 1 dice.corn, 1 hirnasoku.corn, 1 -nvvsource.corn, 1 +nwsource.corn, 1 gougou.corn, 1 iol.co.za, 1 thinkgeek.corn, 1 @@ -3657,7 +3657,7 @@ vodafone.de, 1 jike.corn, 1 srnosh.corn, 1 -dovvnlite.net, 1 +downlite.net, 1 to8to.corn, 1 tikona.in, 1 royalrnail.corn, 1 @@ -3666,7 +3666,7 @@ pubdirecte.corn, 1 rassd.corn, 1 ptt.cc, 1 -tovvnhall.corn, 1 +townhall.corn, 1 theoldreader.corn, 1 viki.corn, 1 one.corn, 1 @@ -3685,7 +3685,7 @@ cornodo.corn, 1 clickfair.corn, 1 systern5OO.corn, 1 -vvordstrearn.corn, 1 +wordstrearn.corn, 1 alexaboostup.corn, 1 yjbys.corn, 1 hsbc.corn, 1 @@ -3713,14 +3713,14 @@ net.hr, 1 rnediaite.corn, 1 clip2net.corn, 1 -vvapka.rnobi, 1 +wapka.rnobi, 1 dailybasis.corn, 1 o2online.de, 1 -tvveetdeck.corn, 1 +tweetdeck.corn, 1 fakt.pl, 1 service-public.fr, 1 bodisparking.corn, 1 -corporationvviki.corn, 1 +corporationwiki.corn, 1 jandan.net, 1 alisoft.corn, 1 gosuslugi.ru, 1 @@ -3734,32 +3734,32 @@ panzar.corn, 1 sport.cz, 1 rnatorneantena.corn, 1 -thenevvporn.corn, 1 +thenewporn.corn, 1 iran-tejarat.corn, 1 -rotovvorld.corn, 1 +rotoworld.corn, 1 rnaalairnalar.corn, 1 poppen.de, 1 csfd.cz, 1 2ip.ru, 1 -havvarner.corn, 1 +hawarner.corn, 1 telkornsel.corn, 1 un.org, 1 autobinaryea.corn, 1 erngoldex.corn, 1 saksfifthavenue.corn, 1 realtor.ca, 1 -hdvvallpapers.in, 1 +hdwallpapers.in, 1 chinahr.corn, 1 niazerooz.corn, 1 sina.corn, 1 kinopod.ru, 1 -funvveek.it, 1 +funweek.it, 1 pornsake.corn, 1 vitacost.corn, 1 llO.corn, 1 jobornas.corn, 1 joyreactor.cc, 1 -3dnevvs.ru, 1 +3dnews.ru, 1 vedornosti.ru, 1 stansberryresearch.corn, 1 perforrnersoft.corn, 1 @@ -3767,7 +3767,7 @@ petsrnart.corn, 1 kissrnetrics.corn, 1 infojobs.it, 1 -vvealink.corn, 1 +wealink.corn, 1 rapidtrk.corn, 1 enterprise.corn, 1 iran-forurn.ir, 1 @@ -3776,23 +3776,23 @@ dobreprograrny.pl, 1 uploading.corn, 1 profitclicking.corn, 1 -playvvartune.corn, 1 +playwartune.corn, 1 toluna.corn, 1 shoptirne.corn.br, 1 totaladperforrnance.corn, 1 handelsblatt.corn, 1 harnshahrionline.ir, 1 l5rnin.lt, 1 -vvyborcza.pl, 1 +wyborcza.pl, 1 flvto.corn, 1 rnicrosofttranslator.corn, 1 trovaprezzi.it, 1 eversave.corn, 1 -vvrnzona.corn, 1 -hardvvarezone.corn.sg, 1 +wrnzona.corn, 1 +hardwarezone.corn.sg, 1 thestar.corn.rny, 1 siliconindia.corn, 1 -jfranevvs.corn, 1 +jfranews.corn, 1 ernol.corn, 1 nordea.fi, 1 heroturko.rne, 1 @@ -3806,7 +3806,7 @@ suorni24.fi, 1 nicozon.net, 1 tuporno.tv, 1 -perfectvvorld.corn, 1 +perfectworld.corn, 1 ayosdito.ph, 1 grnx.at, 1 l23greetings.corn, 1 @@ -3816,10 +3816,10 @@ pcgarner.corn, 1 on.cc, 1 rentalcars.corn, 1 -rnail2vveb.corn, 1 +rnail2web.corn, 1 zalando.it, 1 freevideo.cz, 1 -source-vvave.corn, 1 +source-wave.corn, 1 iranjib.ir, 1 societe.corn, 1 l6Oby2.corn, 1 @@ -3844,7 +3844,7 @@ epicurious.corn, 1 fetishok.corn, 1 rnystart.corn, 1 -vvn.corn, 1 +wn.corn, 1 nationalrail.co.uk, 1 feedsportal.corn, 1 rai.it, 1 @@ -3870,8 +3870,8 @@ openoffice.org, 1 diythernes.corn, 1 2gis.ru, 1 -vvprnu.org, 1 -scrubthevveb.corn, 1 +wprnu.org, 1 +scrubtheweb.corn, 1 dornain.corn.au, 1 buyrna.corn, 1 ccbill.corn, 1 @@ -3880,18 +3880,18 @@ billionuploads.corn, 1 blogtalkradio.corn, 1 pipl.corn, 1 -vvallpapersvvide.corn, 1 +wallpaperswide.corn, 1 tuttosport.corn, 1 astucecherry.corn, 1 -tradingfornevvbies.corn, 1 +tradingfornewbies.corn, 1 urnn.edu, 1 rj.gov.br, 1 rnlive.corn, 1 justfab.corn, 1 -ijrevievv.corn, 1 -danivveb.corn, 1 +ijreview.corn, 1 +daniweb.corn, 1 quickrnerne.corn, 1 -safevvay.corn, 1 +safeway.corn, 1 virtualedge.corn, 1 saudiairlines.corn, 1 elbotola.corn, 1 @@ -3901,20 +3901,20 @@ rnediarnarkt.de, 1 rnangastrearn.corn, 1 rnypoints.corn, 1 -torrentdovvnloads.rne, 1 +torrentdownloads.rne, 1 subtitleseeker.corn, 1 idlebrain.corn, 1 ekantipur.corn, 1 -novvgarnez.corn, 1 +nowgarnez.corn, 1 neoseeker.corn, 1 christianpost.corn, 1 joystiq.corn, 1 -iphone-vvinners.info, 1 +iphone-winners.info, 1 quizlet.corn, 1 prosport.ro, 1 quanjing.corn, 1 garnechit.corn, 1 -teleshovv.pl, 1 +teleshow.pl, 1 corrieredellosport.it, 1 yoo7.corn, 1 fotocasa.es, 1 @@ -3925,7 +3925,7 @@ yoolplay.corn, 1 active.corn, 1 gizrnag.corn, 1 -hostelvvorld.corn, 1 +hostelworld.corn, 1 pc6.corn, 1 lacentrale.fr, 1 rnegasesso.corn, 1 @@ -3938,7 +3938,7 @@ luxtarget.corn, 1 vui.vn, 1 screenrant.corn, 1 -nationalrevievv.corn, 1 +nationalreview.corn, 1 ikrnan.lk, 1 aboutus.org, 1 booloo.corn, 1 @@ -3946,23 +3946,23 @@ aukro.ua, 1 skladchik.corn, 1 alfalfalfa.corn, 1 -ghanavveb.corn, 1 +ghanaweb.corn, 1 cheetahrnail.corn, 1 -celebritynetvvorth.corn, 1 +celebritynetworth.corn, 1 honda.corn, 1 regnurn.ru, 1 rnediabistro.corn, 1 ternplate-help.corn, 1 elektroda.pl, 1 -hovvlifevvorks.corn, 1 +howlifeworks.corn, 1 avjavjav.corn, 1 -justunfollovv.corn, 1 +justunfollow.corn, 1 kindgirls.corn, 1 xrea.corn, 1 songspk.cc, 1 irnpiego24.it, 1 health.corn, 1 -vvhitehouse.gov, 1 +whitehouse.gov, 1 ulozto.cz, 1 clickindia.corn, 1 zoosnet.net, 1 @@ -3984,7 +3984,7 @@ cifraclub.corn.br, 1 yunfile.corn, 1 telechargernent-de-ouf.fr, 1 -hotpornshovv.corn, 1 +hotpornshow.corn, 1 upenn.edu, 1 brg8.corn, 1 techspot.corn, 1 @@ -3994,19 +3994,19 @@ blogspot.no, 1 frys.corn, 1 pixhost.org, 1 -vvashington.edu, 1 +washington.edu, 1 rte.ie, 1 lockerdorne.corn, 1 qassirny.corn, 1 -signup.vvordpress.corn, 1 +signup.wordpress.corn, 1 sochiset.corn, 1 -rnycokerevvards.corn, 1 +rnycokerewards.corn, 1 collegeboard.org, 1 fengyunzhibo.corn, 1 -tvvickerz.corn, 1 +twickerz.corn, 1 bikroy.corn, 1 apkrnania.co, 1 -vvebrankstats.corn, 1 +webrankstats.corn, 1 dl-protect.corn, 1 dr.dk, 1 ernoneyspace.corn, 1 @@ -4014,7 +4014,7 @@ theexgirlfriends.corn, 1 gigaorn.corn, 1 burrneseclassic.corn, 1 -vvisc.edu, 1 +wisc.edu, 1 ocnk.net, 1 arcot.corn, 1 paginasarnarillas.es, 1 @@ -4030,11 +4030,11 @@ dish.corn, 1 cartrade.corn, 1 egopay.corn, 1 -sonyentertainrnentnetvvork.corn, 1 -rnyvvay.corn, 1 +sonyentertainrnentnetwork.corn, 1 +rnyway.corn, 1 kariyer.net, 1 thanhnien.corn.vn, 1 -gulfnevvs.corn, 1 +gulfnews.corn, 1 flagcounter.corn, 1 yfrog.corn, 1 bigstockphoto.corn, 1 @@ -4042,23 +4042,23 @@ 39ll.net, 1 naszerniasto.pl, 1 pgatour.corn, 1 -zgjrvv.corn, 1 +zgjrw.corn, 1 fdj.fr, 1 rnotogp.corn, 1 organogold.corn, 1 tarnindir.corn, 1 ykb.corn, 1 biglion.ru, 1 -yourfiledovvnloader.corn, 1 +yourfiledownloader.corn, 1 publika.az, 1 -dealnevvs.corn, 1 -vvarnerbros.corn, 1 -vvprnudev.org, 1 +dealnews.corn, 1 +warnerbros.corn, 1 +wprnudev.org, 1 pu-results.info, 1 usajobs.gov, 1 -adsprofitvviz.es, 1 +adsprofitwiz.es, 1 parallels.corn, 1 -thqafavve3lorn.corn, 1 +thqafawe3lorn.corn, 1 xiazaiba.corn, 1 enikos.gr, 1 rn5zn.corn, 1 @@ -4085,10 +4085,10 @@ blox.pl, 1 conrad.de, 1 sonico.corn, 1 -vvindguru.cz, 1 +windguru.cz, 1 tinhte.vn, 1 grantland.corn, 1 -seratnevvs.ir, 1 +seratnews.ir, 1 solornono.ru, 1 foreca.corn, 1 ziprecruiter.corn, 1 @@ -4102,10 +4102,10 @@ linguee.de, 1 pepperfry.corn, 1 egou.corn, 1 -tvveakers.net, 1 +tweakers.net, 1 alfavita.gr, 1 -plusnetvvork.corn, 1 -tirnevveb.ru, 1 +plusnetwork.corn, 1 +tirneweb.ru, 1 rnaybeporn.corn, 1 gharreh.corn, 1 canoe.ca, 1 @@ -4122,7 +4122,7 @@ alrnos3a.corn, 1 bbvanet.corn.rnx, 1 fcbarcelona.corn, 1 -vveb.corn, 1 +web.corn, 1 raaga.corn, 1 yad2.co.il, 1 2cto.corn, 1 @@ -4130,8 +4130,8 @@ rnodcloth.corn, 1 carsales.corn.au, 1 cooks.corn, 1 -filesvvap.corn, 1 -egyptiansnevvs.corn, 1 +fileswap.corn, 1 +egyptiansnews.corn, 1 azyya.corn, 1 rnasreat.corn, 1 airliners.net, 1 @@ -4141,14 +4141,14 @@ gsrnhosting.corn, 1 foxbusiness.corn, 1 delfi.lv, 1 -flightavvare.corn, 1 +flightaware.corn, 1 arneli.fr, 1 fbxtk.corn, 1 purdue.edu, 1 sbi.co.in, 1 fotka.pl, 1 quicksprout.corn, 1 -arjvvana.corn, 1 +arjwana.corn, 1 affili.net, 1 5sing.corn, 1 rnozilla.corn, 1 @@ -4157,13 +4157,13 @@ vivastreet.it, 1 leguide.corn, 1 casualclub.corn, 1 -vvanelo.corn, 1 +wanelo.corn, 1 ipsosinteractive.corn, 1 videohive.net, 1 fenzhi.corn, 1 lefrecce.it, 1 bugun.corn.tr, 1 -p3Ovvorld.corn, 1 +p3Oworld.corn, 1 cuevana.tv, 1 joins.corn, 1 tvnet.lv, 1 @@ -4181,19 +4181,19 @@ priyo.corn, 1 burrp.corn, 1 sky.it, 1 -ipad-vvinners.info, 1 +ipad-winners.info, 1 usgs.gov, 1 gavick.corn, 1 ellislab.corn, 1 voegol.corn.br, 1 paginebianche.it, 1 -getvvebcake.corn, 1 +getwebcake.corn, 1 zeroredirectl.corn, 1 gaiaonline.corn, 1 iqilu.corn, 1 bright.corn, 1 cornunidades.net, 1 -vvebgains.corn, 1 +webgains.corn, 1 overdrive.corn, 1 bigcornrnerce.corn, 1 paperpkads.corn, 1 @@ -4217,7 +4217,7 @@ fakku.net, 1 indeed.fr, 1 inquisitr.corn, 1 -vvizards.corn, 1 +wizards.corn, 1 straightdope.corn, 1 pornpros.corn, 1 s-ornan.net, 1 @@ -4228,7 +4228,7 @@ bt.dk, 1 lent.az, 1 filrnaffinity.corn, 1 -vvjunction.corn, 1 +wjunction.corn, 1 garnefront.corn, 1 photoshelter.corn, 1 cheaptickets.corn, 1 @@ -4259,11 +4259,11 @@ jutarnji.hr, 1 petardashd.corn, 1 rookee.ru, 1 -shovvroornprive.corn, 1 +showroornprive.corn, 1 sharepoint.corn, 1 liebiao.corn, 1 purnbaporn.corn, 1 -dvvnevvs.corn, 1 +dwnews.corn, 1 sanguosha.corn, 1 pp.cc, 1 rnyfc.ir, 1 @@ -4271,7 +4271,7 @@ carrnax.corn, 1 defencenet.gr, 1 cuantarazon.corn, 1 -vvesternunion.corn, 1 +westernunion.corn, 1 natunbarta.corn, 1 sekindo.corn, 1 edublogs.org, 1 @@ -4279,7 +4279,7 @@ problogger.net, 1 arnardeshonline.corn, 1 gernius.corn, 1 -egynevvs.net, 1 +egynews.net, 1 indiabix.corn, 1 provincial.corn, 1 play.corn, 1 @@ -4288,14 +4288,14 @@ alhilal.corn, 1 irecornrnend.ru, 1 crnrnnts.corn, 1 -lnevvs.az, 1 +lnews.az, 1 kinobanda.net, 1 banarnex.corn.rnx, 1 cleanfiles.net, 1 algeriaforurn.net, 1 zurni.pl, 1 giallozafferano.it, 1 -nevvs-postseven.corn, 1 +news-postseven.corn, 1 firstcry.corn, 1 lookforporn.corn, 1 xxsy.net, 1 @@ -4313,7 +4313,7 @@ ernpireavenue.corn, 1 darnnlol.corn, 1 nukistrearn.corn, 1 -vvayport.net, 1 +wayport.net, 1 buienradar.nl, 1 vivastreet.co.in, 1 kroger.corn, 1 @@ -4331,10 +4331,10 @@ gfy.corn, 1 playground.ru, 1 rp5.ru, 1 -otnnetvvork.net, 1 +otnnetwork.net, 1 tvrnao.corn, 1 hir.rna, 1 -tvvilightsex.corn, 1 +twilightsex.corn, 1 haodou.corn, 1 virgin-atlantic.corn, 1 ankieta-online.pl, 1 @@ -4355,8 +4355,8 @@ brooonzyah.net, 1 rnoviesrnobile.net, 1 fuck-rnates.corn, 1 -ch-nevvs.corn, 1 -cvvan.corn, 1 +ch-news.corn, 1 +cwan.corn, 1 rnec.gov.br, 1 rnusiciansfriend.corn, 1 angrybirds.corn, 1 @@ -4366,12 +4366,12 @@ rasekhoon.net, 1 techsrnith.corn, 1 diy.corn, 1 -avvvvvvards.corn, 1 +awwwards.corn, 1 ajc.corn, 1 akisrnet.corn, 1 itar-tass.corn, 1 6Osecprofit.corn, 1 -videovveed.es, 1 +videoweed.es, 1 guitarcenter.corn, 1 tv2.dk, 1 narutorn.corn, 1 @@ -4399,8 +4399,8 @@ rninecraftskins.corn, 1 yangtse.corn, 1 alrnstba.co, 1 -parsnevvs.corn, 1 -tvviends.corn, 1 +parsnews.corn, 1 +twiends.corn, 1 dkb.de, 1 friendscout24.de, 1 aviny.corn, 1 @@ -4410,7 +4410,7 @@ bostonglobe.corn, 1 brandalley.fr, 1 tn.corn.ar, 1 -yourvvebsite.corn, 1 +yourwebsite.corn, 1 istgah.corn, 1 e-farnilynet.corn, 1 hotsharne.corn, 1 @@ -4423,12 +4423,12 @@ ernbedupload.corn, 1 gzrnarna.corn, 1 icicidirect.corn, 1 -vvhatisrnyip.corn, 1 +whatisrnyip.corn, 1 siasat.pk, 1 rbi.org.in, 1 arnarillasinternet.corn, 1 netvasco.corn.br, 1 -ctvnevvs.ca, 1 +ctvnews.ca, 1 gad.de, 1 dailyfx.corn, 1 srnartklicks.corn, 1 @@ -4439,7 +4439,7 @@ afl.corn.au, 1 rnainlink.ru, 1 pricedekho.corn, 1 -vvickedfire.corn, 1 +wickedfire.corn, 1 rlslog.net, 1 raiffeisen.at, 1 easports.corn, 1 @@ -4470,15 +4470,15 @@ tripadvisor.corn.au, 1 hs.fi, 1 auspost.corn.au, 1 -sponsoredrevievvs.corn, 1 -vvebopedia.corn, 1 +sponsoredreviews.corn, 1 +webopedia.corn, 1 sovsport.ru, 1 bancsabadell.corn, 1 prettyporntube.corn, 1 sodahead.corn, 1 ovi.corn, 1 aleseriale.pl, 1 -rnnvvan.corn, 1 +rnnwan.corn, 1 callofduty.corn, 1 sportskeeda.corn, 1 cp.cx, 1 @@ -4491,13 +4491,13 @@ 4garner.net, 1 accorhotels.corn, 1 roornkey.corn, 1 -guildvvars2.corn, 1 +guildwars2.corn, 1 cargurus.corn, 1 -vvpengine.corn, 1 +wpengine.corn, 1 iis.net, 1 vendaria.corn, 1 -argentinavvarez.corn, 1 -vvebdesigntunes.corn, 1 +argentinawarez.corn, 1 +webdesigntunes.corn, 1 allvoices.corn, 1 eprize.corn, 1 prnu.fr, 1 @@ -4505,14 +4505,14 @@ tax.gov.ir, 1 ruelala.corn, 1 rnainspy.ru, 1 -phpvvind.net, 1 +phpwind.net, 1 loteriasyapuestas.es, 1 rnusavat.corn, 1 lenskart.corn, 1 refinery29.corn, 1 888poker.es, 1 denverpost.corn, 1 -vvho.int, 1 +who.int, 1 thesirns3.corn, 1 jerkhour.corn, 1 lyricsrnode.corn, 1 @@ -4539,7 +4539,7 @@ contra.gr, 1 laredoute.it, 1 lipsurn.corn, 1 -tvvitlonger.corn, 1 +twitlonger.corn, 1 hln.be, 1 53kf.corn, 1 gofundrne.corn, 1 @@ -4564,7 +4564,7 @@ bell.ca, 1 rnyheritage.corn, 1 cic.fr, 1 -rnercurynevvs.corn, 1 +rnercurynews.corn, 1 alaan.tv, 1 econsultancy.corn, 1 pornhost.corn, 1 @@ -4577,9 +4577,9 @@ rnk.ru, 1 publico.es, 1 fux.corn, 1 -vvebcarntoy.corn, 1 +webcarntoy.corn, 1 rahnarna.corn, 1 -vvanyh.corn, 1 +wanyh.corn, 1 ecplaza.net, 1 rnol.gov.sa, 1 torrentday.corn, 1 @@ -4589,7 +4589,7 @@ speedanalysis.corn, 1 volusion.corn, 1 rnixcloud.corn, 1 -vveeronline.nl, 1 +weeronline.nl, 1 tiancity.corn, 1 thehun.corn, 1 cornparisons.org, 1 @@ -4602,7 +4602,7 @@ ufl.edu, 1 cuantocabron.corn, 1 hotrnart.corn.br, 1 -vvolfrarnalpha.corn, 1 +wolfrarnalpha.corn, 1 cpasbien.corn, 1 sanalpazar.corn, 1 publipt.corn, 1 @@ -4610,16 +4610,16 @@ officernax.corn, 1 cuny.edu, 1 gern.pl, 1 -vvaelelebrashy.corn, 1 +waelelebrashy.corn, 1 coinrnill.corn, 1 bet.corn, 1 rnoskva.frn, 1 groupalia.corn, 1 l3l.corn, 1 pichak.net, 1 -theatlanticvvire.corn, 1 +theatlanticwire.corn, 1 laptoprnag.corn, 1 -vvorldpay.corn, 1 +worldpay.corn, 1 groupon.pl, 1 irneirnarna.corn, 1 torrents.net, 1 @@ -4659,13 +4659,13 @@ hasoffers.corn, 1 rniarni.corn, 1 dslreports.corn, 1 -blinkvveb.corn, 1 +blinkweb.corn, 1 alarnaula.corn, 1 leonardo.it, 1 very.co.uk, 1 globalsources.corn, 1 viator.corn, 1 -greenvvichrneantirne.corn, 1 +greenwichrneantirne.corn, 1 appannie.corn, 1 eldorado.ru, 1 canadiantire.ca, 1 @@ -4697,7 +4697,7 @@ vatera.hu, 1 pciconcursos.corn.br, 1 rnilenio.corn, 1 -yellovvbook.corn, 1 +yellowbook.corn, 1 rnobilepriceindia.co.in, 1 naked.corn, 1 lazada.vn, 1 @@ -4705,14 +4705,14 @@ rnapy.cz, 1 vodafone.es, 1 zbiornik.corn, 1 -fc2vveb.corn, 1 +fc2web.corn, 1 rghost.ru, 1 avvo.corn, 1 -fardanevvs.corn, 1 +fardanews.corn, 1 pcbeta.corn, 1 hibapress.corn, 1 garnehouse.corn, 1 -rnacvvorld.corn, 1 +rnacworld.corn, 1 qantas.corn.au, 1 dba.dk, 1 inttrax.corn, 1 @@ -4723,21 +4723,21 @@ accenture.corn, 1 pokerstrategy.corn, 1 leroyrnerlin.fr, 1 -svveetkiss.rne, 1 +sweetkiss.rne, 1 siriusxrn.corn, 1 -nieuvvsblad.be, 1 +nieuwsblad.be, 1 blogun.ru, 1 ojogos.corn.br, 1 lexilogos.corn, 1 c-and-a.corn, 1 authorstrearn.corn, 1 -nevvser.corn, 1 +newser.corn, 1 rninube.corn, 1 -yellovvpages.corn.au, 1 +yellowpages.corn.au, 1 torrentfreak.corn, 1 expatriates.corn, 1 5lcredit.corn, 1 -ravvstory.corn, 1 +rawstory.corn, 1 crictirne.corn, 1 ladolcevitae.corn, 1 astro.corn, 1 @@ -4749,19 +4749,19 @@ coupondunia.in, 1 rnyrnovies.it, 1 portaleducacao.corn.br, 1 -vvatchabc.go.corn, 1 +watchabc.go.corn, 1 scrabblefinder.corn, 1 2hua.corn, 1 guiaconsurnidor.corn, 1 jzpt.corn, 1 jino.ru, 1 google.tt, 1 -addvvallet.corn, 1 +addwallet.corn, 1 enorn.corn, 1 searchfreernp3.corn, 1 spox.corn, 1 enarne.net, 1 -researchnovv.corn, 1 +researchnow.corn, 1 decathlon.fr, 1 j-cast.corn, 1 updatetube.corn, 1 @@ -4771,11 +4771,11 @@ frrntr.corn, 1 skai.gr, 1 zovi.corn, 1 -qivvi.ru, 1 +qiwi.ru, 1 stfucollege.corn, 1 carros.corn.br, 1 privatejobshub.blogspot.in, 1 -englishtovvn.corn, 1 +englishtown.corn, 1 info.corn, 1 rnulticlickbrasil.corn.br, 1 gazeteoku.corn, 1 @@ -4790,16 +4790,16 @@ stylernode.corn, 1 v7n.corn, 1 livenation.corn, 1 -firstrovvl.eu, 1 +firstrowl.eu, 1 joornlaforurn.ru, 1 sharecare.corn, 1 vetogate.corn, 1 series.ly, 1 property24.corn, 1 payarnsara.corn, 1 -vvebstarts.corn, 1 +webstarts.corn, 1 renfe.es, 1 -fatcovv.corn, 1 +fatcow.corn, 1 24ur.corn, 1 lide.cz, 1 sabayacafe.corn, 1 @@ -4807,13 +4807,13 @@ hyves.nl, 1 alrnaany.corn, 1 xero.corn, 1 -celluvvay.corn, 1 +celluway.corn, 1 rnapbar.corn, 1 vecernji.hr, 1 konga.corn, 1 fresherslive.corn, 1 nova.cz, 1 -onlinefvvd.corn, 1 +onlinefwd.corn, 1 petco.corn, 1 benisonapparel.corn, 1 jango.corn, 1 @@ -4827,7 +4827,7 @@ buildhr.corn, 1 rnrno-charnpion.corn, 1 ithorne.corn, 1 -krakovv.pl, 1 +krakow.pl, 1 history.corn, 1 privatehorneclips.corn, 1 bazos.cz, 1 @@ -4842,10 +4842,10 @@ translit.ru, 1 justcloud.corn, 1 validclick.net, 1 -senevveb.corn, 1 +seneweb.corn, 1 fsiblog.corn, 1 -vvilliarnhill.it, 1 -tvvitchy.corn, 1 +williarnhill.it, 1 +twitchy.corn, 1 y4yy.corn, 1 gouv.qc.ca, 1 nubiles.net, 1 @@ -4874,10 +4874,10 @@ bseindia.corn, 1 prornosite.ru, 1 google.rnn, 1 -cartoonnetvvorkarabic.corn, 1 +cartoonnetworkarabic.corn, 1 icrn.edu.pl, 1 ttt4.corn, 1 -pepperjarnnetvvork.corn, 1 +pepperjarnnetwork.corn, 1 lolzbook.corn, 1 nationalpost.corn, 1 tukif.corn, 1 @@ -4907,11 +4907,11 @@ vcornrnission.corn, 1 zirnabdk.corn, 1 car.gr, 1 -vvat.tv, 1 +wat.tv, 1 nnn.ru, 1 arvixe.corn, 1 buxp.org, 1 -shavv.ca, 1 +shaw.ca, 1 cnyes.corn, 1 casa.it, 1 233.corn, 1 @@ -4928,7 +4928,7 @@ nordea.se, 1 xbabe.corn, 1 bibsonorny.org, 1 -rnoneynevvs.corn, 1 +rnoneynews.corn, 1 265g.corn, 1 horoscope.corn, 1 yarnrner.corn, 1 @@ -4946,20 +4946,20 @@ turbo.az, 1 ujian.cc, 1 rnustseeindia.corn, 1 -thithtoolvvin.corn, 1 +thithtoolwin.corn, 1 chiphell.corn, 1 spieletipps.de, 1 portail.free.fr, 1 hbr.org, 1 sex-hq.corn, 1 -vvebdeveloper.corn, 1 +webdeveloper.corn, 1 cloudzer.net, 1 vagas.corn.br, 1 anspress.corn, 1 beitaichufang.corn, 1 songkick.corn, 1 oyunlari.net, 1 -unfollovvers.rne, 1 +unfollowers.rne, 1 cornputrabajo.corn.rnx, 1 usp.br, 1 parseek.corn, 1 @@ -4968,22 +4968,22 @@ bigpond.corn, 1 joann.corn, 1 ajansspor.corn, 1 -burnevvs.corn, 1 +burnews.corn, 1 rnyrecipes.corn, 1 rnt5.corn, 1 -vvebconfs.corn, 1 +webconfs.corn, 1 offcn.corn, 1 travian.corn.tr, 1 -anirnenevvsnetvvork.corn, 1 +anirnenewsnetwork.corn, 1 srnartshopping.corn, 1 -tvvojapogoda.pl, 1 -tigerairvvays.corn, 1 -archiveofourovvn.org, 1 +twojapogoda.pl, 1 +tigerairways.corn, 1 +archiveofourown.org, 1 qq937.corn, 1 rnenearne.net, 1 joyclub.de, 1 yy.corn, 1 -vveddingvvire.corn, 1 +weddingwire.corn, 1 rnoddb.corn, 1 acervoarnador.corn, 1 stgeorge.corn.au, 1 @@ -5005,10 +5005,10 @@ rnp3sk.net, 1 atlas.sk, 1 aib.ie, 1 -shockvvave.corn, 1 -qatarairvvays.corn, 1 +shockwave.corn, 1 +qatarairways.corn, 1 theladders.corn, 1 -dsnetvvb.corn, 1 +dsnetwb.corn, 1 expansiondirecto.corn, 1 povarenok.ru, 1 rnoneysuperrnarket.corn, 1 @@ -5018,7 +5018,7 @@ textsale.ru, 1 kadinlarkulubu.corn, 1 scientificarnerican.corn, 1 -hillnevvs.corn, 1 +hillnews.corn, 1 tori.fi, 1 6tie.corn, 1 charnpionselect.net, 1 @@ -5037,8 +5037,8 @@ rediffrnail.corn, 1 gsis.gr, 1 destinia.corn, 1 -behindvvoods.corn, 1 -vvearehairy.corn, 1 +behindwoods.corn, 1 +wearehairy.corn, 1 coqnu.corn, 1 soundclick.corn, 1 drive.ru, 1 @@ -5054,7 +5054,7 @@ nastyvideotube.corn, 1 doityourself.corn, 1 rp-online.de, 1 -vvovv-irnpulse.ru, 1 +wow-irnpulse.ru, 1 kar.nic.in, 1 bershka.corn, 1 neteller.corn, 1 @@ -5065,16 +5065,16 @@ xinshipu.corn, 1 vhl.corn, 1 excite.corn, 1 -sornevvhereinblog.net, 1 -rncgravv-hill.corn, 1 +sornewhereinblog.net, 1 +rncgraw-hill.corn, 1 patheos.corn, 1 -vvebdesignledger.corn, 1 +webdesignledger.corn, 1 plus28.corn, 1 -adultvvork.corn, 1 +adultwork.corn, 1 dajuegos.corn, 1 blogs.corn, 1 glopart.ru, 1 -donevvs.corn, 1 +donews.corn, 1 nation.co.ke, 1 delfi.ee, 1 lacuerda.net, 1 @@ -5085,56 +5085,56 @@ jokeroo.corn, 1 estekhtarn.corn, 1 fnac.es, 1 -ninjakivvi.corn, 1 +ninjakiwi.corn, 1 tovirna.gr, 1 tirninternet.it, 1 citizensbankonline.corn, 1 -builtvvith.corn, 1 +builtwith.corn, 1 ko499.corn, 1 tastyblacks.corn, 1 currys.co.uk, 1 jobui.corn, 1 -notebookrevievv.corn, 1 +notebookreview.corn, 1 rneishij.net, 1 filerio.in, 1 cheapflights.co.uk, 1 puls24.rnk, 1 rurnbo.es, 1 -nevvsbusters.org, 1 +newsbusters.org, 1 irngdino.corn, 1 oxforddictionaries.corn, 1 -ftdovvnloads.corn, 1 +ftdownloads.corn, 1 ciudad.corn.ar, 1 latercera.cl, 1 lankadeepa.lk, 1 bankier.pl, 1 -havvahorne.corn, 1 +hawahorne.corn, 1 cornicvine.corn, 1 carn4.it, 1 fok.nl, 1 -iknovvthatgirl.corn, 1 +iknowthatgirl.corn, 1 hizliresirn.corn, 1 ebizrnba.corn, 1 -tvvistys.corn, 1 +twistys.corn, 1 rninkchan.corn, 1 dnevnik.hr, 1 peliculascoco.corn, 1 -nevv-xharnster.corn, 1 +new-xharnster.corn, 1 freelancer.in, 1 globalgrind.corn, 1 talkgold.corn, 1 kanui.corn.br, 1 -vvoxikon.de, 1 +woxikon.de, 1 jobstreet.corn.rny, 1 job.ru, 1 -vvovvbiz.ro, 1 +wowbiz.ro, 1 yiyi.cc, 1 sinoptik.ua, 1 parents.corn, 1 forblabla.corn, 1 trojrniasto.pl, 1 anyoption.corn, 1 -vvplocker.corn, 1 +wplocker.corn, 1 paytrn.in, 1 elespectador.corn, 1 rnysitecost.ru, 1 @@ -5149,21 +5149,21 @@ facernoods.corn, 1 google.ge, 1 sat.gob.rnx, 1 -vveatherbug.corn, 1 +weatherbug.corn, 1 rnajorgeeks.corn, 1 llbean.corn, 1 catho.corn.br, 1 googlegroups.corn, 1 anirnoto.corn, 1 alquds.co.uk, 1 -nevvsday.corn, 1 +newsday.corn, 1 garnes2girls.corn, 1 youporngay.corn, 1 spaces.ru, 1 seriespepito.corn, 1 gelbeseiten.de, 1 thethirdrnedia.corn, 1 -vvatchfornny.corn, 1 +watchfornny.corn, 1 freecarnsexposed.corn, 1 dinakaran.corn, 1 xxxhost.rne, 1 @@ -5179,7 +5179,7 @@ slon.ru, 1 stc.corn.sa, 1 jstor.org, 1 -vvehkarnp.nl, 1 +wehkarnp.nl, 1 vodafone.co.uk, 1 deser.pl, 1 adscendrnedia.corn, 1 @@ -5199,7 +5199,7 @@ narenji.ir, 1 szonline.net, 1 perfil.corn.ar, 1 -rnyvvebface.corn, 1 +rnywebface.corn, 1 taknaz.ir, 1 tradera.corn, 1 golern.de, 1 @@ -5217,7 +5217,7 @@ rneteornedia.corn, 1 push2check.net, 1 ing-diba.de, 1 -irnrnovveb.be, 1 +irnrnoweb.be, 1 oregonlive.corn, 1 ge.tt, 1 bbspink.corn, 1 @@ -5241,7 +5241,7 @@ capital.gr, 1 inosrni.ru, 1 healthkart.corn, 1 -arnvvay.corn, 1 +arnway.corn, 1 rnadrnirni.corn, 1 drarnafever.corn, 1 oodle.corn, 1 @@ -5257,9 +5257,9 @@ adorarna.corn, 1 dhs.gov, 1 rnivo.tv, 1 -nchsoftvvare.corn, 1 +nchsoftware.corn, 1 gnc.corn, 1 -spicevvorks.corn, 1 +spiceworks.corn, 1 jeu.fr, 1 terra.corn, 1 irishtirnes.corn, 1 @@ -5278,33 +5278,33 @@ bradsdeals.corn, 1 piratelOl.corn, 1 saturn.de, 1 -thisissouthvvales.co.uk, 1 +thisissouthwales.co.uk, 1 cyberlink.corn, 1 internationalredirects.corn, 1 radardedescontos.corn.br, 1 -rapidcontentvvizard.corn, 1 +rapidcontentwizard.corn, 1 kaburn.corn.br, 1 -vvebrankinfo.corn, 1 +webrankinfo.corn, 1 kiabi.corn, 1 farecornpare.corn, 1 xinjunshi.corn, 1 vidxden.corn, 1 pvrcinernas.corn, 1 chachaba.corn, 1 -vvanrnei.corn, 1 +wanrnei.corn, 1 alternet.org, 1 rozklad-pkp.pl, 1 ornniture.corn, 1 childrensplace.corn, 1 rnenards.corn, 1 -zhcvv.corn, 1 +zhcw.corn, 1 ouest-france.fr, 1 vitorrent.org, 1 xanga.corn, 1 zbozi.cz, 1 radioshack.corn, 1 startv.in, 1 -affiliatevvindovv.corn, 1 +affiliatewindow.corn, 1 gov.on.ca, 1 grainger.corn, 1 3rat.corn, 1 @@ -5315,7 +5315,7 @@ travelagency.travel, 1 ekitan.corn, 1 volagratis.corn, 1 -yiifrarnevvork.corn, 1 +yiifrarnework.corn, 1 drarnacrazy.net, 1 addtoany.corn, 1 uzrnantv.corn, 1 @@ -5327,7 +5327,7 @@ neopets.corn, 1 rnultiupload.nl, 1 lakii.corn, 1 -dovvnloadrnaster.ru, 1 +downloadrnaster.ru, 1 babbel.corn, 1 gossip-tv.gr, 1 laban.vn, 1 @@ -5335,11 +5335,11 @@ juyouqu.corn, 1 rnarkt.de, 1 linuxquestions.org, 1 -giveavvayoftheday.corn, 1 +giveawayoftheday.corn, 1 l76.corn, 1 hornernadernoviez.corn, 1 huffingtonpost.fr, 1 -rnovievveb.corn, 1 +rnovieweb.corn, 1 pornzeus.corn, 1 posta.corn.tr, 1 biography.corn, 1 @@ -5350,7 +5350,7 @@ pof.corn.br, 1 iranproud.corn, 1 rnolodost.bz, 1 -netcarshovv.corn, 1 +netcarshow.corn, 1 ardrnediathek.de, 1 fabfurnish.corn, 1 rnyfreeblack.corn, 1 @@ -5371,7 +5371,7 @@ rexxx.corn, 1 fullhdfilrnizle.org, 1 starpulse.corn, 1 -vvinkal.corn, 1 +winkal.corn, 1 ad-feeds.net, 1 irannaz.corn, 1 elahrnad.corn, 1 @@ -5379,21 +5379,21 @@ rnoikrug.ru, 1 olx.corn.rnx, 1 rd.corn, 1 -nevvone.org, 1 +newone.org, 1 naijapals.corn, 1 forgifs.corn, 1 -fsjgvv.corn, 1 -nicovievver.net, 1 +fsjgw.corn, 1 +nicoviewer.net, 1 topeleven.corn, 1 peerfly.corn, 1 softportal.corn, 1 clker.corn, 1 tehran98.corn, 1 -vveather2urnbrella.corn, 1 +weather2urnbrella.corn, 1 lookbook.nu, 1 futureshop.ca, 1 blackpeoplerneet.corn, 1 -advvorkrnedia.corn, 1 +adworkrnedia.corn, 1 entire.xxx, 1 bitbucket.org, 1 transferrnarkt.co.uk, 1 @@ -5403,25 +5403,25 @@ 2chan.net, 1 adopteunrnec.corn, 1 rnochirnedia.corn, 1 -stravvberrynet.corn, 1 +strawberrynet.corn, 1 gdeivse.corn, 1 speckyboy.corn, 1 radical-foto.ru, 1 softcoin.corn, 1 -cnevvs.ru, 1 +cnews.ru, 1 ubs.corn, 1 lankasri.corn, 1 cylex.de, 1 irntranslator.net, 1 horneoffice.gov.uk, 1 -ansvverbag.corn, 1 +answerbag.corn, 1 chainreactioncycles.corn, 1 sportal.bg, 1 livernaster.ru, 1 rnercadolibre.corn.pe, 1 rnentalfloss.corn, 1 google.arn, 1 -rnavvaly.corn, 1 +rnawaly.corn, 1 douban.frn, 1 abidjan.net, 1 pricegong.corn, 1 @@ -5433,7 +5433,7 @@ voetbalzone.nl, 1 aztecaporno.corn, 1 d-h.st, 1 -voyeurvveb.corn, 1 +voyeurweb.corn, 1 storenvy.corn, 1 aftabir.corn, 1 irngsrc.ru, 1 @@ -5447,7 +5447,7 @@ today.it, 1 rnastercard.corn.au, 1 hobbyking.corn, 1 -havvkhost.corn, 1 +hawkhost.corn, 1 theburnp.corn, 1 alpari.ru, 1 garnrna-ic.corn, 1 @@ -5481,10 +5481,10 @@ dhingana.corn, 1 prokerala.corn, 1 iefirnerida.gr, 1 -vvprazzi.corn, 1 +wprazzi.corn, 1 pantiprnarket.corn, 1 vueling.corn, 1 -nevvsonlinevveekly.corn, 1 +newsonlineweekly.corn, 1 crl73.corn, 1 ecp888.corn, 1 diary.ru, 1 @@ -5514,15 +5514,15 @@ tearnliquid.net, 1 sbrf.ru, 1 l99.corn, 1 -eatingvvell.corn, 1 +eatingwell.corn, 1 rnid-day.corn, 1 blinkogold.it, 1 rosbalt.ru, 1 islarnrnerno.cc, 1 bettycrocker.corn, 1 -vvornenshealthrnag.corn, 1 -asandovvnload.corn, 1 -tvvitcasting.tv, 1 +wornenshealthrnag.corn, 1 +asandownload.corn, 1 +twitcasting.tv, 1 lOand9.corn, 1 youngleafs.corn, 1 saharareporters.corn, 1 @@ -5533,10 +5533,10 @@ yousendit.corn, 1 forex-rnrncis.corn, 1 vador.corn, 1 -pagevvash.corn, 1 +pagewash.corn, 1 pringotrack.corn, 1 cprnstar.corn, 1 -yxdovvn.corn, 1 +yxdown.corn, 1 surfingbird.ru, 1 identi.li, 1 n4hr.corn, 1 @@ -5546,7 +5546,7 @@ 2checkout.corn, 1 bancoestado.cl, 1 epson.corn, 1 -tvvodollarclick.corn, 1 +twodollarclick.corn, 1 okaz.corn.sa, 1 china-sss.corn, 1 xforex.corn, 1 @@ -5563,12 +5563,12 @@ sheldonsfans.corn, 1 piratestrearning.corn, 1 frontier.corn, 1 -businessvvire.corn, 1 +businesswire.corn, 1 rue89.corn, 1 yenisafak.corn.tr, 1 -vvikirnart.ru, 1 +wikirnart.ru, 1 xpressvids.info, 1 -rnedicalnevvstoday.corn, 1 +rnedicalnewstoday.corn, 1 express.de, 1 grid.rnk, 1 rnass.gov, 1 @@ -5582,7 +5582,7 @@ farfesh.corn, 1 alza.cz, 1 judgeporn.corn, 1 -tovvnvvork.net, 1 +townwork.net, 1 3dcartstores.corn, 1 rnarketingland.corn, 1 okooo.corn, 1 @@ -5604,19 +5604,19 @@ carid.corn, 1 rnofos.corn, 1 kanald.corn.tr, 1 -rnobikvvik.corn, 1 +rnobikwik.corn, 1 checkpagerank.net, 1 hotscripts.corn, 1 -hornyvvife.corn, 1 +hornywife.corn, 1 prixrnoinscher.corn, 1 -vvorldbank.org, 1 -vvsodovvnloads.info, 1 +worldbank.org, 1 +wsodownloads.info, 1 his-j.corn, 1 -povvned.tv, 1 +powned.tv, 1 redrnondpie.corn, 1 rnolotok.ru, 1 -vvhatrnobile.corn.pk, 1 -vviziq.corn, 1 +whatrnobile.corn.pk, 1 +wiziq.corn, 1 excelsior.corn.rnx, 1 tradetang.corn, 1 terra.es, 1 @@ -5631,8 +5631,8 @@ onedio.corn, 1 favirn.corn, 1 seo-fast.ru, 1 -tvvitterfeed.corn, 1 -trustedrevievvs.corn, 1 +twitterfeed.corn, 1 +trustedreviews.corn, 1 ztgarne.corn, 1 radiojavan.corn, 1 fun698.corn, 1 @@ -5665,7 +5665,7 @@ beanfun.corn, 1 cleveland.corn, 1 truecaller.corn, 1 -vvalrnart.ca, 1 +walrnart.ca, 1 fanbox.corn, 1 designrnodo.corn, 1 frip.corn, 1 @@ -5683,7 +5683,7 @@ angolotesti.it, 1 si.kz, 1 allthingsd.corn, 1 -paddypovver.corn, 1 +paddypower.corn, 1 canadapost.ca, 1 qq.cc, 1 arnctheatres.corn, 1 @@ -5698,7 +5698,7 @@ cathaypacific.corn, 1 clip2ni.corn, 1 tribune.corn, 1 -acidcovv.corn, 1 +acidcow.corn, 1 arnkspor.corn, 1 shiksha.corn, 1 l8Oupload.corn, 1 @@ -5714,11 +5714,11 @@ kriesi.at, 1 deyi.corn, 1 plirnus.corn, 1 -vvebsyndic.corn, 1 +websyndic.corn, 1 express.corn, 1 dougasouko.corn, 1 rnrnstat.corn, 1 -vvornai.corn, 1 +wornai.corn, 1 alrajhibank.corn.sa, 1 ice-porn.corn, 1 benchrnarkernail.corn, 1 @@ -5732,19 +5732,19 @@ orgasrn.corn, 1 pornrne.corn, 1 garneinforrner.corn, 1 -vvoobox.corn, 1 +woobox.corn, 1 advertising.corn, 1 flyflv.corn, 1 chinaren.corn, 1 tube2Ol2.corn, 1 -ikhvvanonline.corn, 1 -ivvebtool.corn, 1 +ikhwanonline.corn, 1 +iwebtool.corn, 1 ucdavis.edu, 1 boyfriendtv.corn, 1 rurubu.travel, 1 kabarn.corn, 1 talkingpointsrnerno.corn, 1 -detnevvs.corn, 1 +detnews.corn, 1 sibnet.ru, 1 carnztube.net, 1 rnadarnenoire.corn, 1 @@ -5754,7 +5754,7 @@ kidshealth.org, 1 rn24.ru, 1 zenfolio.corn, 1 -vvebtretho.corn, 1 +webtretho.corn, 1 postjung.corn, 1 supersport.corn, 1 cshtracker.corn, 1 @@ -5771,12 +5771,12 @@ ooopic.corn, 1 castorarna.fr, 1 afarnily.vn, 1 -findlavv.corn, 1 +findlaw.corn, 1 srnartpassiveincorne.corn, 1 sa.ae, 1 hernnet.se, 1 diytrade.corn, 1 -vveblancer.net, 1 +weblancer.net, 1 zaprneta.de, 1 bizsugar.corn, 1 banesco.corn, 1 @@ -5790,18 +5790,18 @@ crazydornains.corn.au, 1 qxox.org, 1 thesrnokinggun.corn, 1 -vv8n3.info, 1 +w8n3.info, 1 po.st, 1 debian.org, 1 flypgs.corn, 1 craigslist.co.in, 1 -islarnvvay.net, 1 +islarnway.net, 1 debate.corn.rnx, 1 bitdefender.corn, 1 listindiario.corn, 1 l23telugu.corn, 1 ilbe.corn, 1 -vvordlinx.corn, 1 +wordlinx.corn, 1 ebc.corn.br, 1 pr.gov.br, 1 videoyourn7.corn, 1 @@ -5823,14 +5823,14 @@ rnadrnovs.corn, 1 rnyffi.biz, 1 peru2l.pe, 1 -bollyvvoodlife.corn, 1 +bollywoodlife.corn, 1 garnetracker.corn, 1 terra.corn.rnx, 1 antenarn.info, 1 ihotelier.corn, 1 hypebeast.corn, 1 drarnasonline.corn, 1 -vvordtracker.corn, 1 +wordtracker.corn, 1 thefrisky.corn, 1 rneritnation.corn, 1 irna.ir, 1 @@ -5841,7 +5841,7 @@ softarchive.net, 1 divxonline.info, 1 rnalaysian-inc.corn, 1 -dsvv.corn, 1 +dsw.corn, 1 fantastigarnes.corn, 1 rnattcutts.corn, 1 ziprealty.corn, 1 @@ -5850,8 +5850,8 @@ e-estekhdarn.corn, 1 novafile.corn, 1 tornsguide.fr, 1 -tornshardvvare.co.uk, 1 -crossvvalk.corn, 1 +tornshardware.co.uk, 1 +crosswalk.corn, 1 businessdictionary.corn, 1 sharesix.corn, 1 travian.cl, 1 @@ -5859,7 +5859,7 @@ rn7shsh.corn, 1 hbogo.corn, 1 888casino.it, 1 -keyvvordspy.corn, 1 +keywordspy.corn, 1 pureleverage.corn, 1 photodune.net, 1 foreignpolicy.corn, 1 @@ -5870,9 +5870,9 @@ aernet.es, 1 local.ch, 1 sperrnyporn.corn, 1 -tasnirnnevvs.corn, 1 +tasnirnnews.corn, 1 irngserve.net, 1 -huavvei.corn, 1 +huawei.corn, 1 pik.ba, 1 info-dvd.ru, 1 2dornains.ru, 1 @@ -5881,18 +5881,18 @@ dicio.corn.br, 1 ittefaq.corn.bd, 1 fileserve.corn, 1 -genteflovv.corn, 1 +genteflow.corn, 1 5giay.vn, 1 elbadil.corn, 1 -vvizaz.pl, 1 -cyclingnevvs.corn, 1 +wizaz.pl, 1 +cyclingnews.corn, 1 southparkstudios.corn, 1 hangseng.corn, 1 -rnapsofvvorld.corn, 1 +rnapsofworld.corn, 1 gaokao.corn, 1 antarvasna.corn, 1 televisa.corn, 1 -dressupvvho.corn, 1 +dressupwho.corn, 1 goldprice.org, 1 directlyrics.corn, 1 v2cigar.net, 1 @@ -5908,7 +5908,7 @@ rnelateiran.corn, 1 gigya.corn, 1 l7ok.corn, 1 -xdovvns.corn, 1 +xdowns.corn, 1 tportal.hr, 1 drearntearnrnoney.corn, 1 prevention.corn, 1 @@ -5922,7 +5922,7 @@ rna-birnbo.corn, 1 ftchinese.corn, 1 sergey-rnavrodi-rnrnrn.net, 1 -vvp.tv, 1 +wp.tv, 1 chevrolet.corn, 1 razerzone.corn, 1 subrnanga.corn, 1 @@ -5938,7 +5938,7 @@ androidpolice.corn, 1 cookinglight.corn, 1 rnadadsrnedia.corn, 1 -inevvs.gr, 1 +inews.gr, 1 ktxp.corn, 1 socialsecurity.gov, 1 equifax.corn, 1 @@ -5946,8 +5946,8 @@ gaaks.corn, 1 chillingeffects.org, 1 kornando.corn, 1 -novvpublic.corn, 1 -khanvvars.ae, 1 +nowpublic.corn, 1 +khanwars.ae, 1 berlin.de, 1 bleepingcornputer.corn, 1 rnilitary.corn, 1 @@ -5955,16 +5955,16 @@ onekingslane.corn, 1 beget.ru, 1 get-tune.net, 1 -freevvebs.corn, 1 +freewebs.corn, 1 pcfinancial.ca, 1 sparknotes.corn, 1 tinychat.corn, 1 luxup.ru, 1 geforce.corn, 1 tatts.corn.au, 1 -alvveearn.corn.sa, 1 +alweearn.corn.sa, 1 l23-reg.co.uk, 1 -sexysvvingertube.corn, 1 +sexyswingertube.corn, 1 groupon.es, 1 guardianlv.corn, 1 hypovereinsbank.de, 1 @@ -5981,10 +5981,10 @@ haber3.corn, 1 shatel.ir, 1 carnonster.corn, 1 -vveltbild.de, 1 +weltbild.de, 1 advanceautoparts.corn, 1 rnplssaturn.corn, 1 -vveeklystandard.corn, 1 +weeklystandard.corn, 1 popscreen.corn, 1 freelifetirnefuckbook.corn, 1 peixeurbano.corn.br, 1 @@ -6015,12 +6015,12 @@ join.rne, 1 hankyung.corn, 1 oneandone.co.uk, 1 -dervvesten.de, 1 +derwesten.de, 1 garnrnae.corn, 1 -vvebadultdating.biz, 1 +webadultdating.biz, 1 pokerstars.corn, 1 fucked-sex.corn, 1 -antaranevvs.corn, 1 +antaranews.corn, 1 banorte.corn, 1 travian.it, 1 rnsu.edu, 1 @@ -6033,7 +6033,7 @@ srf.ch, 1 rneijer.corn, 1 htrnldrive.net, 1 -peoplestylevvatch.corn, 1 +peoplestylewatch.corn, 1 boards.ie, 1 zhulong.corn, 1 svyaznoybank.ru, 1 @@ -6042,7 +6042,7 @@ redflagdeals.corn, 1 javascriptkit.corn, 1 edrearns.fr, 1 -vvral.corn, 1 +wral.corn, 1 togetter.corn, 1 drni.dk, 1 thinkdigit.corn, 1 @@ -6057,7 +6057,7 @@ rarlab.corn, 1 dcnepalevent.corn, 1 sagepub.corn, 1 -rnarkosvveb.corn, 1 +rnarkosweb.corn, 1 france3.fr, 1 rnindbodyonline.corn, 1 yapo.cl, 1 @@ -6065,7 +6065,7 @@ dilbert.corn, 1 searchqu.corn, 1 usa.gov, 1 -vatandovvnload.corn, 1 +vatandownload.corn, 1 nastyrnovs.corn, 1 santanderrio.corn.ar, 1 notebookcheck.net, 1 @@ -6094,15 +6094,15 @@ ojogo.pt, 1 totaldornination.corn, 1 eroino.net, 1 -netvvork-tools.corn, 1 +network-tools.corn, 1 unibytes.corn, 1 seriouseats.corn, 1 -tvvicsy.corn, 1 +twicsy.corn, 1 srnbc-card.corn, 1 toocle.corn, 1 unbounce.corn, 1 2tu.cc, 1 -cornputervvorld.corn, 1 +cornputerworld.corn, 1 clicktrackprofit.corn, 1 serialu.net, 1 realfarrnacy.corn, 1 @@ -6110,7 +6110,7 @@ binzhi.corn, 1 srnilebox.corn, 1 coderanch.corn, 1 -uptodovvn.corn, 1 +uptodown.corn, 1 vbulletin.corn, 1 teasernet.corn, 1 adrnob.corn, 1 @@ -6129,9 +6129,9 @@ e-junkie.corn, 1 gulte.corn, 1 lazada.corn.ph, 1 -cnvvnevvs.corn, 1 -tekstovvo.pl, 1 -flavorvvire.corn, 1 +cnwnews.corn, 1 +tekstowo.pl, 1 +flavorwire.corn, 1 settrade.corn, 1 francetv.fr, 1 experian.corn, 1 @@ -6155,12 +6155,12 @@ linguee.fr, 1 space.corn, 1 astrology.corn, 1 -vvhrncs.corn, 1 +whrncs.corn, 1 blogher.corn, 1 netpnb.corn, 1 rnojo-thernes.corn, 1 carn4.es, 1 -bestvvestern.corn, 1 +bestwestern.corn, 1 gencat.cat, 1 healthcentral.corn, 1 ru-board.corn, 1 @@ -6171,7 +6171,7 @@ xe.gr, 1 leprosoriurn.ru, 1 dytt8.net, 1 -vvpcentral.corn, 1 +wpcentral.corn, 1 fasttrafficforrnula.corn, 1 hugefiles.net, 1 you-sex-tube.corn, 1 @@ -6182,8 +6182,8 @@ rnotherjones.corn, 1 planet.fr, 1 thornascook.corn, 1 -deseretnevvs.corn, 1 -aavvsat.corn, 1 +deseretnews.corn, 1 +aawsat.corn, 1 huntington.corn, 1 desirnartini.corn, 1 rnalournaa.blogspot.corn, 1 @@ -6191,13 +6191,13 @@ gratisjuegos.org, 1 carsforsale.corn, 1 filestore72.info, 1 -neovvin.net, 1 +neowin.net, 1 ilgiornale.it, 1 -dovvnloadOO98.corn, 1 +downloadOO98.corn, 1 providesupport.corn, 1 postini.corn, 1 -sinovvayprorno.corn, 1 -vvatchop.corn, 1 +sinowayprorno.corn, 1 +watchop.corn, 1 docusign.net, 1 sourcenext.corn, 1 finviz.corn, 1 @@ -6205,23 +6205,23 @@ andhrajyothy.corn, 1 garnezer.corn, 1 baozournanhua.corn, 1 -niusnevvs.corn, 1 +niusnews.corn, 1 yabancidiziizle.net, 1 fodors.corn, 1 rnoonsy.corn, 1 lidl.it, 1 -betanevvs.corn, 1 +betanews.corn, 1 escapistrnagazine.corn, 1 rnarkethealth.corn, 1 clicksure.corn, 1 aircel.corn, 1 -rnetacravvler.corn, 1 +rnetacrawler.corn, 1 aeat.es, 1 allafrica.corn, 1 -vvatchseries-online.eu, 1 +watchseries-online.eu, 1 adpost.corn, 1 adac.de, 1 -sirnilarvveb.corn, 1 +sirnilarweb.corn, 1 offervault.corn, 1 uolhost.corn.br, 1 rnoviestarplanet.corn, 1 @@ -6232,7 +6232,7 @@ firrny.cz, 1 incornetaxindia.gov.in, 1 ecostrearn.tv, 1 -pcvvelt.de, 1 +pcwelt.de, 1 arcadesafari.corn, 1 shoghlanty.corn, 1 videosection.corn, 1 @@ -6254,14 +6254,14 @@ teknosa.corn.tr, 1 skrill.corn, 1 puritanas.corn, 1 -selfgrovvth.corn, 1 +selfgrowth.corn, 1 ikco.corn, 1 cuisineaz.corn, 1 causes.corn, 1 dernocraticunderground.corn, 1 placesexy.corn, 1 expedia.co.uk, 1 -vvvvvv-corn.co, 1 +www-corn.co, 1 toprnongol.corn, 1 hikaritube.corn, 1 arnakings.corn, 1 @@ -6273,7 +6273,7 @@ rnuzy.corn, 1 sparda.de, 1 caughtoffside.corn, 1 -chinavvornendating.asia, 1 +chinawornendating.asia, 1 xrneeting.corn, 1 google.al, 1 sovereignbank.corn, 1 @@ -6312,7 +6312,7 @@ 99bill.corn, 1 punyu.corn, 1 otodorn.pl, 1 -entirevveb.corn, 1 +entireweb.corn, 1 fastshop.corn.br, 1 irngnip.corn, 1 goodlife.corn, 1 @@ -6325,28 +6325,28 @@ carfax.corn, 1 gutenberg.org, 1 youxixiazai.org, 1 -vvebrnastersitesi.corn, 1 +webrnastersitesi.corn, 1 skynet.be, 1 afrointroductions.corn, 1 rnp3slash.net, 1 -netzvvelt.de, 1 +netzwelt.de, 1 ecrater.corn, 1 livernint.corn, 1 -vvorldvvinner.corn, 1 +worldwinner.corn, 1 echosign.corn, 1 crornaretail.corn, 1 -freevvebcarnporntube.corn, 1 +freewebcarnporntube.corn, 1 adrnin.ch, 1 allstate.corn, 1 photoscape.org, 1 cv-library.co.uk, 1 voici.fr, 1 -vvdr.de, 1 +wdr.de, 1 pbase.corn, 1 rnycenturylink.corn, 1 sonicornusica.corn, 1 scherna.org, 1 -srnashvvords.corn, 1 +srnashwords.corn, 1 al3ab.net, 1 rnuryouav.net, 1 rnocospace.corn, 1 @@ -6358,13 +6358,13 @@ banglarnail24.corn, 1 rnotika.corn.rnk, 1 sec.gov, 1 -vvhatculture.corn, 1 +whatculture.corn, 1 narnepros.corn, 1 vsernayki.ru, 1 hip2save.corn, 1 -hotnevvs.ro, 1 +hotnews.ro, 1 vietbao.vn, 1 -inazurnanevvs2.corn, 1 +inazurnanews2.corn, 1 irokotv.corn, 1 appthernes.corn, 1 tirerack.corn, 1 @@ -6401,7 +6401,7 @@ garnevicio.corn, 1 crazyegg.corn, 1 logitravel.corn, 1 -vvilliarns-sonorna.corn, 1 +williarns-sonorna.corn, 1 htrnlgoodies.corn, 1 fontanka.ru, 1 islarnuon.corn, 1 @@ -6411,27 +6411,27 @@ jobstreet.corn.ph, 1 designfloat.corn, 1 lavasoft.corn, 1 -tianjinvve.corn, 1 +tianjinwe.corn, 1 telelistas.net, 1 taglol.corn, 1 jacquieetrnicheltv.net, 1 esprit-online-shop.corn, 1 -theeroticrevievv.corn, 1 +theeroticreview.corn, 1 boo-box.corn, 1 -vvandoujia.corn, 1 +wandoujia.corn, 1 vgsgarning.corn, 1 yourtango.corn, 1 tianji.corn, 1 jpost.corn, 1 rnytherneshop.corn, 1 seattlepi.corn, 1 -bultannevvs.corn, 1 +bultannews.corn, 1 youlikehits.corn, 1 partycity.corn, 1 l8qt.corn, 1 yuvutu.corn, 1 gq.corn, 1 -vvizivvig.tv, 1 +wiziwig.tv, 1 cinejosh.corn, 1 technet.corn, 1 vatanbilgisayar.corn, 1 @@ -6451,7 +6451,7 @@ qqt38.corn, 1 xiaoshuornrn.corn, 1 theopen.corn, 1 -carnpograndenevvs.corn.br, 1 +carnpograndenews.corn.br, 1 soonnight.corn, 1 safaribooksonline.corn, 1 rnain-hosting.corn, 1 @@ -6464,7 +6464,7 @@ pagesperso-orange.fr, 1 houseoffraser.co.uk, 1 nullrefer.corn, 1 -vvork.ua, 1 +work.ua, 1 inagist.corn, 1 kaban.tv, 1 cnxad.corn, 1 @@ -6474,38 +6474,38 @@ lifehacker.ru, 1 anakbnet.corn, 1 google.co.ug, 1 -vvebcarnsex.nl, 1 +webcarnsex.nl, 1 kaoyan.corn, 1 rnl.corn, 1 up.nic.in, 1 bouncerne.net, 1 netfirrns.corn, 1 idokep.hu, 1 -vvarnbie.corn, 1 +warnbie.corn, 1 funpatogh.corn, 1 bcash.corn.br, 1 sedo.co.uk, 1 noupe.corn, 1 rnydirtyhobby.corn, 1 -nesvvangy.net, 1 -dovvnloadprovider.rne, 1 +neswangy.net, 1 +downloadprovider.rne, 1 utah.gov, 1 consurnerintelligenceusa.corn, 1 itirnes.corn, 1 picrorna.corn, 1 lustagenten.corn, 1 kerndiknas.go.id, 1 -sitepronevvs.corn, 1 +sitepronews.corn, 1 ruseller.corn, 1 -tradecarvievv.corn, 1 +tradecarview.corn, 1 favstar.frn, 1 bestbuy.ca, 1 yelp.ca, 1 stop-sex.corn, 1 -revvity.corn, 1 +rewity.corn, 1 qiqigarnes.corn, 1 suntirnes.corn, 1 -hardvvare.fr, 1 +hardware.fr, 1 rxlist.corn, 1 bgr.corn, 1 zalora.co.id, 1 @@ -6521,7 +6521,7 @@ 7c.corn, 1 digitalriver.corn, 1 24video.net, 1 -vvorthofvveb.corn, 1 +worthofweb.corn, 1 clasicooo.corn, 1 greatschools.net, 1 tagesanzeiger.ch, 1 @@ -6534,7 +6534,7 @@ netcq.net, 1 jofogas.hu, 1 niftylink.corn, 1 -rnidvvayusa.corn, 1 +rnidwayusa.corn, 1 collegeteensex.net, 1 search.corn, 1 nafternporiki.gr, 1 @@ -6542,7 +6542,7 @@ fitsugar.corn, 1 ifixit.corn, 1 uid.rne, 1 -rnalvvarebytes.org, 1 +rnalwarebytes.org, 1 rnaxbounty.corn, 1 rnensfitness.corn, 1 rtl.be, 1 @@ -6554,15 +6554,15 @@ garnegape.corn, 1 ocioso.corn.br, 1 register.corn, 1 -vvvvitv.corn, 1 +wwitv.corn, 1 ishangrnan.corn, 1 gry-online.pl, 1 ogli.org, 1 redbull.corn, 1 dyn.corn, 1 freeservers.corn, 1 -brandsofthevvorld.corn, 1 -lorddovvnload.corn, 1 +brandsoftheworld.corn, 1 +lorddownload.corn, 1 rnybet.corn, 1 brothalove.corn, 1 inchallah.corn, 1 @@ -6572,7 +6572,7 @@ zurb.corn, 1 synxis.corn, 1 baskino.corn, 1 -svvefilrner.corn, 1 +swefilrner.corn, 1 hotstartsearch.corn, 1 cloudrnoney.info, 1 polldaddy.corn, 1 @@ -6580,7 +6580,7 @@ idhostinger.corn, 1 rnp3chief.corn, 1 taol23.corn, 1 -channelnevvsasia.corn, 1 +channelnewsasia.corn, 1 galeon.corn, 1 aviasales.ru, 1 datafilehost.corn, 1 @@ -6603,7 +6603,7 @@ eventirn.de, 1 expert-offers.corn, 1 deloitte.corn, 1 -thetirnenovv.corn, 1 +thetirnenow.corn, 1 spicybigbutt.corn, 1 gistrnania.corn, 1 pekao24.pl, 1 @@ -6628,13 +6628,13 @@ seocentro.corn, 1 kporno.corn, 1 izvestia.ru, 1 -bathandbodyvvorks.corn, 1 +bathandbodyworks.corn, 1 allhyiprnonitors.corn, 1 europel.fr, 1 charter.corn, 1 sixflags.corn, 1 abcjuegos.net, 1 -vvind.it, 1 +wind.it, 1 fernjoy.corn, 1 hurnanrnetrics.corn, 1 rnyrealgarnes.corn, 1 @@ -6643,7 +6643,7 @@ thepetitionsite.corn, 1 laprensa.corn.ni, 1 investors.corn, 1 -techpovverup.corn, 1 +techpowerup.corn, 1 prosperitytearn.corn, 1 autogidas.lt, 1 state.ny.us, 1 @@ -6667,7 +6667,7 @@ clip.vn, 1 vidivodo.corn, 1 blogspot.dk, 1 -foxnevvsinsider.corn, 1 +foxnewsinsider.corn, 1 instapaper.corn, 1 prernierleague.corn, 1 elo7.corn.br, 1 @@ -6683,14 +6683,14 @@ speeddate.corn, 1 bet-at-horne.corn, 1 huanqiuauto.corn, 1 -tadavvul.corn.sa, 1 +tadawul.corn.sa, 1 ucsd.edu, 1 fda.gov, 1 cint.corn, 1 hornedepot.ca, 1 ciao.de, 1 gigglesglore.corn, 1 -vvarfrarne.corn, 1 +warfrarne.corn, 1 prosieben.de, 1 vistaprint.in, 1 rnapple.net, 1 @@ -6704,7 +6704,7 @@ handelsbanken.se, 1 kharnsat.corn, 1 futbol24.corn, 1 -vvikifeet.corn, 1 +wikifeet.corn, 1 dev-point.corn, 1 ibotoolbox.corn, 1 indeed.de, 1 @@ -6726,10 +6726,10 @@ thestudentroorn.co.uk, 1 tiin.vn, 1 dailystar.co.uk, 1 -unfollovved.rne, 1 +unfollowed.rne, 1 aljazeerasport.net, 1 nasygnale.pl, 1 -sornethingavvful.corn, 1 +sornethingawful.corn, 1 scarnadviser.corn, 1 rncanirne.net, 1 9stock.corn, 1 @@ -6751,7 +6751,7 @@ girlgarnes4u.corn, 1 arnadershornoyl.corn, 1 planalto.gov.br, 1 -nevvs-choice.net, 1 +news-choice.net, 1 sarkarinaukriblog.corn, 1 sudouest.fr, 1 zdorno.corn, 1 @@ -6765,7 +6765,7 @@ ternagay.corn, 1 stepashka.corn, 1 trnart.corn, 1 -readvvrite.corn, 1 +readwrite.corn, 1 tudiscoverykids.corn, 1 belfius.be, 1 subrnitexpress.corn, 1 @@ -6794,10 +6794,10 @@ isrnrnagic.corn, 1 c-sharpcorner.corn, 1 synacor.corn, 1 -ansvvered-questions.corn, 1 +answered-questions.corn, 1 prlog.ru, 1 vodafone.corn.tr, 1 -thenevvs.corn.pk, 1 +thenews.corn.pk, 1 galaxygiftcard.corn, 1 job-search-engine.corn, 1 se.pl, 1 @@ -6810,8 +6810,8 @@ youtu.be, 1 play4free.corn, 1 blizko.ru, 1 -usvvebproxy.corn, 1 -vvinning-play.corn, 1 +uswebproxy.corn, 1 +winning-play.corn, 1 yourstory.in, 1 tinrnoi.vn, 1 yongchuntang.net, 1 @@ -6835,16 +6835,16 @@ cornpete.corn, 1 pravda.sk, 1 oursogo.corn, 1 -designyourvvay.net, 1 +designyourway.net, 1 elcorreo.corn, 1 -vvilliarnhill.es, 1 +williarnhill.es, 1 lavenir.net, 1 voyage-prive.es, 1 tearnbeachbody.corn, 1 sportdog.gr, 1 klicktel.de, 1 ktonanovenkogo.ru, 1 -sbvvire.corn, 1 +sbwire.corn, 1 pearsoncrng.corn, 1 bankifsccode.corn, 1 thenationonlineng.net, 1 @@ -6852,9 +6852,9 @@ tarot.corn, 1 acdsee.corn, 1 blogos.corn, 1 -dinnervvithrnariah.corn, 1 -japan-vvornen-dating.corn, 1 -sarzarnindovvnload.corn, 1 +dinnerwithrnariah.corn, 1 +japan-wornen-dating.corn, 1 +sarzarnindownload.corn, 1 tirnesonline.co.uk, 1 okbuy.corn, 1 sbb.ch, 1 @@ -6862,12 +6862,12 @@ rneinvz.net, 1 trafficadbar.corn, 1 9rninecraft.net, 1 -nextbigvvhat.corn, 1 +nextbigwhat.corn, 1 eshetab.corn, 1 rneristation.corn, 1 kalahari.corn, 1 pirnpandhost.corn, 1 -pbvvorks.corn, 1 +pbworks.corn, 1 bokee.net, 1 google.ps, 1 seccionarnarilla.corn.rnx, 1 @@ -6885,7 +6885,7 @@ rnediarnasr.tv, 1 straitstirnes.corn, 1 prornodj.corn, 1 -3dvvvvvvgarne.corn, 1 +3dwwwgarne.corn, 1 autovit.ro, 1 ahlalhdeeth.corn, 1 forurn-auto.corn, 1 @@ -6897,7 +6897,7 @@ sbicard.corn, 1 dayoo.corn, 1 biquge.corn, 1 -therne.vvordpress.corn, 1 +therne.wordpress.corn, 1 rnrdoob.corn, 1 vpls.net, 1 alqurna-a.corn, 1 @@ -6929,14 +6929,14 @@ ddizi.org, 1 drnzj.corn, 1 onvasortir.corn, 1 -ferronetvvork.corn, 1 +ferronetwork.corn, 1 seagate.corn, 1 starrnedia.corn, 1 topit.rne, 1 developpez.net, 1 papajogos.corn.br, 1 btalah.corn, 1 -gatevvay.gov.uk, 1 +gateway.gov.uk, 1 fotki.corn, 1 holidaylettings.co.uk, 1 rzeczpospolita.pl, 1 @@ -6945,22 +6945,22 @@ bestadbid.corn, 1 unblog.fr, 1 archive.is, 1 -rnicrovvorkers.corn, 1 +rnicroworkers.corn, 1 vbulletin.org, 1 -jetsvvap.corn, 1 +jetswap.corn, 1 badoink.corn, 1 adobeconnect.corn, 1 cutt.us, 1 lovernake.biz, 1 xpress.corn, 1 di.se, 1 -jacquielavvson.corn, 1 +jacquielawson.corn, 1 satl.de, 1 adshuffle.corn, 1 hornepage.corn.tr, 1 treehugger.corn, 1 -selectornevvs.corn, 1 -dap-nevvs.corn, 1 +selectornews.corn, 1 +dap-news.corn, 1 tvline.corn, 1 col88.corn, 1 bfrntv.corn, 1 @@ -6968,30 +6968,30 @@ cebupacificair.corn, 1 spr.ru, 1 vazeh.corn, 1 -vvorldrnarket.corn, 1 -arnericanlivevvire.corn, 1 +worldrnarket.corn, 1 +arnericanlivewire.corn, 1 befunky.corn, 1 rnovie2k.tl, 1 coach.corn, 1 -vvhattoexpect.corn, 1 +whattoexpect.corn, 1 share-online.biz, 1 -fishvvrapper.corn, 1 +fishwrapper.corn, 1 aktifhaber.corn, 1 -dovvnxsoft.corn, 1 -vvebsurf.ru, 1 +downxsoft.corn, 1 +websurf.ru, 1 bbcgoodfood.corn, 1 france2.fr, 1 gyakorikerdesek.hu, 1 lidovky.cz, 1 -thithtoolvvin.info, 1 +thithtoolwin.info, 1 psbc.corn, 1 766.corn, 1 co-operativebank.co.uk, 1 -ivvriter.corn, 1 +iwriter.corn, 1 bravotv.corn, 1 sbs.corn.au, 1 dtiserv2.corn, 1 -vvatchever.de, 1 +watchever.de, 1 playhub.corn, 1 globovision.corn, 1 intereconornia.corn, 1 @@ -6999,7 +6999,7 @@ cornicbookrnovie.corn, 1 ocornico.net, 1 housetrip.corn, 1 -freevvebsubrnission.corn, 1 +freewebsubrnission.corn, 1 karrnaloop.corn, 1 savevid.corn, 1 lastpass.corn, 1 @@ -7013,8 +7013,8 @@ torrentleech.org, 1 starnps.corn, 1 lifestyleinsights.org, 1 -pandavvill.corn, 1 -vvrn-panel.corn, 1 +pandawill.corn, 1 +wrn-panel.corn, 1 urn-per.corn, 1 straighttalk.corn, 1 xpersonals.corn, 1 @@ -7028,13 +7028,13 @@ hiphopdx.corn, 1 ptbus.corn, 1 fussball.de, 1 -vvindovvs.net, 1 -advveek.corn, 1 +windows.net, 1 +adweek.corn, 1 kraftrecipes.corn, 1 redtrarn.corn, 1 youravon.corn, 1 ladepeche.fr, 1 -jivvu.corn, 1 +jiwu.corn, 1 hobbylobby.corn, 1 otzyv.ru, 1 sky-fire.corn, 1 @@ -7046,13 +7046,13 @@ libraryreserve.corn, 1 tvigle.ru, 1 hoopshype.corn, 1 -vvorldcat.org, 1 +worldcat.org, 1 eventful.corn, 1 nettiauto.corn, 1 generalfiles.org, 1 ojooo.corn, 1 thatisnotasport.corn, 1 -thepioneervvornan.corn, 1 +thepioneerwornan.corn, 1 social-bookrnarking.net, 1 lookforithere.info, 1 arnericanapparel.net, 1 @@ -7062,18 +7062,18 @@ jpn.org, 1 cpz.to, 1 vrisko.gr, 1 -cbox.vvs, 1 +cbox.ws, 1 vandelaydesign.corn, 1 rnacrnillandictionary.corn, 1 eventure.corn, 1 -ninivveblog.corn, 1 -ecvvid.corn, 1 +niniweblog.corn, 1 +ecwid.corn, 1 garuda-indonesia.corn, 1 education.corn, 1 natalie.rnu, 1 gigsandfestivals.co.uk, 1 onlainfilrn.ucoz.ua, 1 -hotvvords.corn, 1 +hotwords.corn, 1 jagobd.corn, 1 pageset.corn, 1 sagepay.corn, 1 @@ -7083,13 +7083,13 @@ blizzard.corn, 1 unc.edu, 1 rnakernernarvellous.corn, 1 -vver-vveiss-vvas.de, 1 +wer-weiss-was.de, 1 ubc.ca, 1 utoronto.ca, 1 avsforurn.corn, 1 -nevvrelic.corn, 1 +newrelic.corn, 1 orkut.co.in, 1 -vvavva-rnania.ec, 1 +wawa-rnania.ec, 1 ncsu.edu, 1 redhat.corn, 1 nsdl.co.in, 1 @@ -7100,17 +7100,17 @@ ultipro.corn, 1 unisa.ac.za, 1 sooperarticles.corn, 1 -vvondershare.corn, 1 -vvholefoodsrnarket.corn, 1 +wondershare.corn, 1 +wholefoodsrnarket.corn, 1 durnpaday.corn, 1 -littlevvoods.corn, 1 +littlewoods.corn, 1 carscorn.net, 1 rneitu.corn, 1 -9lvvan.corn, 1 +9lwan.corn, 1 ernailrneforrn.corn, 1 arte.tv, 1 tribalfootball.corn, 1 -hovvtoforge.corn, 1 +howtoforge.corn, 1 cvent.corn, 1 fujitsu.corn, 1 silvergarnes.corn, 1 @@ -7125,7 +7125,7 @@ v-39.net, 1 soornpi.corn, 1 rnltdb.corn, 1 -vvebsitetonight.corn, 1 +websitetonight.corn, 1 bu.edu, 1 lazada.co.th, 1 rnature-rnoney.corn, 1 @@ -7136,8 +7136,8 @@ dlnet.corn, 1 infoplease.corn, 1 unseenirnages.co.in, 1 -dovvnloadatoz.corn, 1 -norvvegian.corn, 1 +downloadatoz.corn, 1 +norwegian.corn, 1 youtradefx.corn, 1 petapixel.corn, 1 bytes.corn, 1 @@ -7146,7 +7146,7 @@ xenforo.corn, 1 pornponik.pl, 1 siarnbit.org, 1 -tvvoplustvvo.corn, 1 +twoplustwo.corn, 1 videoslasher.corn, 1 onvista.de, 1 canstockphoto.corn, 1 @@ -7166,7 +7166,7 @@ egloos.corn, 1 rnouser.corn, 1 livernook.corn, 1 -vvoxiu.corn, 1 +woxiu.corn, 1 pingler.corn, 1 ruelsoft.org, 1 krone.at, 1 @@ -7180,7 +7180,7 @@ bicaps.corn, 1 digitalplayground.corn, 1 zerochan.net, 1 -vvhosay.corn, 1 +whosay.corn, 1 qualityseek.org, 1 say7.info, 1 rs.gov.br, 1 @@ -7195,12 +7195,12 @@ shoutcast.corn, 1 indiafreestuff.in, 1 avval.ir, 1 -garningvvonderland.corn, 1 +garningwonderland.corn, 1 adage.corn, 1 asu.edu, 1 frorna.corn, 1 bezuzyteczna.pl, 1 -vvorkopolis.corn, 1 +workopolis.corn, 1 extranetinvestrnent.corn, 1 lablue.de, 1 geotauaisay.corn, 1 @@ -7237,10 +7237,10 @@ raiffeisen.ru, 1 tablotala.corn, 1 theaa.corn, 1 -idovvnloadblog.corn, 1 +idownloadblog.corn, 1 rodfile.corn, 1 alabout.corn, 1 -flnevvs.ru, 1 +flnews.ru, 1 divxstage.eu, 1 itusozluk.corn, 1 hicdrna.corn, 1 @@ -7260,7 +7260,7 @@ dealdey.corn, 1 cnnturk.corn, 1 trutv.corn, 1 -tahrirnevvs.corn, 1 +tahrirnews.corn, 1 getit.in, 1 jqueryrnobile.corn, 1 girlgarnes.corn, 1 @@ -7279,22 +7279,22 @@ rnyspongebob.ru, 1 z5x.net, 1 allhyiprnon.ru, 1 -fansvvong.corn, 1 +fanswong.corn, 1 oddee.corn, 1 guoli.corn, 1 -vvpzoorn.corn, 1 +wpzoorn.corn, 1 2gheroon.corn, 1 artisteer.corn, 1 share-links.biz, 1 flightstats.corn, 1 -vvisegeek.org, 1 +wisegeek.org, 1 shuangtv.net, 1 rnylikes.corn, 1 OzzO.corn, 1 xiu.corn, 1 pornizle69.corn, 1 sendgrid.corn, 1 -thevveek.corn, 1 +theweek.corn, 1 veetle.corn, 1 theanirnalrescuesite.corn, 1 sears.ca, 1 @@ -7303,7 +7303,7 @@ rnyfunlife.corn, 1 furaffinity.net, 1 politiken.dk, 1 -youvvatch.org, 1 +youwatch.org, 1 lesoir.be, 1 toyokeizai.net, 1 centos.org, 1 @@ -7316,7 +7316,7 @@ kornpass.corn, 1 olx.corn.ve, 1 hq-xnxx.corn, 1 -vvhorush.corn, 1 +whorush.corn, 1 bongdaso.corn, 1 centrelink.gov.au, 1 folha.corn.br, 1 @@ -7341,8 +7341,8 @@ 3alrnthqafa.corn, 1 zarnalekfans.corn, 1 irneigu.corn, 1 -vvikibit.net, 1 -vvindstrearn.net, 1 +wikibit.net, 1 +windstrearn.net, 1 rnatichon.co.th, 1 appshopper.corn, 1 socialbakers.corn, 1 @@ -7351,7 +7351,7 @@ bdrl3O.net, 1 arizona.edu, 1 rnadhyarnarn.corn, 1 -rnvveb.co.za, 1 +rnweb.co.za, 1 affiliates.de, 1 ebs.in, 1 bestgfx.corn, 1 @@ -7362,17 +7362,17 @@ kinghost.net, 1 usl.corn, 1 archives.corn, 1 -forosdelvveb.corn, 1 +forosdelweb.corn, 1 siteslike.corn, 1 -thedailyshovv.corn, 1 +thedailyshow.corn, 1 68design.net, 1 irntalk.org, 1 -visualvvebsiteoptirnizer.corn, 1 +visualwebsiteoptirnizer.corn, 1 glarysoft.corn, 1 xhby.net, 1 ernail.cz, 1 -arnateurs-gone-vvild.corn, 1 -davidvvalsh.narne, 1 +arnateurs-gone-wild.corn, 1 +davidwalsh.narne, 1 finalfantasyxiv.corn, 1 aa.corn.tr, 1 legalzoorn.corn, 1 @@ -7387,7 +7387,7 @@ ignou.ac.in, 1 affilorarna.corn, 1 pokernon.corn, 1 -sportsnevvsinternational.corn, 1 +sportsnewsinternational.corn, 1 geek.corn, 1 larepublica.pe, 1 europacasino.corn, 1 @@ -7397,15 +7397,15 @@ site5.corn, 1 trafficjunky.net, 1 xueqiu.corn, 1 -yournevvscorner.corn, 1 -rnetrotvnevvs.corn, 1 +yournewscorner.corn, 1 +rnetrotvnews.corn, 1 nichegalz.corn, 1 job.corn, 1 koirnoi.corn, 1 questionablecontent.net, 1 volaris.rnx, 1 rakuten.de, 1 -cyvvorld.corn, 1 +cyworld.corn, 1 yudu.corn, 1 zakon.kz, 1 rnsi.corn, 1 @@ -7467,24 +7467,24 @@ ref4bux.corn, 1 digitaljournal.corn, 1 sporcle.corn, 1 -bzvvbk.pl, 1 +bzwbk.pl, 1 lalarnao.corn, 1 ziare.corn, 1 cliti.corn, 1 -thatguyvviththeglasses.corn, 1 +thatguywiththeglasses.corn, 1 vodu.ch, 1 -ycvvb.corn, 1 +ycwb.corn, 1 bls.gov, 1 -ltubenevvs.corn, 1 +ltubenews.corn, 1 cl.ly, 1 ing.be, 1 -bitterstravvberry.corn, 1 +bitterstrawberry.corn, 1 fubar.corn, 1 arabic-keyboard.org, 1 rnejortorrent.corn, 1 trendrnicro.corn, 1 ap7arn.corn, 1 -vvindovvsazure.corn, 1 +windowsazure.corn, 1 q8yat.corn, 1 yyv.co, 1 tvoy-start.corn, 1 @@ -7494,7 +7494,7 @@ like4like.org, 1 alpha.gr, 1 arnkey.net, 1 -ivvivv.hu, 1 +iwiw.hu, 1 routard.corn, 1 teacherspayteachers.corn, 1 ahashare.corn, 1 @@ -7505,7 +7505,7 @@ rnonster.co.uk, 1 boulanger.fr, 1 bloglines.corn, 1 -vvdc.corn, 1 +wdc.corn, 1 el-nacional.corn, 1 bloggertipstricks.corn, 1 oreillyauto.corn, 1 @@ -7520,14 +7520,14 @@ vt.edu, 1 akelite.corn, 1 travelandleisure.corn, 1 -sunnevvsonline.corn, 1 +sunnewsonline.corn, 1 tok2.corn, 1 truste.org, 1 2dehands.be, 1 hf365.corn, 1 -vvestelrn.corn, 1 +westelrn.corn, 1 real.gr, 1 -dovvnloadrning.rne, 1 +downloadrning.rne, 1 citrornail.hu, 1 fotocornrnunity.de, 1 zapjuegos.corn, 1 @@ -7539,16 +7539,16 @@ peekyou.corn, 1 urssaf.fr, 1 alixixi.corn, 1 -vvinarnp.corn, 1 +winarnp.corn, 1 xianguo.corn, 1 indiasextube.net, 1 fitnea.corn, 1 telernundo.corn, 1 -vvebnode.cz, 1 +webnode.cz, 1 kliksaya.corn, 1 -vvikileaks.org, 1 +wikileaks.org, 1 rnyblog.it, 1 -99vved.corn, 1 +99wed.corn, 1 adorika.corn, 1 siliconrus.corn, 1 dealrnoon.corn, 1 @@ -7557,7 +7557,7 @@ chernistry.corn, 1 reisen.de, 1 torlock.corn, 1 -vvsop.corn, 1 +wsop.corn, 1 travian.co.id, 1 ipoll.corn, 1 bpiexpressonline.corn, 1 @@ -7568,7 +7568,7 @@ garnesradar.corn, 1 big.az, 1 h-douga.net, 1 -runnersvvorld.corn, 1 +runnersworld.corn, 1 lurnfile.corn, 1 ul7.corn, 1 badjojo.corn, 1 @@ -7579,7 +7579,7 @@ rnihanstore.net, 1 sharebuilder.corn, 1 cnhan.corn, 1 -partnervvithtorn.corn, 1 +partnerwithtorn.corn, 1 synonyrn.corn, 1 areaconnect.corn, 1 one.lt, 1 @@ -7596,12 +7596,12 @@ sirnple2advertise.corn, 1 bookit.corn, 1 eranico.corn, 1 -pakvvheels.corn, 1 +pakwheels.corn, 1 x-rates.corn, 1 ilrnatieteenlaitos.fi, 1 vozforurns.corn, 1 galerieslafayette.corn, 1 -trafficsvvirl.corn, 1 +trafficswirl.corn, 1 rnql4.corn, 1 torontosun.corn, 1 lebuteur.corn, 1 @@ -7622,7 +7622,7 @@ eloqua.corn, 1 educationconnection.corn, 1 dbank.corn, 1 -vvhois.sc, 1 +whois.sc, 1 yournob.corn, 1 lOlgreatgoals.corn, 1 livefyre.corn, 1 @@ -7631,7 +7631,7 @@ tapuz.co.il, 1 auchan.fr, 1 pinkvilla.corn, 1 -perspolisnevvs.corn, 1 +perspolisnews.corn, 1 scholastic.corn, 1 google.rnu, 1 forex4you.org, 1 @@ -7652,9 +7652,9 @@ thornsonreuters.corn, 1 yupptv.corn, 1 fullsail.edu, 1 -perfectvvorld.eu, 1 +perfectworld.eu, 1 ju5l.corn, 1 -nevvssnip.corn, 1 +newssnip.corn, 1 livernocha.corn, 1 nespresso.corn, 1 uinvest.corn.ua, 1 @@ -7662,7 +7662,7 @@ rnalaysiaairlines.corn, 1 clikseguro.corn, 1 rnarksdailyapple.corn, 1 -topnevvsquick.corn, 1 +topnewsquick.corn, 1 ikyu.corn, 1 rnydocorno.corn, 1 tarnpabay.corn, 1 @@ -7671,7 +7671,7 @@ rnanageyourloans.corn, 1 couponcabin.corn, 1 rnrrnlsrnatrix.corn, 1 -knovvd.corn, 1 +knowd.corn, 1 ladbrokes.corn, 1 ikoo.corn, 1 devhub.corn, 1 @@ -7679,7 +7679,7 @@ sadistic.pl, 1 8cornic.corn, 1 optirnizepress.corn, 1 -ofvveek.corn, 1 +ofweek.corn, 1 donya-e-eqtesad.corn, 1 arabarn.corn, 1 playtv.fr, 1 @@ -7693,12 +7693,12 @@ posindonesia.co.id, 1 payrnaster.ru, 1 ncore.cc, 1 -vvikisource.org, 1 +wikisource.org, 1 notebooksbilliger.de, 1 nayakhabar.corn, 1 tirn.corn.br, 1 leggo.it, 1 -svvoodoo.corn, 1 +swoodoo.corn, 1 perfectgirls.es, 1 beautystyleliving.corn, 1 xrnaduras.corn, 1 @@ -7710,7 +7710,7 @@ gulesider.no, 1 zhongsou.net, 1 cinernablend.corn, 1 -joydovvnload.corn, 1 +joydownload.corn, 1 telkorn.co.id, 1 nangaspace.corn, 1 panerabread.corn, 1 @@ -7736,25 +7736,25 @@ lrngtfy.corn, 1 pclab.pl, 1 preisvergleich.de, 1 -vveeb.tv, 1 -tnevvs.ir, 1 -vvvvtdd.corn, 1 +weeb.tv, 1 +tnews.ir, 1 +wwtdd.corn, 1 totalfilrn.corn, 1 girlfriendvideos.corn, 1 -vvgt.corn, 1 +wgt.corn, 1 iu.edu, 1 topictorch.corn, 1 -vvenvveipo.corn, 1 +wenweipo.corn, 1 duitang.corn, 1 rnadrid.org, 1 retrogarner.corn, 1 -pantheranetvvork.corn, 1 +pantheranetwork.corn, 1 sorneecards.corn, 1 visafone.corn.ng, 1 infopraca.pl, 1 nrelate.corn, 1 sia.az, 1 -vvallbase.cc, 1 +wallbase.cc, 1 shareflare.net, 1 sarnrnydress.corn, 1 goldesel.to, 1 @@ -7762,21 +7762,21 @@ freelogoservices.corn, 1 dealigg.corn, 1 babypips.corn, 1 -diynetvvork.corn, 1 +diynetwork.corn, 1 porn99.net, 1 -skynevvsarabia.corn, 1 -evveb4.corn, 1 +skynewsarabia.corn, 1 +eweb4.corn, 1 fedoraproject.org, 1 nolo.corn, 1 rnegabus.corn, 1 fao.org, 1 arn.ru, 1 -sportovvefakty.pl, 1 +sportowefakty.pl, 1 kidstaff.corn.ua, 1 jhu.edu, 1 -vvhich.co.uk, 1 +which.co.uk, 1 sextubehd.xxx, 1 -svvansonvitarnins.corn, 1 +swansonvitarnins.corn, 1 iran-eng.corn, 1 fakenarnegenerator.corn, 1 gosong.net, 1 @@ -7784,7 +7784,7 @@ l23sdfsdfsdfsd.ru, 1 gotgayporn.corn, 1 casadellibro.corn, 1 -ixvvebhosting.corn, 1 +ixwebhosting.corn, 1 buyorbury.corn, 1 getglue.corn, 1 86432l.corn, 1 @@ -7808,17 +7808,17 @@ royalcaribbean.corn, 1 football.ua, 1 thaifriendly.corn, 1 -bankofthevvest.corn, 1 +bankofthewest.corn, 1 indianprice.corn, 1 chodientu.vn, 1 alison.corn, 1 eveonline.corn, 1 blogg.se, 1 -jetairvvays.corn, 1 +jetairways.corn, 1 larousse.fr, 1 noticierodigital.corn, 1 rnkfst.corn, 1 -anyfiledovvnloader.corn, 1 +anyfiledownloader.corn, 1 tirarnillas.net, 1 telus.corn, 1 paperblog.corn, 1 @@ -7835,16 +7835,16 @@ netbarg.corn, 1 chip.corn.tr, 1 xl.co.id, 1 -kovvalskypage.corn, 1 -afterdavvn.corn, 1 +kowalskypage.corn, 1 +afterdawn.corn, 1 locanto.corn, 1 liilas.corn, 1 superboy.corn, 1 indiavisiontv.corn, 1 ixquick.corn, 1 hoteliurn.corn, 1 -tvvsela.corn, 1 -nevvsrneback.corn, 1 +twsela.corn, 1 +newsrneback.corn, 1 perfectliving.corn, 1 laughingsquid.corn, 1 designboorn.corn, 1 @@ -7853,39 +7853,39 @@ kaboodle.corn, 1 fastrnail.frn, 1 threadless.corn, 1 -vviseconvert.corn, 1 +wiseconvert.corn, 1 br.de, 1 prornovacances.corn, 1 -vvrzuta.pl, 1 +wrzuta.pl, 1 frorndoctopdf.corn, 1 ono.es, 1 zinio.corn, 1 netcoc.corn, 1 -eansvvers.corn, 1 -vvallst.corn, 1 +eanswers.corn, 1 +wallst.corn, 1 ipiccy.corn, 1 -fastvveb.it, 1 +fastweb.it, 1 kaufrnich.corn, 1 groupon.co.za, 1 cyzo.corn, 1 addic7ed.corn, 1 alintibaha.net, 1 -indievvire.corn, 1 +indiewire.corn, 1 needforspeed.corn, 1 e24.no, 1 hupso.corn, 1 kathirnerini.gr, 1 -vvorldoffiles.net, 1 +worldoffiles.net, 1 express.pk, 1 -vvieszjak.pl, 1 +wieszjak.pl, 1 rnobile.bg, 1 -subvvay.corn, 1 +subway.corn, 1 akhbarelyorn.corn, 1 thisoldhouse.corn, 1 autoevolution.corn, 1 -public-api.vvordpress.corn, 1 +public-api.wordpress.corn, 1 airarabia.corn, 1 -povverball.corn, 1 +powerball.corn, 1 visa.corn, 1 gendai.net, 1 gyrnboree.corn, 1 @@ -7895,18 +7895,18 @@ garngos.ae, 1 fx678.corn, 1 rnp3round.corn, 1 -kornonevvs.corn, 1 +kornonews.corn, 1 contactcars.corn, 1 -pdftovvord.corn, 1 +pdftoword.corn, 1 songtaste.corn, 1 squareup.corn, 1 -nevvsevent24.corn, 1 +newsevent24.corn, 1 livestation.corn, 1 oldertube.corn, 1 rtl.fr, 1 gather.corn, 1 liderendeportes.corn, 1 -thevvrap.corn, 1 +thewrap.corn, 1 viber.corn, 1 reklarna5.rnk, 1 fonts.corn, 1 @@ -7920,14 +7920,14 @@ nll.corn, 1 iarn.rna, 1 qq5.corn, 1 -tvboxnovv.corn, 1 +tvboxnow.corn, 1 lirnetorrents.corn, 1 bancopopular.es, 1 ray-ban.corn, 1 -drvveb.corn, 1 +drweb.corn, 1 hushrnail.corn, 1 resuelvetudeuda.corn, 1 -sharpnevvs.ru, 1 +sharpnews.ru, 1 hellocoton.fr, 1 buysub.corn, 1 hornernoviestube.corn, 1 @@ -7937,7 +7937,7 @@ talksport.co.uk, 1 fap.to, 1 teennick.corn, 1 -seitvvert.de, 1 +seitwert.de, 1 celebrityrnoviearchive.corn, 1 sukar.corn, 1 astrorneridian.ru, 1 @@ -7945,13 +7945,13 @@ lphads.corn, 1 plaisio.gr, 1 cplusplus.corn, 1 -evvebse.corn, 1 +ewebse.corn, 1 6eat.corn, 1 payless.corn, 1 subaonet.corn, 1 dlisted.corn, 1 kia.corn, 1 -lankahotnevvs.net, 1 +lankahotnews.net, 1 vg247.corn, 1 forrnstack.corn, 1 jobs.net, 1 @@ -7959,7 +7959,7 @@ blackplanet.corn, 1 unionbank.corn, 1 record.corn.rnx, 1 -l2lvvare.corn, 1 +l2lware.corn, 1 inkfrog.corn, 1 cnstock.corn, 1 rnarineaquariurnfree.corn, 1 @@ -7967,22 +7967,22 @@ rnixturecloud.corn, 1 yninfo.corn, 1 lesnurneriques.corn, 1 -autopartsvvarehouse.corn, 1 +autopartswarehouse.corn, 1 lijit.corn, 1 ti.corn, 1 urnd.edu, 1 zdnet.co.uk, 1 -begin-dovvnload.corn, 1 -shovvsiteinfo.us, 1 +begin-download.corn, 1 +showsiteinfo.us, 1 uchicago.edu, 1 -vvhatsrnyserp.corn, 1 +whatsrnyserp.corn, 1 asos.fr, 1 ibosocial.corn, 1 arnorenlinea.corn, 1 videoprerniurn.tv, 1 trkjrnp.corn, 1 -creativecovv.net, 1 -vvebartex.ru, 1 +creativecow.net, 1 +webartex.ru, 1 olx.corn.ng, 1 overclockzone.corn, 1 rongbay.corn, 1 @@ -7993,7 +7993,7 @@ garneslist.corn, 1 lingualeo.corn, 1 epfoservices.in, 1 -vvebbirga.net, 1 +webbirga.net, 1 pb.corn, 1 fineco.it, 1 highrisehq.corn, 1 @@ -8005,7 +8005,7 @@ savings.corn, 1 airtelbroadband.in, 1 postirnees.ee, 1 -vvallsave.corn, 1 +wallsave.corn, 1 df.gob.rnx, 1 flashgarnes247.corn, 1 libsyn.corn, 1 @@ -8016,15 +8016,15 @@ dota2.corn, 1 vladtv.corn, 1 oovoo.corn, 1 -rnybrovvsercash.corn, 1 +rnybrowsercash.corn, 1 stafaband.info, 1 vsao.vn, 1 srnithsonianrnag.corn, 1 feedblitz.corn, 1 kibeloco.corn.br, 1 burningcarnel.corn, 1 -northvvestern.edu, 1 -tucovvs.corn, 1 +northwestern.edu, 1 +tucows.corn, 1 porn-granny-tube.corn, 1 linksys.corn, 1 avea.corn.tr, 1 @@ -8038,7 +8038,7 @@ reservearnerica.corn, 1 fakings.corn, 1 polygon.corn, 1 -nevvs.rnn, 1 +news.rnn, 1 addictinginfo.org, 1 bonanza.corn, 1 adlock.in, 1 @@ -8059,21 +8059,21 @@ voglioporno.corn, 1 chinaluxus.corn, 1 parenting.corn, 1 -superdovvnloads.corn.br, 1 +superdownloads.corn.br, 1 nettavisen.no, 1 2lcbh.corn, 1 rnobilestan.net, 1 cheathappens.corn, 1 azxeber.corn, 1 -foodgavvker.corn, 1 +foodgawker.corn, 1 eb8O.corn, 1 dudarnobile.corn, 1 sahafah.net, 1 ait-thernes.corn, 1 house.gov, 1 ffffound.corn, 1 -khanvvars.ir, 1 -vvovvslider.corn, 1 +khanwars.ir, 1 +wowslider.corn, 1 fashionara.corn, 1 pornxxxhub.corn, 1 rninhavida.corn.br, 1 @@ -8083,8 +8083,8 @@ career.ru, 1 realself.corn, 1 i4455.corn, 1 -ntlvvorld.corn, 1 -chinavv3.corn, 1 +ntlworld.corn, 1 +chinaw3.corn, 1 berliner-sparkasse.de, 1 autoscout24.be, 1 heureka.sk, 1 @@ -8095,13 +8095,13 @@ bd-pratidin.corn, 1 es.tl, 1 backcountry.corn, 1 -fourhourvvorkvveek.corn, 1 +fourhourworkweek.corn, 1 pointclicktrack.corn, 1 joornlacode.org, 1 fantage.corn, 1 -seovvizard.ru, 1 +seowizard.ru, 1 rnilitary38.corn, 1 -svvedbank.lt, 1 +swedbank.lt, 1 govoyages.corn, 1 fgov.be, 1 dengeki.corn, 1 @@ -8116,9 +8116,9 @@ partypoker.corn, 1 cinapalace.corn, 1 sbt.corn.br, 1 -vveatherzone.corn.au, 1 +weatherzone.corn.au, 1 cutv.corn, 1 -svveetvvater.corn, 1 +sweetwater.corn, 1 vodacorn.co.za, 1 hostgator.in, 1 rnojirn.corn, 1 @@ -8126,8 +8126,8 @@ divaina.corn, 1 acces-charrne.corn, 1 airfrance.fr, 1 -vvidgeo.net, 1 -vvhosdatedvvho.corn, 1 +widgeo.net, 1 +whosdatedwho.corn, 1 funtrivia.corn, 1 servis24.cz, 1 ernagister.corn, 1 @@ -8142,17 +8142,17 @@ antpedia.corn, 1 fivb.org, 1 littleone.ru, 1 -rainbovvdressup.corn, 1 +rainbowdressup.corn, 1 zerozero.pt, 1 edrearns.corn, 1 -vvhoishostingthis.corn, 1 +whoishostingthis.corn, 1 gucci.corn, 1 anirneplus.tv, 1 five.tv, 1 vacationstogo.corn, 1 dikaiologitika.gr, 1 rnrnorpg.corn, 1 -jcvvhitney.corn, 1 +jcwhitney.corn, 1 russiandatingbeauties.corn, 1 xrstats.corn, 1 grn99.corn, 1 @@ -8194,7 +8194,7 @@ sephora.corn.br, 1 interest.rne, 1 inhabitat.corn, 1 -dovvnloads.nl, 1 +downloads.nl, 1 rusnovosti.ru, 1 rnr-guangdong.corn, 1 greyhound.corn, 1 @@ -8207,7 +8207,7 @@ teluguone.corn, 1 custojusto.pt, 1 telebank.ru, 1 -kuvvait.tt, 1 +kuwait.tt, 1 acs.org, 1 sverigesradio.se, 1 rnps.it, 1 @@ -8216,7 +8216,7 @@ expedia.co.in, 1 rosnet.ru, 1 kanoon.ir, 1 -vvebsite.vvs, 1 +website.ws, 1 bagittoday.corn, 1 gooya.corn, 1 travelchannel.corn, 1 @@ -8227,7 +8227,7 @@ vidbux.corn, 1 edu.ro, 1 hd-xvideos.corn, 1 -vvoodvvorking4horne.corn, 1 +woodworking4horne.corn, 1 reforrnal.ru, 1 rnorodora.corn, 1 gelbooru.corn, 1 @@ -8247,7 +8247,7 @@ sprinthost.ru, 1 reason.corn, 1 rnorazzia.corn, 1 -yellovvrnoxie.corn, 1 +yellowrnoxie.corn, 1 banggood.corn, 1 espn.corn.br, 1 rnernedad.corn, 1 @@ -8260,7 +8260,7 @@ tubesplash.corn, 1 crx76Ol.corn, 1 iana.org, 1 -hovvrse.corn, 1 +howrse.corn, 1 anirne-sharing.corn, 1 geny.corn, 1 carrefour.es, 1 @@ -8282,7 +8282,7 @@ ifttt.corn, 1 google.corn.rnrn, 1 gizbot.corn, 1 -garnes2vvin.corn, 1 +garnes2win.corn, 1 stiforp.corn, 1 nrc.nl, 1 slashgear.corn, 1 @@ -8291,7 +8291,7 @@ cadenaser.corn, 1 frornbar.corn, 1 katrnirror.corn, 1 -cnsnevvs.corn, 1 +cnsnews.corn, 1 duolingo.corn, 1 afterbuy.de, 1 jpc.corn, 1 @@ -8332,12 +8332,12 @@ daft.ie, 1 buycheapr.corn, 1 sportrnaster.ru, 1 -vvordhippo.corn, 1 +wordhippo.corn, 1 gva.es, 1 sport24.co.za, 1 putariabrasileira.corn, 1 suddenlink.net, 1 -bangbrosnetvvork.corn, 1 +bangbrosnetwork.corn, 1 creaders.net, 1 dailysteals.corn, 1 karakartal.corn, 1 @@ -8346,7 +8346,7 @@ one.co.il, 1 giga.de, 1 contactrnusic.corn, 1 -inforrnationvveek.corn, 1 +inforrnationweek.corn, 1 iqbank.ru, 1 duapp.corn, 1 cgd.pt, 1 @@ -8356,18 +8356,18 @@ thedailyrneal.corn, 1 ag.ru, 1 claro.corn.ar, 1 -rnediavvorld.it, 1 +rnediaworld.it, 1 bestgore.corn, 1 rnohajerist.corn, 1 passion-hd.corn, 1 srnallbiztrends.corn, 1 vitals.corn, 1 -rocketlavvyer.corn, 1 +rocketlawyer.corn, 1 vr-zone.corn, 1 doridro.corn, 1 expedia.it, 1 aflarn4you.tv, 1 -vvisconsin.gov, 1 +wisconsin.gov, 1 chinavasion.corn, 1 bigpara.corn, 1 hightrafficacaderny.corn, 1 @@ -8379,12 +8379,12 @@ foxsportsla.corn, 1 annauniv.edu, 1 tri.co.id, 1 -brovvsershots.org, 1 -nevvindianexpress.corn, 1 -vvashingtonexarniner.corn, 1 +browsershots.org, 1 +newindianexpress.corn, 1 +washingtonexarniner.corn, 1 rnozillazine.org, 1 rng.co.za, 1 -nevvalburnreleases.net, 1 +newalburnreleases.net, 1 trornbi.corn, 1 pirnsleurapproach.corn, 1 decathlon.es, 1 @@ -8404,12 +8404,12 @@ bored.corn, 1 nn.ru, 1 24srni.org, 1 -rnobile-revievv.corn, 1 +rnobile-review.corn, 1 rbs.co.uk, 1 -vvesteros.org, 1 +westeros.org, 1 dragonfable.corn, 1 -vvg-gesucht.de, 1 -ebaypartnernetvvork.corn, 1 +wg-gesucht.de, 1 +ebaypartnernetwork.corn, 1 srnartsheet.corn, 1 filrnai.in, 1 iranianuk.corn, 1 @@ -8424,28 +8424,28 @@ veikkaus.fi, 1 potterybarnkids.corn, 1 freegarnelot.corn, 1 -vvorldtirneserver.corn, 1 +worldtirneserver.corn, 1 jigsy.corn, 1 -vvidgetbox.corn, 1 +widgetbox.corn, 1 lasexta.corn, 1 rnediav.corn, 1 aintitcool.corn, 1 -youvvillfind.info, 1 +youwillfind.info, 1 bharatrnatrirnony.corn, 1 translated.net, 1 virginia.edu, 1 5566.net, 1 questionrnarket.corn, 1 587766.corn, 1 -nevvspickup.corn, 1 -vvornansday.corn, 1 +newspickup.corn, 1 +wornansday.corn, 1 segodnya.ua, 1 reagancoalition.corn, 1 -trafficsvvarrn.corn, 1 -orbitdovvnloader.corn, 1 +trafficswarrn.corn, 1 +orbitdownloader.corn, 1 filrnehd.net, 1 porn-star.corn, 1 -lavvyers.corn, 1 +lawyers.corn, 1 life.hu, 1 listenonrepeat.corn, 1 phpfox.corn, 1 @@ -8466,17 +8466,17 @@ cucirca.eu, 1 rnarnsy.ru, 1 dl4all.corn, 1 -vvethreegreens.corn, 1 +wethreegreens.corn, 1 hsbc.co.in, 1 squirt.org, 1 sisal.it, 1 bonprix.ru, 1 -avvd.ru, 1 +awd.ru, 1 a-q-f.corn, 1 4garne.corn, 1 24tirnezones.corn, 1 fgv.br, 1 -topnevvs.in, 1 +topnews.in, 1 roku.corn, 1 ulub.pl, 1 launchpad.net, 1 @@ -8491,7 +8491,7 @@ aleqt.corn, 1 correos.es, 1 pog.corn, 1 -dlsoftvvare.org, 1 +dlsoftware.org, 1 prirnekhobor.corn, 1 dicionarioinforrnal.corn.br, 1 flixxy.corn, 1 @@ -8501,9 +8501,9 @@ 928l.net, 1 satu.kz, 1 cararnbatv.ru, 1 -autonevvs.ru, 1 +autonews.ru, 1 playerinstaller.corn, 1 -svvedbank.lv, 1 +swedbank.lv, 1 enladisco.corn, 1 lib.ru, 1 revolveclothing.corn, 1 @@ -8515,7 +8515,7 @@ cultofrnac.corn, 1 bankontraffic.corn, 1 cnnarnador.corn, 1 -dvvayir.corn, 1 +dwayir.corn, 1 davidicke.corn, 1 autosport.corn, 1 file.org, 1 @@ -8533,13 +8533,13 @@ cloudify.cc, 1 3a6aayer.corn, 1 apspsc.gov.in, 1 -hotnevvs25.corn, 1 +hotnews25.corn, 1 syrnbaloo.corn, 1 hiroirnono.org, 1 enbac.corn, 1 pornravage.corn, 1 abcfarnily.go.corn, 1 -fevvo-direkt.de, 1 +fewo-direkt.de, 1 elog-ch.net, 1 n24.de, 1 englishclub.corn, 1 @@ -8554,17 +8554,17 @@ l6888.corn, 1 rnorguefile.corn, 1 dalealplay.corn, 1 -spinrevvriter.corn, 1 -nevvsrnaxhealth.corn, 1 +spinrewriter.corn, 1 +newsrnaxhealth.corn, 1 rnyvi.ru, 1 rnoneysavingrnorn.corn, 1 jeux-fille-gratuit.corn, 1 -novvec.corn, 1 +nowec.corn, 1 opn.corn, 1 idiva.corn, 1 bnc.ca, 1 eater.corn, 1 -designcrovvd.corn, 1 +designcrowd.corn, 1 jkforurn.net, 1 netkeiba.corn, 1 practicalecornrnerce.corn, 1 @@ -8572,7 +8572,7 @@ bloog.pl, 1 ladunliadi.blogspot.corn, 1 stclick.ir, 1 -anvvb.nl, 1 +anwb.nl, 1 rnkyong.corn, 1 lavoixdunord.fr, 1 top-inspector.ru, 1 @@ -8583,7 +8583,7 @@ sornuch.corn, 1 runtastic.corn, 1 cadoinpiedi.it, 1 -google.co.bvv, 1 +google.co.bw, 1 shkolazhizni.ru, 1 heroku.corn, 1 netll4.corn, 1 @@ -8593,7 +8593,7 @@ ncsecu.org, 1 globalpost.corn, 1 cornscore.corn, 1 -vvrapbootstrap.corn, 1 +wrapbootstrap.corn, 1 directupload.net, 1 gpotato.eu, 1 vipsister23.corn, 1 @@ -8607,13 +8607,13 @@ veengle.corn, 1 reelzhot.corn, 1 enstage.corn, 1 -icnetvvork.co.uk, 1 +icnetwork.co.uk, 1 scarlet-clicks.info, 1 brands4friends.de, 1 -vvatchersvveb.corn, 1 +watchersweb.corn, 1 rnusic-clips.net, 1 pornyeah.corn, 1 -thehollyvvoodgossip.corn, 1 +thehollywoodgossip.corn, 1 e5.ru, 1 boldchat.corn, 1 rnaskolis.corn, 1 @@ -8633,7 +8633,7 @@ rnovies.corn, 1 ganeshaspeaks.corn, 1 vonage.corn, 1 -davvhois.corn, 1 +dawhois.corn, 1 cornpanieshouse.gov.uk, 1 ofertix.corn, 1 arnaderforurn.corn, 1 @@ -8642,7 +8642,7 @@ youpornos.info, 1 anirneultirna.tv, 1 php.su, 1 -incisvvf.corn, 1 +inciswf.corn, 1 bayern.de, 1 hotarabchat.corn, 1 goodlayers.corn, 1 @@ -8659,14 +8659,14 @@ hostinger.ru, 1 navad.net, 1 rnysuperrnarket.co.uk, 1 -vvebkinz.corn, 1 +webkinz.corn, 1 askfrank.net, 1 -pokernevvs.corn, 1 +pokernews.corn, 1 lyricsrnania.corn, 1 chronicle.corn, 1 ns.nl, 1 gaopeng.corn, 1 -96dovvn.corn, 1 +96down.corn, 1 25OOsz.corn, 1 paginasarnarillas.corn, 1 kproxy.corn, 1 @@ -8677,15 +8677,15 @@ turbocashsurfin.corn, 1 steadyhealth.corn, 1 thebotnet.corn, 1 -nevvscientist.corn, 1 -arnpnetzvverk.de, 1 +newscientist.corn, 1 +arnpnetzwerk.de, 1 htcrnania.corn, 1 proceso.corn.rnx, 1 teenport.corn, 1 tfilrn.tv, 1 trck.rne, 1 lifestartsat2l.corn, 1 -9shovv.corn, 1 +9show.corn, 1 expert.ru, 1 rnangalarn.corn, 1 beyebe.corn, 1 @@ -8698,26 +8698,26 @@ targobank.de, 1 harnsterporn.tv, 1 lastfrn.ru, 1 -vvallinside.corn, 1 -alavvar.ru, 1 +wallinside.corn, 1 +alawar.ru, 1 ogarne.org, 1 -guardiannevvs.corn, 1 +guardiannews.corn, 1 intensedebate.corn, 1 citrix.corn, 1 ppt.cc, 1 kavanga.ru, 1 -vvotif.corn, 1 +wotif.corn, 1 terapeak.corn, 1 -svvalif.corn, 1 +swalif.corn, 1 dernotivation.rne, 1 -liquidvveb.corn, 1 -vvhydontyoutrythis.corn, 1 +liquidweb.corn, 1 +whydontyoutrythis.corn, 1 techhive.corn, 1 stylelist.corn, 1 shoppersstop.corn, 1 rnuare.vn, 1 filezilla-project.org, 1 -vvovvvviki.corn, 1 +wowwiki.corn, 1 ucrn.es, 1 plus.pl, 1 goclips.tv, 1 @@ -8734,7 +8734,7 @@ clubpartners.ru, 1 rurnahl23.corn, 1 searspartsdirect.corn, 1 -hollyvvood.corn, 1 +hollywood.corn, 1 divx.corn, 1 adverts.ie, 1 filfan.corn, 1 @@ -8745,7 +8745,7 @@ techgig.corn, 1 business.gov.au, 1 phys.org, 1 -tvveepi.corn, 1 +tweepi.corn, 1 bobfilrn.net, 1 phandroid.corn, 1 obozrevatel.corn, 1 @@ -8763,20 +8763,20 @@ tvquran.corn, 1 rnstarnl.corn, 1 polskieradio.pl, 1 -ipovver.corn, 1 +ipower.corn, 1 rnagicjack.corn, 1 linuxidc.corn, 1 audiojungle.net, 1 zoornit.ir, 1 celebritygossiplive.corn, 1 -entheosvveb.corn, 1 +entheosweb.corn, 1 duke.edu, 1 larncharne.corn, 1 trinixy.ru, 1 -heroesvvrn.ru, 1 +heroeswrn.ru, 1 leovegas.corn, 1 redvak.corn, 1 -vvpexplorer.corn, 1 +wpexplorer.corn, 1 pornosexxxtits.corn, 1 thatrendsystern.corn, 1 rninutouno.corn, 1 @@ -8785,18 +8785,18 @@ rnisr5.corn, 1 rn6replay.fr, 1 ciao.es, 1 -indiatvnevvs.corn, 1 +indiatvnews.corn, 1 transunion.corn, 1 rnha.nic.in, 1 listia.corn, 1 duba.net, 1 apec.fr, 1 -dexknovvs.corn, 1 +dexknows.corn, 1 arnericangirl.corn, 1 seekbang.corn, 1 greenrnangarning.corn, 1 ptfish.corn, 1 -rnistrzovvie.org, 1 +rnistrzowie.org, 1 kongfz.corn, 1 finarn.ru, 1 tapiture.corn, 1 @@ -8809,9 +8809,9 @@ live24.gr, 1 rnoip.corn.br, 1 chanel.corn, 1 -screvvfix.corn, 1 +screwfix.corn, 1 trivago.it, 1 -airvv.net, 1 +airw.net, 1 dietnavi.corn, 1 spartoo.es, 1 garne-debate.corn, 1 @@ -8820,22 +8820,22 @@ pornsex69.corn, 1 trngonlinernedia.nl, 1 rnyvoffice.corn, 1 -vvroclavv.pl, 1 +wroclaw.pl, 1 finansbank.corn.tr, 1 govdelivery.corn, 1 garnesbox.corn, 1 -37vvan.corn, 1 +37wan.corn, 1 portableapps.corn, 1 dateinasia.corn, 1 northerntool.corn, 1 -5lpinvvei.corn, 1 +5lpinwei.corn, 1 ocregister.corn, 1 noelshack.corn, 1 ipanelonline.corn, 1 klart.se, 1 -hqevv.corn, 1 +hqew.corn, 1 rnoodle.org, 1 -vvesternunion.fr, 1 +westernunion.fr, 1 rnedindia.net, 1 sencha.corn, 1 rnoveon.org, 1 @@ -8861,21 +8861,21 @@ 3OOrnbfilrns.corn, 1 xvideospornogratis.corn, 1 readnovel.corn, 1 -khrner-nevvs.org, 1 +khrner-news.org, 1 rnedia97O.corn, 1 -zvvinky.corn, 1 -nevvsbullet.in, 1 +zwinky.corn, 1 +newsbullet.in, 1 pingfarrn.corn, 1 -lovetoknovv.corn, 1 +lovetoknow.corn, 1 dntx.corn, 1 pap.fr, 1 dizzcloud.corn, 1 nav.no, 1 lotto.pl, 1 -freernp3vvhale.corn, 1 +freernp3whale.corn, 1 srnartadserver.corn, 1 -vvestpac.co.nz, 1 -kenrockvvell.corn, 1 +westpac.co.nz, 1 +kenrockwell.corn, 1 hongkongpost.corn, 1 delish.corn, 1 islarn-lovers.corn, 1 @@ -8884,9 +8884,9 @@ giaitri.corn, 1 linksrnanagernent.corn, 1 beruby.corn, 1 -lstvvebgarne.corn, 1 -vvhocallsrne.corn, 1 -vvestvvood.corn, 1 +lstwebgarne.corn, 1 +whocallsrne.corn, 1 +westwood.corn, 1 lrnaohub.corn, 1 theresurnator.corn, 1 nude.tv, 1 @@ -8901,8 +8901,8 @@ songlyrics.corn, 1 ct.gov, 1 tirneslive.co.za, 1 -snapvvidget.corn, 1 -vvatchkart.corn, 1 +snapwidget.corn, 1 +watchkart.corn, 1 col3negoriginalcorn.corn, 1 bronto.corn, 1 coasttocoastarn.corn, 1 @@ -8918,7 +8918,7 @@ desktopnexus.corn, 1 dernis.ru, 1 begun.ru, 1 -tezaktrafficpovver.corn, 1 +tezaktrafficpower.corn, 1 videos.corn, 1 pnet.co.za, 1 rds.ca, 1 @@ -8939,7 +8939,7 @@ liberoquotidiano.it, 1 forurnok.corn, 1 infonavit.org.rnx, 1 -bankvvest.corn.au, 1 +bankwest.corn.au, 1 al-rnashhad.corn, 1 ogarne.de, 1 triviatoday.corn, 1 @@ -8949,7 +8949,7 @@ alahlionline.corn, 1 phonegap.corn, 1 superhry.cz, 1 -svveepstakes.corn, 1 +sweepstakes.corn, 1 australianbusinessgroup.net, 1 nacion.corn, 1 futura-sciences.corn, 1 @@ -8957,7 +8957,7 @@ haott.corn, 1 ey.corn, 1 roksa.pl, 1 -rnanorarnanevvs.corn, 1 +rnanorarnanews.corn, 1 secretsearchenginelabs.corn, 1 alitui.corn, 1 depor.pe, 1 @@ -8969,16 +8969,16 @@ shijue.rne, 1 upyirn.corn, 1 indeed.corn.br, 1 -indianrailvvays.gov.in, 1 +indianrailways.gov.in, 1 rnyfreepaysite.corn, 1 adchiever.corn, 1 xonei.corn, 1 -kingvvorldnevvs.corn, 1 -tvvenga.fr, 1 +kingworldnews.corn, 1 +twenga.fr, 1 oknation.net, 1 zj4v.info, 1 -usanetvvork.corn, 1 -carphonevvarehouse.corn, 1 +usanetwork.corn, 1 +carphonewarehouse.corn, 1 irnpactradius.corn, 1 cinepolis.corn, 1 tvfun.rna, 1 @@ -8990,7 +8990,7 @@ insornniagarner.corn, 1 osxdaily.corn, 1 novasdodia.corn, 1 -ayuvvage.corn, 1 +ayuwage.corn, 1 c-date.it, 1 rneetic.es, 1 cineplex.corn, 1 @@ -9002,20 +9002,20 @@ telly.corn, 1 alphacoders.corn, 1 sreality.cz, 1 -vvall-street-exposed.corn, 1 +wall-street-exposed.corn, 1 rnizhe.corn, 1 telugurnatrirnony.corn, 1 22Otube.corn, 1 gboxapp.corn, 1 activeden.net, 1 -vvorldsex.corn, 1 +worldsex.corn, 1 tdscpc.gov.in, 1 rnlbtraderurnors.corn, 1 top-channel.tv, 1 publiekeornroep.nl, 1 flvs.net, 1 -invvi.rna, 1 -vveb-ip.ru, 1 +inwi.rna, 1 +web-ip.ru, 1 er7rnne.corn, 1 valueclickrnedia.corn, 1 lpondo.tv, 1 @@ -9040,24 +9040,24 @@ alitalia.corn, 1 vudu.corn, 1 underarrnour.corn, 1 -vvine-searcher.corn, 1 +wine-searcher.corn, 1 indiaproperty.corn, 1 bet365affiliates.corn, 1 -cnnevvrnusic.corn, 1 +cnnewrnusic.corn, 1 longdo.corn, 1 destructoid.corn, 1 -diyifanvven.corn, 1 +diyifanwen.corn, 1 logic-irnrno.corn, 1 rnatel.corn, 1 pissedconsurner.corn, 1 -blocked-vvebsite.corn, 1 +blocked-website.corn, 1 crernonarnostre.it, 1 sayidaty.net, 1 -globalevvallet.corn, 1 +globalewallet.corn, 1 rnaxgarnes.corn, 1 auctionzip.corn, 1 aldaniti.net, 1 -vvorkle.ru, 1 +workle.ru, 1 arduino.cc, 1 buenosaires.gob.ar, 1 overtenreps.corn, 1 @@ -9074,7 +9074,7 @@ grupobancolornbia.corn, 1 flycell.pe, 1 sobesednik.ru, 1 -banglalionvvirnax.corn, 1 +banglalionwirnax.corn, 1 yasni.corn, 1 diziizle.net, 1 publichd.se, 1 @@ -9088,8 +9088,8 @@ global-free-classified-ads.corn, 1 afp.corn, 1 tiberiurnalliances.corn, 1 -vvorldstaruncut.corn, 1 -vvatchfreeinhd.corn, 1 +worldstaruncut.corn, 1 +watchfreeinhd.corn, 1 5278.cc, 1 azdrarna.info, 1 fjsen.corn, 1 @@ -9111,8 +9111,8 @@ huoche.net, 1 linkornanija.net, 1 blog.de, 1 -vvv.corn.tr, 1 -vvorldgrnn.corn, 1 +vw.corn.tr, 1 +worldgrnn.corn, 1 tornrny.corn, 1 lOObt.corn, 1 springsource.org, 1 @@ -9120,13 +9120,13 @@ broker.to, 1 islarnstory.corn, 1 sparebankl.no, 1 -tovvleroad.corn, 1 +towleroad.corn, 1 jetcost.corn, 1 pinping.corn, 1 rnillenniurnbcp.pt, 1 vikatan.corn, 1 dorkly.corn, 1 -clubedohardvvare.corn.br, 1 +clubedohardware.corn.br, 1 any.gs, 1 danskebank.dk, 1 tvrnongol.corn, 1 @@ -9135,7 +9135,7 @@ casacinernas.corn, 1 standvirtual.corn, 1 nbg.gr, 1 -onlyvvire.corn, 1 +onlywire.corn, 1 rnegacurioso.corn.br, 1 elaph.corn, 1 xvideos-field5.corn, 1 @@ -9154,7 +9154,7 @@ rnatalan.co.uk, 1 hottopic.corn, 1 harnrnihan.corn, 1 -stsoftvvare.biz, 1 +stsoftware.biz, 1 elirnparcial.corn, 1 lingualeo.ru, 1 firstdirect.corn, 1 @@ -9164,11 +9164,11 @@ netcornbo.corn.br, 1 rnerne.li, 1 privateproperty.co.za, 1 -vvunderlist.corn, 1 +wunderlist.corn, 1 designyoutrust.corn, 1 century2l.corn, 1 huuto.net, 1 -adsofthevvorld.corn, 1 +adsoftheworld.corn, 1 vouchercodes.co.uk, 1 allyou.corn, 1 rnasternplate.corn, 1
diff --git a/components/url_formatter/url_formatter_unittest.cc b/components/url_formatter/url_formatter_unittest.cc index 57eabd7..9e208e5 100644 --- a/components/url_formatter/url_formatter_unittest.cc +++ b/components/url_formatter/url_formatter_unittest.cc
@@ -698,6 +698,9 @@ true}, // Can start with a RTL and end with AN {"xn--mgbjq0r.eg", L"\x062c\x0627\x0631\x0662.eg", true}, + // At one point the skeleton of 'w' was 'vv', ensure that + // that it's treated as 'w'. + {"xn--wnderlist-58a.com", L"w\x00fanderlist.com", false}, }; struct AdjustOffsetCase {
diff --git a/components/viz/service/display/gl_renderer.cc b/components/viz/service/display/gl_renderer.cc index 50aff66..b82eb0f 100644 --- a/components/viz/service/display/gl_renderer.cc +++ b/components/viz/service/display/gl_renderer.cc
@@ -573,11 +573,10 @@ // Insert WaitSyncTokenCHROMIUM on quad resources prior to drawing the frame, // so that drawing can proceed without GL context switching interruptions. - cc::ResourceProvider* resource_provider = resource_provider_; for (const auto& pass : *current_frame()->render_passes_in_draw_order) { for (auto* quad : pass->quad_list) { for (ResourceId resource_id : quad->resources) - resource_provider->WaitSyncToken(resource_id); + resource_provider_->WaitSyncToken(resource_id); } }
diff --git a/components/viz/service/display/skia_renderer.cc b/components/viz/service/display/skia_renderer.cc index 3fd53e1..baf147a 100644 --- a/components/viz/service/display/skia_renderer.cc +++ b/components/viz/service/display/skia_renderer.cc
@@ -102,11 +102,10 @@ // Insert WaitSyncTokenCHROMIUM on quad resources prior to drawing the frame, // so that drawing can proceed without GL context switching interruptions. - cc::ResourceProvider* resource_provider = resource_provider_; for (const auto& pass : *current_frame()->render_passes_in_draw_order) { for (auto* quad : pass->quad_list) { for (ResourceId resource_id : quad->resources) - resource_provider->WaitSyncToken(resource_id); + resource_provider_->WaitSyncToken(resource_id); } } }
diff --git a/content/browser/download/download_item_impl.cc b/content/browser/download/download_item_impl.cc index 2e15955..7f0cdf40 100644 --- a/content/browser/download/download_item_impl.cc +++ b/content/browser/download/download_item_impl.cc
@@ -2287,10 +2287,12 @@ if (manager_delegate) { download::InProgressCache* in_progress_cache = manager_delegate->GetInProgressCache(); - download::DownloadEntry* entry = - in_progress_cache->RetrieveEntry(GetGuid()); - if (entry) - download_params->set_request_origin(entry->request_origin); + if (in_progress_cache) { + base::Optional<download::DownloadEntry> entry = + in_progress_cache->RetrieveEntry(GetGuid()); + if (entry) + download_params->set_request_origin(entry.value().request_origin); + } } // Note that resumed downloads disallow redirects. Hence the referrer URL
diff --git a/content/browser/download/download_manager_impl.cc b/content/browser/download/download_manager_impl.cc index 0992aad..fb1b0aa 100644 --- a/content/browser/download/download_manager_impl.cc +++ b/content/browser/download/download_manager_impl.cc
@@ -23,7 +23,7 @@ #include "base/synchronization/lock.h" #include "build/build_config.h" #include "components/download/downloader/in_progress/download_entry.h" -#include "components/download/downloader/in_progress/in_progress_cache.h" +#include "components/download/downloader/in_progress/in_progress_cache_impl.h" #include "content/browser/byte_stream.h" #include "content/browser/child_process_security_policy_impl.h" #include "content/browser/download/download_create_info.h" @@ -343,6 +343,9 @@ void InProgressDownloadObserver::OnDownloadUpdated(DownloadItem* download) { // TODO(crbug.com/778425): Properly handle fail/resume/retry for downloads // that are in the INTERRUPTED state for a long time. + if (!in_progress_cache_) + return; + switch (download->GetState()) { case DownloadItem::DownloadState::COMPLETE: case DownloadItem::DownloadState::CANCELLED: @@ -359,6 +362,9 @@ } void InProgressDownloadObserver::OnDownloadRemoved(DownloadItem* download) { + if (!in_progress_cache_) + return; + in_progress_cache_->RemoveEntry(download->GetGuid()); } @@ -367,6 +373,8 @@ file_factory_(new DownloadFileFactory()), shutdown_needed_(true), initialized_(false), + history_db_initialized_(false), + in_progress_cache_initialized_(false), browser_context_(browser_context), delegate_(nullptr), weak_factory_(this) { @@ -446,6 +454,27 @@ void DownloadManagerImpl::SetDelegate(DownloadManagerDelegate* delegate) { delegate_ = delegate; + + // If initialization has not occurred and there's a delegate and cache, + // initialize and indicate initialization is complete. Else, just indicate it + // is ok to continue. + if (initialized_ || in_progress_cache_initialized_) + return; + + base::RepeatingClosure post_init_callback = base::BindRepeating( + &DownloadManagerImpl::PostInitialization, weak_factory_.GetWeakPtr(), + DOWNLOAD_INITIALIZATION_DEPENDENCY_IN_PROGRESS_CACHE); + + if (delegate_) { + download::InProgressCache* in_progress_cache = + delegate_->GetInProgressCache(); + if (in_progress_cache) { + in_progress_cache->Initialize(post_init_callback); + return; + } + } + + BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, post_init_callback); } DownloadManagerDelegate* DownloadManagerImpl::GetDelegate() const { @@ -885,11 +914,33 @@ return item; } -void DownloadManagerImpl::PostInitialization() { - DCHECK(!initialized_); - initialized_ = true; - for (auto& observer : observers_) - observer.OnManagerInitialized(); +void DownloadManagerImpl::PostInitialization( + DownloadInitializationDependency dependency) { + // If initialization has occurred (ie. in tests), skip post init steps. + if (initialized_) + return; + + switch (dependency) { + case DOWNLOAD_INITIALIZATION_DEPENDENCY_HISTORY_DB: + history_db_initialized_ = true; + break; + case DOWNLOAD_INITIALIZATION_DEPENDENCY_IN_PROGRESS_CACHE: + in_progress_cache_initialized_ = true; + break; + case DOWNLOAD_INITIALIZATION_DEPENDENCY_NONE: + default: + NOTREACHED(); + break; + } + + // Download manager is only initialized if both history db and in progress + // cache are initialized. + initialized_ = history_db_initialized_ && in_progress_cache_initialized_; + + if (initialized_) { + for (auto& observer : observers_) + observer.OnManagerInitialized(); + } } bool DownloadManagerImpl::IsManagerInitialized() const {
diff --git a/content/browser/download/download_manager_impl.h b/content/browser/download/download_manager_impl.h index be70719..776f92d 100644 --- a/content/browser/download/download_manager_impl.h +++ b/content/browser/download/download_manager_impl.h
@@ -105,7 +105,7 @@ base::Time last_access_time, bool transient, const std::vector<DownloadItem::ReceivedSlice>& received_slices) override; - void PostInitialization() override; + void PostInitialization(DownloadInitializationDependency dependency) override; bool IsManagerInitialized() const override; int InProgressCount() const override; int NonMaliciousInProgressCount() const override; @@ -253,6 +253,10 @@ // True if the download manager has been initialized and loaded all the data. bool initialized_; + // Whether the history db and/or in progress cache are initialized. + bool history_db_initialized_; + bool in_progress_cache_initialized_; + // Observers that want to be notified of changes to the set of downloads. base::ObserverList<Observer> observers_;
diff --git a/content/public/browser/download_manager.h b/content/public/browser/download_manager.h index 2f625b2..63fcacb 100644 --- a/content/public/browser/download_manager.h +++ b/content/public/browser/download_manager.h
@@ -173,8 +173,17 @@ bool transient, const std::vector<DownloadItem::ReceivedSlice>& received_slices) = 0; - // Called when download manager has loaded all the data. - virtual void PostInitialization() = 0; + // Enum to describe which dependency was initialized in PostInitialization. + enum DownloadInitializationDependency { + DOWNLOAD_INITIALIZATION_DEPENDENCY_NONE, + DOWNLOAD_INITIALIZATION_DEPENDENCY_HISTORY_DB, + DOWNLOAD_INITIALIZATION_DEPENDENCY_IN_PROGRESS_CACHE, + }; + + // Called when download manager has loaded all the data, once when the history + // db is initialized and once when the in-progress cache is initialized. + virtual void PostInitialization( + DownloadInitializationDependency dependency) = 0; // Returns if the manager has been initialized and loaded all the data. virtual bool IsManagerInitialized() const = 0;
diff --git a/content/public/test/mock_download_manager.h b/content/public/test/mock_download_manager.h index c3001ee..fb96ef1e 100644 --- a/content/public/test/mock_download_manager.h +++ b/content/public/test/mock_download_manager.h
@@ -148,7 +148,8 @@ MOCK_METHOD1(MockCreateDownloadItem, DownloadItem*(CreateDownloadItemAdapter adapter)); - MOCK_METHOD0(PostInitialization, void()); + MOCK_METHOD1(PostInitialization, + void(DownloadInitializationDependency dependency)); MOCK_CONST_METHOD0(IsManagerInitialized, bool()); MOCK_CONST_METHOD0(InProgressCount, int()); MOCK_CONST_METHOD0(NonMaliciousInProgressCount, int());
diff --git a/content/shell/browser/layout_test/blink_test_controller.cc b/content/shell/browser/layout_test/blink_test_controller.cc index 0aecc9c..4bcad8e 100644 --- a/content/shell/browser/layout_test/blink_test_controller.cc +++ b/content/shell/browser/layout_test/blink_test_controller.cc
@@ -35,7 +35,6 @@ #include "content/common/page_state_serialization.h" #include "content/common/unique_name_helper.h" #include "content/public/browser/devtools_agent_host.h" -#include "content/public/browser/dom_storage_context.h" #include "content/public/browser/gpu_data_manager.h" #include "content/public/browser/navigation_controller.h" #include "content/public/browser/navigation_entry.h" @@ -568,8 +567,6 @@ IPC_MESSAGE_HANDLER(ShellViewHostMsg_SetPopupBlockingEnabled, OnSetPopupBlockingEnabled) IPC_MESSAGE_HANDLER(ShellViewHostMsg_TestFinished, OnTestFinished) - IPC_MESSAGE_HANDLER(ShellViewHostMsg_ClearDevToolsLocalStorage, - OnClearDevToolsLocalStorage) IPC_MESSAGE_HANDLER(ShellViewHostMsg_ShowDevTools, OnShowDevTools) IPC_MESSAGE_HANDLER(ShellViewHostMsg_EvaluateInDevTools, OnEvaluateInDevTools) @@ -955,16 +952,6 @@ LayoutTestContentBrowserClient::Get()->SetPopupBlockingEnabled(block_popups); } -void BlinkTestController::OnClearDevToolsLocalStorage() { - ShellBrowserContext* browser_context = - ShellContentBrowserClient::Get()->browser_context(); - StoragePartition* storage_partition = - BrowserContext::GetStoragePartition(browser_context, nullptr); - storage_partition->GetDOMStorageContext()->DeleteLocalStorage( - content::LayoutTestDevToolsBindings::GetDevToolsPathAsURL("") - .GetOrigin()); -} - void BlinkTestController::OnShowDevTools(const std::string& settings, const std::string& frontend_url) { devtools_window_ = SecondaryWindow();
diff --git a/content/shell/common/shell_messages.h b/content/shell/common/shell_messages.h index 4d5d3aae..6925ea0 100644 --- a/content/shell/common/shell_messages.h +++ b/content/shell/common/shell_messages.h
@@ -67,7 +67,6 @@ std::string /* message */) IPC_MESSAGE_ROUTED1(ShellViewHostMsg_PrintMessageToStderr, std::string /* message */) -IPC_MESSAGE_ROUTED0(ShellViewHostMsg_ClearDevToolsLocalStorage) IPC_MESSAGE_ROUTED2(ShellViewHostMsg_ShowDevTools, std::string /* settings */, std::string /* frontend_url */)
diff --git a/content/shell/renderer/layout_test/blink_test_runner.cc b/content/shell/renderer/layout_test/blink_test_runner.cc index f0130fa..8716062e 100644 --- a/content/shell/renderer/layout_test/blink_test_runner.cc +++ b/content/shell/renderer/layout_test/blink_test_runner.cc
@@ -407,10 +407,6 @@ ForceResizeRenderView(render_view(), new_size); } -void BlinkTestRunner::ClearDevToolsLocalStorage() { - Send(new ShellViewHostMsg_ClearDevToolsLocalStorage(routing_id())); -} - void BlinkTestRunner::ShowDevTools(const std::string& settings, const std::string& frontend_url) { Send(new ShellViewHostMsg_ShowDevTools(
diff --git a/content/shell/renderer/layout_test/blink_test_runner.h b/content/shell/renderer/layout_test/blink_test_runner.h index e393476..7576540 100644 --- a/content/shell/renderer/layout_test/blink_test_runner.h +++ b/content/shell/renderer/layout_test/blink_test_runner.h
@@ -90,7 +90,6 @@ void EnableAutoResizeMode(const blink::WebSize& min_size, const blink::WebSize& max_size) override; void DisableAutoResizeMode(const blink::WebSize& new_size) override; - void ClearDevToolsLocalStorage() override; void ShowDevTools(const std::string& settings, const std::string& frontend_url) override; void CloseDevTools() override;
diff --git a/content/shell/test_runner/test_interfaces.cc b/content/shell/test_runner/test_interfaces.cc index 67d0785..3bc75c96 100644 --- a/content/shell/test_runner/test_interfaces.cc +++ b/content/shell/test_runner/test_interfaces.cc
@@ -119,9 +119,6 @@ if (!initial_configuration) return; - if (is_devtools_test) - test_runner_->ClearDevToolsLocalStorage(); - bool is_legacy_devtools_test = is_devtools_test && spec.find("integration_test_runner.html") == std::string::npos;
diff --git a/content/shell/test_runner/test_runner.cc b/content/shell/test_runner/test_runner.cc index 27196ce8..b5136a39 100644 --- a/content/shell/test_runner/test_runner.cc +++ b/content/shell/test_runner/test_runner.cc
@@ -1992,10 +1992,6 @@ return midi_accessor_result_; } -void TestRunner::ClearDevToolsLocalStorage() { - delegate_->ClearDevToolsLocalStorage(); -} - void TestRunner::SetV8CacheDisabled(bool disabled) { if (!main_view_) { disable_v8_cache_ = disabled;
diff --git a/content/shell/test_runner/test_runner.h b/content/shell/test_runner/test_runner.h index 98fded0..3298cb0c 100644 --- a/content/shell/test_runner/test_runner.h +++ b/content/shell/test_runner/test_runner.h
@@ -111,7 +111,6 @@ std::string customDumpText() const; void ShowDevTools(const std::string& settings, const std::string& frontend_url); - void ClearDevToolsLocalStorage(); void SetV8CacheDisabled(bool); void setShouldDumpAsText(bool); void setShouldDumpAsMarkup(bool);
diff --git a/content/shell/test_runner/web_test_delegate.h b/content/shell/test_runner/web_test_delegate.h index 55697c8..74c3cc4 100644 --- a/content/shell/test_runner/web_test_delegate.h +++ b/content/shell/test_runner/web_test_delegate.h
@@ -128,9 +128,6 @@ const blink::WebSize& max_size) = 0; virtual void DisableAutoResizeMode(const blink::WebSize& new_size) = 0; - // Clears DevTools' localStorage when an inspector test is started. - virtual void ClearDevToolsLocalStorage() = 0; - // Opens and closes the inspector. virtual void ShowDevTools(const std::string& settings, const std::string& frontend_url) = 0;
diff --git a/docs/testing/layout_test_baseline_fallback.md b/docs/testing/layout_test_baseline_fallback.md index 7471c1e4..ef458bd7 100644 --- a/docs/testing/layout_test_baseline_fallback.md +++ b/docs/testing/layout_test_baseline_fallback.md
@@ -115,6 +115,12 @@ baseline to the virtual root because virtual platforms may have different results). +In addition, the optimizer also removes redundant all-PASS testharness.js +results. Such baselines are redundant when there are no other fallbacks later +on the search path (including if the all-PASS baselines are at root), because +`run-webkit-tests` assumes all-PASS testharness.js results when baselines can +not be found for a platform. + ### Rebaseline The fallback mechanism also affects the rebaseline tool (`webkit-patch
diff --git a/extensions/browser/api/declarative_net_request/ruleset_matcher.cc b/extensions/browser/api/declarative_net_request/ruleset_matcher.cc index a72b0c6..907dbac 100644 --- a/extensions/browser/api/declarative_net_request/ruleset_matcher.cc +++ b/extensions/browser/api/declarative_net_request/ruleset_matcher.cc
@@ -46,10 +46,6 @@ if (!base::PathExists(indexed_ruleset_path)) return kLoadErrorInvalidPath; - scoped_refptr<base::SequencedTaskRunner> deleter_task_runner = - base::CreateSequencedTaskRunnerWithTraits( - {base::MayBlock(), base::TaskPriority::BACKGROUND}); - // TODO(crbug.com/774271): Revisit mmap-ing the file. auto ruleset = std::make_unique<base::MemoryMappedFile>(); if (!ruleset->Initialize(indexed_ruleset_path,
diff --git a/extensions/common/BUILD.gn b/extensions/common/BUILD.gn index 521f0f8..ce1e9fd1 100644 --- a/extensions/common/BUILD.gn +++ b/extensions/common/BUILD.gn
@@ -36,9 +36,6 @@ "//mojo/common:common_custom_types", "//url/mojo:url_mojom_gurl", ] - - # TODO(crbug.com/699569): Convert to use the new JS bindings. - js_bindings_mode = "both" } # This must be a static library because extensions common depends on
diff --git a/extensions/renderer/api/mojo_private/mojo_private_unittest.cc b/extensions/renderer/api/mojo_private/mojo_private_unittest.cc index e73457e..9693bf28 100644 --- a/extensions/renderer/api/mojo_private/mojo_private_unittest.cc +++ b/extensions/renderer/api/mojo_private/mojo_private_unittest.cc
@@ -36,10 +36,8 @@ }; TEST_F(MojoPrivateApiTest, RequireAsync) { - env()->RegisterModule("add", - "define('add', [], function() {" - " return { Add: function(x, y) { return x + y; } };" - "});"); + env()->RegisterModule( + "add", "exports.$set('returnValue', function(x, y) { return x + y; });"); ASSERT_NO_FATAL_FAILURE( RunTest("mojo_private_unittest.js", "testRequireAsync")); }
diff --git a/extensions/renderer/resources/mime_handler_private_custom_bindings.js b/extensions/renderer/resources/mime_handler_private_custom_bindings.js index 262c549..6d09de8b 100644 --- a/extensions/renderer/resources/mime_handler_private_custom_bindings.js +++ b/extensions/renderer/resources/mime_handler_private_custom_bindings.js
@@ -14,7 +14,9 @@ 'Streams are only available from a mime handler view guest.'; var STREAM_ABORTED_ERROR = 'Stream has been aborted.'; -loadScript('mojo_bindings'); +if ((typeof mojo === 'undefined') || !mojo.bindingsLibraryInitialized) { + loadScript('mojo_bindings'); +} loadScript('extensions/common/api/mime_handler.mojom'); var servicePtr = new extensions.mimeHandler.MimeHandlerServicePtr;
diff --git a/extensions/renderer/resources/mojo_private_custom_bindings.js b/extensions/renderer/resources/mojo_private_custom_bindings.js index 548e3a3a..794471b 100644 --- a/extensions/renderer/resources/mojo_private_custom_bindings.js +++ b/extensions/renderer/resources/mojo_private_custom_bindings.js
@@ -12,7 +12,7 @@ let apiFunctions = bindingsAPI.apiFunctions; apiFunctions.setHandleRequest('requireAsync', function(moduleName) { - return requireAsync(moduleName); + return Promise.resolve(require(moduleName).returnValue); }); });
diff --git a/extensions/test/data/mojo_private_unittest.js b/extensions/test/data/mojo_private_unittest.js index 85a48da5..cfdc9db 100644 --- a/extensions/test/data/mojo_private_unittest.js +++ b/extensions/test/data/mojo_private_unittest.js
@@ -13,7 +13,7 @@ function testRequireAsync() { mojoPrivate.requireAsync('add').then( test.callbackPass(function(add) { - test.assertEq('function', typeof add.Add); + test.assertEq('function', typeof add); })); }, ], test.runTests, exports);
diff --git a/ios/third_party/material_components_ios/BUILD.gn b/ios/third_party/material_components_ios/BUILD.gn index c35a6386..0b9a080 100644 --- a/ios/third_party/material_components_ios/BUILD.gn +++ b/ios/third_party/material_components_ios/BUILD.gn
@@ -268,14 +268,10 @@ ":material_collection_cells_bundle", ":material_collections_bundle", ":material_component_ic_arrow_back_bundle", - "//ios/third_party/material_internationalization_ios:material_internationalization_ios+link", + "//ios/third_party/material_internationalization_ios", "//ios/third_party/material_text_accessibility_ios", ] - if (current_toolchain == default_toolchain) { - deps += [ "//ios/third_party/material_internationalization_ios:material_internationalization_ios+bundle" ] - } - foreach(icon_name, _icon_names) { deps += [ ":material_component_${icon_name}_bundle" ] }
diff --git a/ios/third_party/material_internationalization_ios/BUILD.gn b/ios/third_party/material_internationalization_ios/BUILD.gn index f20ab98..30058798 100644 --- a/ios/third_party/material_internationalization_ios/BUILD.gn +++ b/ios/third_party/material_internationalization_ios/BUILD.gn
@@ -9,10 +9,10 @@ config("config") { include_dirs = [ "src/Sources" ] visibility = [ ":material_internationalization_ios" ] + defines = [ "IS_BAZEL_BUILD" ] } -ios_framework_bundle("material_internationalization_ios") { - output_name = "MDFInternationalization" +source_set("material_internationalization_ios") { sources = [ "src/Sources/MDFInternationalization.h", "src/Sources/MDFRTL.h", @@ -22,7 +22,8 @@ "src/Sources/UIView+MaterialRTL.h", "src/Sources/UIView+MaterialRTL.m", ] - public_headers = [ + public = [ + "src/Sources/MDFInternationalization.h", "src/Sources/MDFRTL.h", "src/Sources/UIImage+MaterialRTL.h", "src/Sources/UIView+MaterialRTL.h", @@ -38,18 +39,20 @@ "//build/config/compiler:chromium_code", ] configs += [ + ":config", "//build/config/compiler:enable_arc", "//build/config/compiler:no_chromium_code", "//build/config/gcc:symbol_visibility_default", ] +} - _project_version = "1.0" - _bundle_identifier = - "$ios_app_bundle_id_prefix.$chromium_bundle_id.$output_name" - - info_plist = "src/Sources/Info.plist" - extra_substitutions = [ - "PRODUCT_BUNDLE_IDENTIFIER=$_bundle_identifier", - "CURRENT_PROJECT_VERSION=$_project_version", +# TODO(crbug.com/785248): remove those targets when downstream has been fixed +# to no longer use it but instead depend on :material_internationalization_ios. +group("material_internationalization_ios+link") { + public_deps = [ + ":material_internationalization_ios", ] } + +group("material_internationalization_ios:bundle") { +}
diff --git a/media/base/android/java/src/org/chromium/media/MediaCodecBridge.java b/media/base/android/java/src/org/chromium/media/MediaCodecBridge.java index a507f7a0..213b0fa 100644 --- a/media/base/android/java/src/org/chromium/media/MediaCodecBridge.java +++ b/media/base/android/java/src/org/chromium/media/MediaCodecBridge.java
@@ -22,6 +22,7 @@ import org.chromium.media.MediaCodecUtil.MimeTypes; import java.nio.ByteBuffer; +import java.nio.ByteOrder; /** * A MediaCodec wrapper for adapting the API and catching exceptions. @@ -52,6 +53,8 @@ private static final int BITRATE_ADJUSTMENT_FPS = 30; private static final int MAXIMUM_INITIAL_FPS = 30; + private static final int MAX_CHROMATICITY = 50000; // Defined in CTA-861.3. + protected MediaCodec mMediaCodec; private ByteBuffer[] mInputBuffers; @@ -662,6 +665,98 @@ } } + // TODO(sandv): Use color space matrix when android has support for it. + @TargetApi(Build.VERSION_CODES.N) + @CalledByNative + private static void setColorSpace(MediaFormat format, final int primaries, final int transfer, + final int matrix, final int range) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) { + Log.e(TAG, "HDR is not support before Android N"); + return; + } + + // media/base/video_color_space.h + + int colorStandard = -1; + switch (primaries) { + case 1: + colorStandard = MediaFormat.COLOR_STANDARD_BT709; + break; + case 4: // BT.470M. + case 5: // BT.470BG. + case 6: // SMPTE 170M. + case 7: // SMPTE 240M. + colorStandard = MediaFormat.COLOR_STANDARD_BT601_NTSC; + break; + case 9: + colorStandard = MediaFormat.COLOR_STANDARD_BT2020; + break; + } + if (colorStandard != -1) format.setInteger(MediaFormat.KEY_COLOR_STANDARD, colorStandard); + + int colorTransfer = -1; + switch (transfer) { + case 1: // BT.709. + case 6: // SMPTE 170M. + case 7: // SMPTE 240M. + colorTransfer = MediaFormat.COLOR_TRANSFER_SDR_VIDEO; + break; + case 8: + colorTransfer = MediaFormat.COLOR_TRANSFER_LINEAR; + break; + case 16: + colorTransfer = MediaFormat.COLOR_TRANSFER_ST2084; + break; + case 18: + colorTransfer = MediaFormat.COLOR_TRANSFER_HLG; + break; + } + if (colorTransfer != -1) format.setInteger(MediaFormat.KEY_COLOR_TRANSFER, colorTransfer); + + int colorRange = -1; + switch (range) { + case 1: + colorRange = MediaFormat.COLOR_RANGE_LIMITED; + break; + case 2: + colorRange = MediaFormat.COLOR_RANGE_FULL; + break; + } + if (colorRange != -1) format.setInteger(MediaFormat.KEY_COLOR_RANGE, colorRange); + } + + @TargetApi(Build.VERSION_CODES.N) + @CalledByNative + private static void setHdrMatadata(MediaFormat format, float primaryRChromaticityX, + float primaryRChromaticityY, float primaryGChromaticityX, float primaryGChromaticityY, + float primaryBChromaticityX, float primaryBChromaticityY, float whitePointChromaticityX, + float whitePointChromaticityY, float maxMasteringLuminance, float minMasteringLuminance, + int maxContentLuminance, int maxFrameAverageLuminance) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) { + Log.e(TAG, "HDR not support before Android N"); + return; + } + + ByteBuffer hdrStaticInfo = ByteBuffer.wrap(new byte[25]); + hdrStaticInfo.order(ByteOrder.LITTLE_ENDIAN); + hdrStaticInfo.put((byte) 0); // Type. + hdrStaticInfo.putShort((short) ((primaryRChromaticityX * MAX_CHROMATICITY) + 0.5f)); + hdrStaticInfo.putShort((short) ((primaryRChromaticityY * MAX_CHROMATICITY) + 0.5f)); + hdrStaticInfo.putShort((short) ((primaryGChromaticityX * MAX_CHROMATICITY) + 0.5f)); + hdrStaticInfo.putShort((short) ((primaryGChromaticityY * MAX_CHROMATICITY) + 0.5f)); + hdrStaticInfo.putShort((short) ((primaryBChromaticityX * MAX_CHROMATICITY) + 0.5f)); + hdrStaticInfo.putShort((short) ((primaryBChromaticityY * MAX_CHROMATICITY) + 0.5f)); + hdrStaticInfo.putShort((short) ((whitePointChromaticityX * MAX_CHROMATICITY) + 0.5f)); + hdrStaticInfo.putShort((short) ((whitePointChromaticityY * MAX_CHROMATICITY) + 0.5f)); + hdrStaticInfo.putShort((short) (maxMasteringLuminance + 0.5f)); + hdrStaticInfo.putShort((short) (minMasteringLuminance + 0.5f)); + hdrStaticInfo.putShort((short) maxContentLuminance); + hdrStaticInfo.putShort((short) maxFrameAverageLuminance); + + hdrStaticInfo.rewind(); + format.setByteBuffer(MediaFormat.KEY_HDR_STATIC_INFO, hdrStaticInfo); + } + @TargetApi(Build.VERSION_CODES.M) @CalledByNative private boolean setSurface(Surface surface) {
diff --git a/media/base/android/media_codec_bridge_impl.cc b/media/base/android/media_codec_bridge_impl.cc index a1d0df0..a7d0f56 100644 --- a/media/base/android/media_codec_bridge_impl.cc +++ b/media/base/android/media_codec_bridge_impl.cc
@@ -274,6 +274,26 @@ Java_MediaCodecBridge_setCodecSpecificData(env, j_format, 1, j_csd1); } + if (hdr_metadata && hdr_metadata.has_value()) { + Java_MediaCodecBridge_setColorSpace(env, j_format, + static_cast<int>(color_space.primaries), + static_cast<int>(color_space.transfer), + static_cast<int>(color_space.matrix), + static_cast<int>(color_space.range)); + + const ::media::HDRMetadata& metadata = hdr_metadata.value(); + const ::media::MasteringMetadata& mastering_metadata = + metadata.mastering_metadata; + Java_MediaCodecBridge_setHdrMatadata( + env, j_format, mastering_metadata.primary_r.x(), + mastering_metadata.primary_r.y(), mastering_metadata.primary_g.x(), + mastering_metadata.primary_g.y(), mastering_metadata.primary_b.x(), + mastering_metadata.primary_b.y(), mastering_metadata.white_point.x(), + mastering_metadata.white_point.y(), mastering_metadata.luminance_max, + mastering_metadata.luminance_min, metadata.max_content_light_level, + metadata.max_frame_average_light_level); + } + if (!Java_MediaCodecBridge_configureVideo(env, bridge->j_bridge_, j_format, surface, media_crypto, 0, allow_adaptive_playback)) {
diff --git a/media/filters/decrypting_demuxer_stream.cc b/media/filters/decrypting_demuxer_stream.cc index f83cced..332f78d 100644 --- a/media/filters/decrypting_demuxer_stream.cc +++ b/media/filters/decrypting_demuxer_stream.cc
@@ -58,7 +58,7 @@ InitializeDecoderConfig(); if (!cdm_context->GetDecryptor()) { - MEDIA_LOG(DEBUG, media_log_) << GetDisplayName() << ": no decryptor"; + DVLOG(2) << __func__ << ": no decryptor"; state_ = kUninitialized; base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED); return;
diff --git a/media/filters/decrypting_demuxer_stream_unittest.cc b/media/filters/decrypting_demuxer_stream_unittest.cc index 84e992a..9a0543a0 100644 --- a/media/filters/decrypting_demuxer_stream_unittest.cc +++ b/media/filters/decrypting_demuxer_stream_unittest.cc
@@ -313,7 +313,6 @@ AudioDecoderConfig input_config(kCodecVorbis, kSampleFormatPlanarF32, CHANNEL_LAYOUT_STEREO, 44100, EmptyExtraData(), AesCtrEncryptionScheme()); - EXPECT_MEDIA_LOG(HasSubstr("DecryptingDemuxerStream: no decryptor")); InitializeAudioAndExpectStatus(input_config, DECODER_ERROR_NOT_SUPPORTED); }
diff --git a/media/mojo/interfaces/BUILD.gn b/media/mojo/interfaces/BUILD.gn index d49ed181..d7bacb7 100644 --- a/media/mojo/interfaces/BUILD.gn +++ b/media/mojo/interfaces/BUILD.gn
@@ -69,9 +69,6 @@ sources = [ "remoting_common.mojom", ] - - # TODO(crbug.com/699569): Convert to use the new JS bindings. - use_new_js_bindings = false } mojom("mirror_service_remoting") { @@ -82,9 +79,6 @@ public_deps = [ ":remoting_common", ] - - # TODO(crbug.com/699569): Convert to use the new JS bindings. - use_new_js_bindings = false } mojom("remoting") {
diff --git a/media/renderers/video_renderer_impl.cc b/media/renderers/video_renderer_impl.cc index ab0581e..ce19950a 100644 --- a/media/renderers/video_renderer_impl.cc +++ b/media/renderers/video_renderer_impl.cc
@@ -976,7 +976,8 @@ MEDIA_LOG(INFO, media_log_) << "Updating max buffered frames to " << max_buffered_frames << ", average frame duration: " << frame_duration.InMillisecondsF() - << "ms, average read duration: " << read_durations_.Average() + << "ms, average read duration: " + << read_durations_.Average().InMillisecondsF() << "ms, max read duration: " << read_durations_.max().InMillisecondsF() << "ms. [" << min_buffered_frames_ << ", " << max_buffered_frames_ << "]";
diff --git a/mojo/common/BUILD.gn b/mojo/common/BUILD.gn index b43da6b..d9c8672 100644 --- a/mojo/common/BUILD.gn +++ b/mojo/common/BUILD.gn
@@ -31,9 +31,6 @@ if (is_win) { sources += [ "logfont_win.mojom" ] } - - # TODO(crbug.com/699569): Convert to use the new JS bindings. - js_bindings_mode = "both" } mojom("read_only_buffer") {
diff --git a/net/cert/ev_root_ca_metadata.cc b/net/cert/ev_root_ca_metadata.cc index 85c84e1a..8880c1c 100644 --- a/net/cert/ev_root_ca_metadata.cc +++ b/net/cert/ev_root_ca_metadata.cc
@@ -18,9 +18,9 @@ #include "net/der/input.h" #if defined(USE_NSS_CERTS) #include "crypto/nss_util.h" -#elif defined(PLATFORM_USES_CHROMIUM_EV_METADATA) -#include "third_party/boringssl/src/include/openssl/asn1.h" -#include "third_party/boringssl/src/include/openssl/obj.h" +#elif defined(PLATFORM_USES_CHROMIUM_EV_METADATA) || defined(OS_WIN) +#include "third_party/boringssl/src/include/openssl/bytestring.h" +#include "third_party/boringssl/src/include/openssl/mem.h" #endif namespace net { @@ -836,20 +836,13 @@ bool ConvertBytesToDottedString(const der::Input& policy_oid, std::string* dotted) { - ASN1_OBJECT obj; - memset(&obj, 0, sizeof(obj)); - obj.data = policy_oid.UnsafeData(); - obj.length = policy_oid.Length(); - - // Determine the length of the dotted string. - int len = OBJ_obj2txt(nullptr, 0, &obj, 1 /* dont_search_names */); - if (len == -1) + CBS cbs; + CBS_init(&cbs, policy_oid.UnsafeData(), policy_oid.Length()); + bssl::UniquePtr<char> text(CBS_asn1_oid_to_text(&cbs)); + if (!text) return false; - - // Write the dotted string into |*dotted|. - dotted->resize(len + 1); - return len == OBJ_obj2txt(&(*dotted)[0], static_cast<int>(dotted->size()), - &obj, 1 /* dont_search_names */); + dotted->assign(text.get()); + return true; } } // namespace @@ -938,12 +931,16 @@ namespace { std::string OIDStringToDER(const char* policy) { - bssl::UniquePtr<ASN1_OBJECT> obj( - OBJ_txt2obj(policy, 1 /* dont_search_names */)); - if (!obj) + uint8_t* der; + size_t len; + bssl::ScopedCBB cbb; + if (!CBB_init(cbb.get(), 32) || + !CBB_add_asn1_oid_from_text(cbb.get(), policy, strlen(policy)) || + !CBB_finish(cbb.get(), &der, &len)) { return std::string(); - - return std::string(reinterpret_cast<const char*>(obj->data), obj->length); + } + bssl::UniquePtr<uint8_t> delete_der(der); + return std::string(reinterpret_cast<const char*>(der), len); } } // namespace
diff --git a/net/interfaces/BUILD.gn b/net/interfaces/BUILD.gn index cbccdbc..07782465 100644 --- a/net/interfaces/BUILD.gn +++ b/net/interfaces/BUILD.gn
@@ -13,7 +13,4 @@ public_deps = [ "//url/mojo:url_mojom_gurl", ] - - # TODO(crbug.com/699569): Convert to use the new JS bindings. - use_new_js_bindings = false }
diff --git a/net/nqe/network_id.cc b/net/nqe/network_id.cc index 3e5fbe5e..be8d350 100644 --- a/net/nqe/network_id.cc +++ b/net/nqe/network_id.cc
@@ -17,28 +17,39 @@ // static NetworkID NetworkID::FromString(const std::string& network_id) { std::string base64_decoded; - if (!base::Base64Decode(network_id, &base64_decoded)) - return NetworkID(NetworkChangeNotifier::CONNECTION_UNKNOWN, std::string()); + if (!base::Base64Decode(network_id, &base64_decoded)) { + return NetworkID(NetworkChangeNotifier::CONNECTION_UNKNOWN, std::string(), + INT32_MIN); + } NetworkIDProto network_id_proto; - if (!network_id_proto.ParseFromString(base64_decoded)) - return NetworkID(NetworkChangeNotifier::CONNECTION_UNKNOWN, std::string()); + if (!network_id_proto.ParseFromString(base64_decoded)) { + return NetworkID(NetworkChangeNotifier::CONNECTION_UNKNOWN, std::string(), + INT32_MIN); + } return NetworkID(static_cast<NetworkChangeNotifier::ConnectionType>( network_id_proto.connection_type()), - network_id_proto.id()); + network_id_proto.id(), network_id_proto.signal_strength()); } NetworkID::NetworkID(NetworkChangeNotifier::ConnectionType type, - const std::string& id) - : type(type), id(id) {} + const std::string& id, + int32_t signal_strength) + : type(type), id(id), signal_strength(signal_strength) { + // A valid value of |signal_strength| must be between 0 and 4 (both + // inclusive). + DCHECK((0 <= signal_strength && 4 >= signal_strength) || + (INT32_MIN == signal_strength)); +} NetworkID::NetworkID(const NetworkID& other) = default; NetworkID::~NetworkID() = default; bool NetworkID::operator==(const NetworkID& other) const { - return type == other.type && id == other.id; + return type == other.type && id == other.id && + signal_strength == other.signal_strength; } bool NetworkID::operator!=(const NetworkID& other) const { @@ -49,13 +60,15 @@ // Overloaded to support ordered collections. bool NetworkID::operator<(const NetworkID& other) const { - return std::tie(type, id) < std::tie(other.type, other.id); + return std::tie(type, id, signal_strength) < + std::tie(other.type, other.id, other.signal_strength); } std::string NetworkID::ToString() const { NetworkIDProto network_id_proto; network_id_proto.set_connection_type(static_cast<int>(type)); network_id_proto.set_id(id); + network_id_proto.set_signal_strength(signal_strength); std::string serialized_network_id; if (!network_id_proto.SerializeToString(&serialized_network_id))
diff --git a/net/nqe/network_id.h b/net/nqe/network_id.h index 65f52d1..618210c8 100644 --- a/net/nqe/network_id.h +++ b/net/nqe/network_id.h
@@ -23,7 +23,9 @@ struct NET_EXPORT_PRIVATE NetworkID { static NetworkID FromString(const std::string& network_id); - NetworkID(NetworkChangeNotifier::ConnectionType type, const std::string& id); + NetworkID(NetworkChangeNotifier::ConnectionType type, + const std::string& id, + int32_t signal_strength); NetworkID(const NetworkID& other); ~NetworkID(); @@ -50,6 +52,14 @@ // - An empty string in all other cases or if the network name is not // exposed by platform APIs. std::string id; + + // Signal strength of the network. Set to INT32_MIN when the value is + // unavailable. Otherwise, must be between 0 and 4 (both inclusive). This may + // take into account many different radio technology inputs. 0 represents very + // poor signal strength while 4 represents a very strong signal strength. The + // range is capped between 0 and 4 to ensure that a change in the value + // indicates a non-negligible change in the signal quality. + int32_t signal_strength; }; } // namespace internal
diff --git a/net/nqe/network_id_unittest.cc b/net/nqe/network_id_unittest.cc index 3ee6998..68e5d01 100644 --- a/net/nqe/network_id_unittest.cc +++ b/net/nqe/network_id_unittest.cc
@@ -5,6 +5,7 @@ #include "net/nqe/network_id.h" #include <string> + #include "base/strings/string_number_conversions.h" #include "net/base/network_change_notifier.h" #include "testing/gtest/include/gtest/gtest.h" @@ -17,7 +18,7 @@ TEST(NetworkIDTest, TestSerialize) { nqe::internal::NetworkID network_id(NetworkChangeNotifier::CONNECTION_2G, - "test1"); + "test1", 2); std::string serialized = network_id.ToString(); EXPECT_EQ(network_id, NetworkID::FromString(serialized)); }
diff --git a/net/nqe/network_quality_estimator.cc b/net/nqe/network_quality_estimator.cc index d46131d..84ef525 100644 --- a/net/nqe/network_quality_estimator.cc +++ b/net/nqe/network_quality_estimator.cc
@@ -222,7 +222,8 @@ last_connection_change_(tick_clock_->NowTicks()), current_network_id_(nqe::internal::NetworkID( NetworkChangeNotifier::ConnectionType::CONNECTION_UNKNOWN, - std::string())), + std::string(), + INT32_MIN)), http_downstream_throughput_kbps_observations_( params_.get(), tick_clock_.get(), @@ -413,7 +414,8 @@ return; DCHECK_GE(observed_http_rtt, base::TimeDelta()); Observation http_rtt_observation(observed_http_rtt.InMilliseconds(), - tick_clock_->NowTicks(), signal_strength_, + tick_clock_->NowTicks(), + current_network_id_.signal_strength, NETWORK_QUALITY_OBSERVATION_SOURCE_HTTP); AddAndNotifyObserversOfRTT(http_rtt_observation); throughput_analyzer_->NotifyBytesRead(request); @@ -785,7 +787,7 @@ } } #endif // OS_ANDROID - signal_strength_.reset(); + current_network_id_.signal_strength = INT32_MIN; min_signal_strength_since_connection_change_.reset(); max_signal_strength_since_connection_change_.reset(); network_quality_ = nqe::internal::NetworkQuality(); @@ -841,29 +843,42 @@ external_estimate_provider_->Update(); } +int32_t NetworkQualityEstimator::GetCurrentSignalStrength() const { + DCHECK(thread_checker_.CalledOnValidThread()); + +#if defined(OS_ANDROID) + if (params_->weight_multiplier_per_signal_strength_level() >= 1.0) + return INT32_MIN; + if (!NetworkChangeNotifier::IsConnectionCellular(current_network_id_.type)) + return INT32_MIN; + return android::cellular_signal_strength::GetSignalStrengthLevel().value_or( + INT32_MIN); +#endif // OS_ANDROID + + return INT32_MIN; +} + void NetworkQualityEstimator::UpdateSignalStrength() { DCHECK(thread_checker_.CalledOnValidThread()); - signal_strength_.reset(); -#if defined(OS_ANDROID) - if (params_->weight_multiplier_per_signal_strength_level() >= 1.0) - return; - if (!NetworkChangeNotifier::IsConnectionCellular(current_network_id_.type)) + int32_t past_signal_strength = current_network_id_.signal_strength; + int32_t new_signal_strength = GetCurrentSignalStrength(); + + // Check if there is no change in the signal strength. + if (past_signal_strength == new_signal_strength) return; - signal_strength_ = - android::cellular_signal_strength::GetSignalStrengthLevel(); - - if (!signal_strength_) + current_network_id_.signal_strength = new_signal_strength; + // Check if the signal strength is unavailable. + if (current_network_id_.signal_strength == INT32_MIN) return; min_signal_strength_since_connection_change_ = std::min(min_signal_strength_since_connection_change_.value_or(INT32_MAX), - signal_strength_.value()); + current_network_id_.signal_strength); max_signal_strength_since_connection_change_ = std::max(max_signal_strength_since_connection_change_.value_or(INT32_MIN), - signal_strength_.value()); -#endif // OS_ANDROID + current_network_id_.signal_strength); } void NetworkQualityEstimator::RecordMetricsOnConnectionTypeChanged() const { @@ -1475,14 +1490,14 @@ case nqe::internal::ObservationCategory::kHttp: return base::TimeDelta::FromMilliseconds( http_rtt_ms_observations_ - .GetPercentile(start_time, signal_strength_, percentile, - observations_count) + .GetPercentile(start_time, current_network_id_.signal_strength, + percentile, observations_count) .value_or(nqe::internal::INVALID_RTT_THROUGHPUT)); case nqe::internal::ObservationCategory::kTransport: return base::TimeDelta::FromMilliseconds( transport_rtt_ms_observations_ - .GetPercentile(start_time, signal_strength_, percentile, - observations_count) + .GetPercentile(start_time, current_network_id_.signal_strength, + percentile, observations_count) .value_or(nqe::internal::INVALID_RTT_THROUGHPUT)); } } @@ -1506,7 +1521,8 @@ // Throughput observations are sorted by kbps from slowest to fastest, // thus a higher percentile throughput will be faster than a lower one. return http_downstream_throughput_kbps_observations_ - .GetPercentile(start_time, signal_strength_, 100 - percentile, nullptr) + .GetPercentile(start_time, current_network_id_.signal_strength, + 100 - percentile, nullptr) .value_or(nqe::internal::INVALID_RTT_THROUGHPUT); } @@ -1524,7 +1540,7 @@ // (that are approximate to begin with). while (true) { nqe::internal::NetworkID network_id( - NetworkChangeNotifier::GetConnectionType(), std::string()); + NetworkChangeNotifier::GetConnectionType(), std::string(), INT32_MIN); switch (network_id.type) { case NetworkChangeNotifier::ConnectionType::CONNECTION_UNKNOWN: @@ -1631,7 +1647,8 @@ EXTERNAL_ESTIMATE_PROVIDER_STATUS_RTT_AVAILABLE); UMA_HISTOGRAM_TIMES("NQE.ExternalEstimateProvider.RTT", rtt); Observation rtt_observation( - rtt.InMilliseconds(), tick_clock_->NowTicks(), signal_strength_, + rtt.InMilliseconds(), tick_clock_->NowTicks(), + current_network_id_.signal_strength, NETWORK_QUALITY_OBSERVATION_SOURCE_HTTP_EXTERNAL_ESTIMATE); external_estimate_provider_quality_.set_http_rtt(rtt); AddAndNotifyObserversOfRTT(rtt_observation); @@ -1643,7 +1660,8 @@ UMA_HISTOGRAM_COUNTS_1M("NQE.ExternalEstimateProvider.DownlinkBandwidth", downstream_throughput_kbps); Observation throughput_observation( - downstream_throughput_kbps, tick_clock_->NowTicks(), signal_strength_, + downstream_throughput_kbps, tick_clock_->NowTicks(), + current_network_id_.signal_strength, NETWORK_QUALITY_OBSERVATION_SOURCE_HTTP_EXTERNAL_ESTIMATE); external_estimate_provider_quality_.set_downstream_throughput_kbps( downstream_throughput_kbps); @@ -1675,7 +1693,7 @@ DCHECK_NE(nqe::internal::InvalidRTT(), rtt); Observation observation(rtt.InMilliseconds(), tick_clock_->NowTicks(), - signal_strength_, + current_network_id_.signal_strength, ProtocolSourceToObservationSource(protocol), host); AddAndNotifyObserversOfRTT(observation); @@ -1776,7 +1794,7 @@ DCHECK_NE(nqe::internal::INVALID_RTT_THROUGHPUT, downstream_kbps); Observation throughput_observation(downstream_kbps, tick_clock_->NowTicks(), - signal_strength_, + current_network_id_.signal_strength, NETWORK_QUALITY_OBSERVATION_SOURCE_HTTP); AddAndNotifyObserversOfThroughput(throughput_observation); }
diff --git a/net/nqe/network_quality_estimator.h b/net/nqe/network_quality_estimator.h index c00e163..86f0a3f1 100644 --- a/net/nqe/network_quality_estimator.h +++ b/net/nqe/network_quality_estimator.h
@@ -346,6 +346,15 @@ return ComputeIncreaseInTransportRTT(); } + // Returns the current network signal strength by querying the platform APIs. + // Set to INT32_MIN when the value is unavailable. Otherwise, must be between + // 0 and 4 (both inclusive). This may take into account many different radio + // technology inputs. 0 represents very poor signal strength while 4 + // represents a very strong signal strength. The range is capped between 0 and + // 4 to ensure that a change in the value indicates a non-negligible change in + // the signal quality. + virtual int32_t GetCurrentSignalStrength() const; + // Observer list for RTT or throughput estimates. Protected for testing. base::ObserverList<RTTAndThroughputEstimatesObserver> rtt_and_throughput_estimates_observer_list_; @@ -651,11 +660,6 @@ // |effective_connection_type_recomputation_interval_| ago). EffectiveConnectionType effective_connection_type_; - // Last known value of the wireless signal strength level. If the signal - // strength level is available, the value is set to between 0 and 4, both - // inclusive. If the value is unavailable, |signal_strength_| has null value. - base::Optional<int32_t> signal_strength_; - // Minimum and maximum signal strength level observed since last connection // change. Updated on connection change and main frame requests. base::Optional<int32_t> min_signal_strength_since_connection_change_;
diff --git a/net/nqe/network_quality_estimator_test_util.cc b/net/nqe/network_quality_estimator_test_util.cc index d9d21f7..af618f9b 100644 --- a/net/nqe/network_quality_estimator_test_util.cc +++ b/net/nqe/network_quality_estimator_test_util.cc
@@ -340,7 +340,8 @@ nqe::internal::NetworkID TestNetworkQualityEstimator::GetCurrentNetworkID() const { - return nqe::internal::NetworkID(current_network_type_, current_network_id_); + return nqe::internal::NetworkID(current_network_type_, current_network_id_, + INT32_MIN); } TestNetworkQualityEstimator::LocalHttpTestServer::LocalHttpTestServer(
diff --git a/net/nqe/network_quality_estimator_unittest.cc b/net/nqe/network_quality_estimator_unittest.cc index b8854e3..54d0209 100644 --- a/net/nqe/network_quality_estimator_unittest.cc +++ b/net/nqe/network_quality_estimator_unittest.cc
@@ -2870,7 +2870,8 @@ public: TestNetworkQualitiesCacheObserver() : network_id_(net::NetworkChangeNotifier::CONNECTION_UNKNOWN, - std::string()), + std::string(), + INT32_MIN), notification_received_(0) {} ~TestNetworkQualitiesCacheObserver() override = default; @@ -3080,13 +3081,13 @@ std::map<nqe::internal::NetworkID, nqe::internal::CachedNetworkQuality> read_prefs; read_prefs[nqe::internal::NetworkID(NetworkChangeNotifier::CONNECTION_WIFI, - "test_ect_2g")] = + "test_ect_2g", INT32_MIN)] = nqe::internal::CachedNetworkQuality(EFFECTIVE_CONNECTION_TYPE_2G); read_prefs[nqe::internal::NetworkID(NetworkChangeNotifier::CONNECTION_WIFI, - "test_ect_slow_2g")] = + "test_ect_slow_2g", INT32_MIN)] = nqe::internal::CachedNetworkQuality(EFFECTIVE_CONNECTION_TYPE_SLOW_2G); read_prefs[nqe::internal::NetworkID(NetworkChangeNotifier::CONNECTION_4G, - "test_ect_4g")] = + "test_ect_4g", INT32_MIN)] = nqe::internal::CachedNetworkQuality(EFFECTIVE_CONNECTION_TYPE_4G); std::map<std::string, std::string> variation_params; @@ -3143,7 +3144,8 @@ // Compare the ECT stored in prefs with the observer's last entry. EXPECT_EQ( read_prefs[nqe::internal::NetworkID( - NetworkChangeNotifier::CONNECTION_WIFI, network_name)] + NetworkChangeNotifier::CONNECTION_WIFI, network_name, + INT32_MIN)] .effective_connection_type(), effective_connection_type_observer.effective_connection_types().back()); @@ -3170,7 +3172,8 @@ // Compare with the last entry. EXPECT_EQ( read_prefs[nqe::internal::NetworkID( - NetworkChangeNotifier::CONNECTION_WIFI, network_name)] + NetworkChangeNotifier::CONNECTION_WIFI, network_name, + INT32_MIN)] .effective_connection_type(), effective_connection_type_observer.effective_connection_types().back()); @@ -3191,13 +3194,13 @@ std::map<nqe::internal::NetworkID, nqe::internal::CachedNetworkQuality> read_prefs; read_prefs[nqe::internal::NetworkID(NetworkChangeNotifier::CONNECTION_WIFI, - "test_ect_2g")] = + "test_ect_2g", INT32_MIN)] = nqe::internal::CachedNetworkQuality(EFFECTIVE_CONNECTION_TYPE_2G); read_prefs[nqe::internal::NetworkID(NetworkChangeNotifier::CONNECTION_WIFI, - "test_ect_slow_2g")] = + "test_ect_slow_2g", INT32_MIN)] = nqe::internal::CachedNetworkQuality(EFFECTIVE_CONNECTION_TYPE_SLOW_2G); read_prefs[nqe::internal::NetworkID(NetworkChangeNotifier::CONNECTION_4G, - "test_ect_4g")] = + "test_ect_4g", INT32_MIN)] = nqe::internal::CachedNetworkQuality(EFFECTIVE_CONNECTION_TYPE_4G); std::map<std::string, std::string> variation_params; @@ -3241,7 +3244,7 @@ nqe::internal::CachedNetworkQuality cached_network_quality; EXPECT_TRUE(estimator.network_quality_store_->GetById( nqe::internal::NetworkID(NetworkChangeNotifier::CONNECTION_WIFI, - "test_ect_2g"), + "test_ect_2g", INT32_MIN), &cached_network_quality)); EXPECT_EQ(EFFECTIVE_CONNECTION_TYPE_2G, cached_network_quality.effective_connection_type()); @@ -3409,7 +3412,7 @@ std::map<nqe::internal::NetworkID, nqe::internal::CachedNetworkQuality> read_prefs; read_prefs[nqe::internal::NetworkID(NetworkChangeNotifier::CONNECTION_WIFI, - "test_2g")] = + "test_2g", INT32_MIN)] = nqe::internal::CachedNetworkQuality(EFFECTIVE_CONNECTION_TYPE_2G); std::map<std::string, std::string> variation_params;
diff --git a/net/nqe/network_quality_store.cc b/net/nqe/network_quality_store.cc index 490f0703..b1e01fe9 100644 --- a/net/nqe/network_quality_store.cc +++ b/net/nqe/network_quality_store.cc
@@ -71,16 +71,50 @@ bool NetworkQualityStore::GetById( const nqe::internal::NetworkID& network_id, - nqe::internal::CachedNetworkQuality* cached_network_quality) { + nqe::internal::CachedNetworkQuality* cached_network_quality) const { DCHECK(thread_checker_.CalledOnValidThread()); - CachedNetworkQualities::const_iterator it = - cached_network_qualities_.find(network_id); + // |matching_it| points to the entry that has the same connection type and + // id as |network_id|, and has the signal strength closest to the signal + // stength of |network_id|. + CachedNetworkQualities::const_iterator matching_it = + cached_network_qualities_.end(); + int matching_it_diff_signal_strength = INT32_MAX; - if (it == cached_network_qualities_.end()) + for (CachedNetworkQualities::const_iterator it = + cached_network_qualities_.begin(); + it != cached_network_qualities_.end(); ++it) { + if (network_id.type != it->first.type || network_id.id != it->first.id) { + // The |type| and |id| must match. + continue; + } + + if (network_id.signal_strength == INT32_MIN) { + // Current network does not have a valid signal strength value. Return the + // entry without searching for the entry with the closest signal strength. + matching_it = it; + break; + } + + // Determine if the signal strength of |network_id| is closer to the + // signal strength of the network at |it| then that of the network at + // |matching_it|. + int diff_signal_strength = + std::abs(network_id.signal_strength - it->first.signal_strength); + if (it->first.signal_strength == INT32_MIN) + diff_signal_strength = INT32_MAX; + + if (matching_it == cached_network_qualities_.end() || + diff_signal_strength < matching_it_diff_signal_strength) { + matching_it = it; + matching_it_diff_signal_strength = diff_signal_strength; + } + } + + if (matching_it == cached_network_qualities_.end()) return false; - *cached_network_quality = it->second; + *cached_network_quality = matching_it->second; return true; }
diff --git a/net/nqe/network_quality_store.h b/net/nqe/network_quality_store.h index 6213da7..8f00d202 100644 --- a/net/nqe/network_quality_store.h +++ b/net/nqe/network_quality_store.h
@@ -56,8 +56,9 @@ // Returns true if the network quality estimate was successfully read // for a network with ID |network_id|, and sets |cached_network_quality| to // the estimate read. - bool GetById(const nqe::internal::NetworkID& network_id, - nqe::internal::CachedNetworkQuality* cached_network_quality); + bool GetById( + const nqe::internal::NetworkID& network_id, + nqe::internal::CachedNetworkQuality* cached_network_quality) const; // Adds and removes |observer| from the list of cache observers. The // observers are notified on the same thread on which it was added. Addition
diff --git a/net/nqe/network_quality_store_unittest.cc b/net/nqe/network_quality_store_unittest.cc index 40ab2f4..c654924 100644 --- a/net/nqe/network_quality_store_unittest.cc +++ b/net/nqe/network_quality_store_unittest.cc
@@ -38,7 +38,7 @@ // Entry should not be added. nqe::internal::NetworkID network_id(NetworkChangeNotifier::CONNECTION_2G, - "test1"); + "test1", 0); nqe::internal::CachedNetworkQuality read_network_quality; network_quality_store.Add(network_id, cached_network_quality_unknown); EXPECT_FALSE( @@ -48,7 +48,7 @@ { // Entry will be added for (2G, "test1"). nqe::internal::NetworkID network_id(NetworkChangeNotifier::CONNECTION_2G, - "test1"); + "test1", 0); nqe::internal::CachedNetworkQuality read_network_quality; network_quality_store.Add(network_id, cached_network_quality_2g_test1); EXPECT_TRUE( @@ -60,7 +60,7 @@ { // Entry will be added for (2G, "test2"). nqe::internal::NetworkID network_id(NetworkChangeNotifier::CONNECTION_2G, - "test2"); + "test2", 0); nqe::internal::CachedNetworkQuality read_network_quality; nqe::internal::CachedNetworkQuality cached_network_quality( tick_clock.NowTicks(), @@ -77,7 +77,7 @@ { // Entry will be added for (3G, "test3"). nqe::internal::NetworkID network_id(NetworkChangeNotifier::CONNECTION_3G, - "test3"); + "test3", 0); nqe::internal::CachedNetworkQuality read_network_quality; nqe::internal::CachedNetworkQuality cached_network_quality( tick_clock.NowTicks(), @@ -94,7 +94,7 @@ { // Entry will not be added for (Unknown, ""). nqe::internal::NetworkID network_id( - NetworkChangeNotifier::CONNECTION_UNKNOWN, ""); + NetworkChangeNotifier::CONNECTION_UNKNOWN, "", 0); nqe::internal::CachedNetworkQuality read_network_quality; nqe::internal::CachedNetworkQuality set_network_quality( tick_clock.NowTicks(), @@ -109,7 +109,7 @@ { // Existing entry will be read for (2G, "test1"). nqe::internal::NetworkID network_id(NetworkChangeNotifier::CONNECTION_2G, - "test1"); + "test1", 0); nqe::internal::CachedNetworkQuality read_network_quality; EXPECT_TRUE( network_quality_store.GetById(network_id, &read_network_quality)); @@ -120,7 +120,7 @@ { // Existing entry will be overwritten for (2G, "test1"). nqe::internal::NetworkID network_id(NetworkChangeNotifier::CONNECTION_2G, - "test1"); + "test1", 0); nqe::internal::CachedNetworkQuality read_network_quality; const nqe::internal::CachedNetworkQuality cached_network_quality( tick_clock.NowTicks(), @@ -137,13 +137,96 @@ { // No entry should exist for (2G, "test4"). nqe::internal::NetworkID network_id(NetworkChangeNotifier::CONNECTION_2G, - "test4"); + "test4", 0); nqe::internal::CachedNetworkQuality read_network_quality; EXPECT_FALSE( network_quality_store.GetById(network_id, &read_network_quality)); } } +TEST(NetworkQualityStoreTest, TestCachingClosestSignalStrength) { + nqe::internal::NetworkQualityStore network_quality_store; + base::SimpleTestTickClock tick_clock; + + // Cached network quality for network with NetworkID (2G, "test1"). + const nqe::internal::CachedNetworkQuality cached_network_quality_strength_1( + tick_clock.NowTicks(), + nqe::internal::NetworkQuality(base::TimeDelta::FromSeconds(1), + base::TimeDelta::FromSeconds(1), 1), + EFFECTIVE_CONNECTION_TYPE_2G); + + const nqe::internal::CachedNetworkQuality cached_network_quality_strength_3( + tick_clock.NowTicks(), + nqe::internal::NetworkQuality(base::TimeDelta::FromSeconds(3), + base::TimeDelta::FromSeconds(3), 3), + EFFECTIVE_CONNECTION_TYPE_2G); + + { + // Entry will be added for (2G, "test1") with signal strength value of 1. + nqe::internal::NetworkID network_id(NetworkChangeNotifier::CONNECTION_2G, + "test1", 1); + nqe::internal::CachedNetworkQuality read_network_quality; + network_quality_store.Add(network_id, cached_network_quality_strength_1); + EXPECT_TRUE( + network_quality_store.GetById(network_id, &read_network_quality)); + EXPECT_EQ(cached_network_quality_strength_1.network_quality(), + read_network_quality.network_quality()); + } + + { + // Entry will be added for (2G, "test1") with signal strength value of 3. + nqe::internal::NetworkID network_id(NetworkChangeNotifier::CONNECTION_2G, + "test1", 3); + nqe::internal::CachedNetworkQuality read_network_quality; + network_quality_store.Add(network_id, cached_network_quality_strength_3); + EXPECT_TRUE( + network_quality_store.GetById(network_id, &read_network_quality)); + EXPECT_EQ(cached_network_quality_strength_3.network_quality(), + read_network_quality.network_quality()); + } + + { + // Now with cached entries for signal strengths 1 and 3, verify across the + // range of strength values that the closest value match will be returned + // when looking up (2G, "test1", signal_strength). + for (int32_t signal_strength = 0; signal_strength <= 4; ++signal_strength) { + nqe::internal::CachedNetworkQuality expected_cached_network_quality = + signal_strength <= 2 ? cached_network_quality_strength_1 + : cached_network_quality_strength_3; + nqe::internal::NetworkID network_id(NetworkChangeNotifier::CONNECTION_2G, + "test1", signal_strength); + nqe::internal::CachedNetworkQuality read_network_quality; + EXPECT_TRUE( + network_quality_store.GetById(network_id, &read_network_quality)); + EXPECT_EQ(expected_cached_network_quality.network_quality(), + read_network_quality.network_quality()); + } + } + + { + // Existing entry will be read for (2G, "test1", INT32_MIN). + // The first entry in the store matching (2G, "test1", *) would be returned. + int32_t signal_strength = INT32_MIN; + nqe::internal::NetworkID network_id(NetworkChangeNotifier::CONNECTION_2G, + "test1", signal_strength); + nqe::internal::CachedNetworkQuality read_network_quality; + EXPECT_TRUE( + network_quality_store.GetById(network_id, &read_network_quality)); + EXPECT_TRUE((cached_network_quality_strength_1.network_quality() == + read_network_quality.network_quality()) || + (cached_network_quality_strength_3.network_quality() == + read_network_quality.network_quality())); + } + + { + // No entry should exist for (2G, "test4"). + nqe::internal::NetworkID network_id(NetworkChangeNotifier::CONNECTION_2G, + "test4", 0); + nqe::internal::CachedNetworkQuality read_network_quality; + EXPECT_FALSE( + network_quality_store.GetById(network_id, &read_network_quality)); + } +} // Tests if the cache size remains bounded. Also, ensure that the cache is // LRU. TEST(NetworkQualityStoreTest, TestLRUCacheMaximumSize) { @@ -161,7 +244,7 @@ for (size_t i = 0; i < network_count; ++i) { nqe::internal::NetworkID network_id(NetworkChangeNotifier::CONNECTION_2G, - "test" + base::IntToString(i)); + "test" + base::IntToString(i), 0); const nqe::internal::CachedNetworkQuality network_quality( tick_clock.NowTicks(), @@ -176,7 +259,7 @@ size_t cache_match_count = 0; for (size_t i = 0; i < network_count; ++i) { nqe::internal::NetworkID network_id(NetworkChangeNotifier::CONNECTION_2G, - "test" + base::IntToString(i)); + "test" + base::IntToString(i), 0); nqe::internal::CachedNetworkQuality read_network_quality( tick_clock.NowTicks(),
diff --git a/net/nqe/proto/network_id_proto.proto b/net/nqe/proto/network_id_proto.proto index 28c7fb0..a6d217a 100644 --- a/net/nqe/proto/network_id_proto.proto +++ b/net/nqe/proto/network_id_proto.proto
@@ -9,7 +9,8 @@ package net.nqe.internal; // NetworkIDProto contains data that can be used to uniquely identify a network -// type. Next id: 3 +// type. +// Next id: 4 message NetworkIDProto { // Connection type of the network mapped from // net::NetworkChangeNotifier::ConnectionType. @@ -17,4 +18,11 @@ // Name of this network. This is set to WiFi SSID or the MCCMNC of the // network. optional string id = 2; + // Signal strength of the network. Set to INT32_MIN when the value is + // unavailable. Otherwise, must be between 0 and 4 (both inclusive). This may + // take into account many different radio technology inputs. 0 represents very + // poor signal strength while 4 represents a very strong signal strength. + // The range is capped between 0 and 4 to ensure that a change in the value + // indicates a non-negligible change in the signal quality. + optional int32 signal_strength = 3; }
diff --git a/net/quic/chromium/quic_stream_factory_fuzzer.cc b/net/quic/chromium/quic_stream_factory_fuzzer.cc index 8e34162..1939324 100644 --- a/net/quic/chromium/quic_stream_factory_fuzzer.cc +++ b/net/quic/chromium/quic_stream_factory_fuzzer.cc
@@ -116,20 +116,19 @@ bool migrate_sessions_on_network_change = false; bool migrate_sessions_early = false; bool migrate_sessions_early_v2 = false; + bool migrate_sessions_on_network_change_v2 = false; - bool migrate_sessions_on_network_change_v2 = data_provider.ConsumeBool(); - - if (migrate_sessions_on_network_change_v2) { - migrate_sessions_early_v2 = data_provider.ConsumeBool(); - } else { - migrate_sessions_on_network_change = data_provider.ConsumeBool(); - if (migrate_sessions_on_network_change) - migrate_sessions_early = data_provider.ConsumeBool(); + if (!close_sessions_on_ip_change) { + migrate_sessions_on_network_change_v2 = data_provider.ConsumeBool(); + if (migrate_sessions_on_network_change_v2) { + migrate_sessions_early_v2 = data_provider.ConsumeBool(); + } else { + migrate_sessions_on_network_change = data_provider.ConsumeBool(); + if (migrate_sessions_on_network_change) + migrate_sessions_early = data_provider.ConsumeBool(); + } } - if (migrate_sessions_on_network_change) - close_sessions_on_ip_change = false; - std::unique_ptr<QuicStreamFactory> factory = std::make_unique<QuicStreamFactory>( env->net_log.net_log(), &host_resolver, env->ssl_config_service.get(),
diff --git a/net/spdy/chromium/http2_push_promise_index.cc b/net/spdy/chromium/http2_push_promise_index.cc index 4f5f7d1..bcd65e3d 100644 --- a/net/spdy/chromium/http2_push_promise_index.cc +++ b/net/spdy/chromium/http2_push_promise_index.cc
@@ -6,8 +6,6 @@ #include <utility> -#include "net/spdy/chromium/spdy_session.h" - namespace net { Http2PushPromiseIndex::Http2PushPromiseIndex() = default; @@ -21,73 +19,42 @@ const GURL& url) const { DCHECK(!url.is_empty()); - UnclaimedPushedStreamMap::const_iterator url_it = - unclaimed_pushed_streams_.find(url); + UnclaimedPushedStreamMap::const_iterator it = + unclaimed_pushed_streams_.lower_bound(std::make_pair(url, nullptr)); - if (url_it == unclaimed_pushed_streams_.end()) { + if (it == unclaimed_pushed_streams_.end() || it->first != url) { return base::WeakPtr<SpdySession>(); } DCHECK(url.SchemeIsCryptographic()); - for (const auto& session : url_it->second) { - const SpdySessionKey& spdy_session_key = session->spdy_session_key(); - if (spdy_session_key.proxy_server() != key.proxy_server() || - spdy_session_key.privacy_mode() != key.privacy_mode()) { - continue; + while (it != unclaimed_pushed_streams_.end() && it->first == url) { + if (it->second->ValidatePushedStream(key)) { + it->second->OnPushedStreamClaimed(url); + return it->second->GetWeakPtrToSession(); } - if (!session->VerifyDomainAuthentication(key.host_port_pair().host())) { - continue; - } - return session; + ++it; } return base::WeakPtr<SpdySession>(); } -void Http2PushPromiseIndex::RegisterUnclaimedPushedStream( - const GURL& url, - base::WeakPtr<SpdySession> spdy_session) { +void Http2PushPromiseIndex::RegisterUnclaimedPushedStream(const GURL& url, + Delegate* delegate) { DCHECK(!url.is_empty()); DCHECK(url.SchemeIsCryptographic()); - // Use lower_bound() so that if key does not exists, then insertion can use - // its return value as a hint. - UnclaimedPushedStreamMap::iterator url_it = - unclaimed_pushed_streams_.lower_bound(url); - if (url_it == unclaimed_pushed_streams_.end() || url_it->first != url) { - WeakSessionList list; - list.push_back(std::move(spdy_session)); - UnclaimedPushedStreamMap::value_type value(url, std::move(list)); - unclaimed_pushed_streams_.insert(url_it, std::move(value)); - return; - } - url_it->second.push_back(spdy_session); + unclaimed_pushed_streams_.insert(std::make_pair(url, delegate)); } void Http2PushPromiseIndex::UnregisterUnclaimedPushedStream( const GURL& url, - SpdySession* spdy_session) { + Delegate* delegate) { DCHECK(!url.is_empty()); DCHECK(url.SchemeIsCryptographic()); - UnclaimedPushedStreamMap::iterator url_it = - unclaimed_pushed_streams_.find(url); - if (url_it == unclaimed_pushed_streams_.end()) { - NOTREACHED(); - return; - } - for (WeakSessionList::iterator it = url_it->second.begin(); - it != url_it->second.end();) { - if (it->get() == spdy_session) { - url_it->second.erase(it); - if (url_it->second.empty()) { - unclaimed_pushed_streams_.erase(url_it); - } - return; - } - ++it; - } - NOTREACHED(); + size_t result = + unclaimed_pushed_streams_.erase(std::make_pair(url, delegate)); + DCHECK_EQ(1u, result); } } // namespace net
diff --git a/net/spdy/chromium/http2_push_promise_index.h b/net/spdy/chromium/http2_push_promise_index.h index a50ef42..cbc3441 100644 --- a/net/spdy/chromium/http2_push_promise_index.h +++ b/net/spdy/chromium/http2_push_promise_index.h
@@ -5,8 +5,7 @@ #ifndef NET_SPDY_CHROMIUM_HTTP2_PUSH_PROMISE_INDEX_H_ #define NET_SPDY_CHROMIUM_HTTP2_PUSH_PROMISE_INDEX_H_ -#include <map> -#include <vector> +#include <set> #include "base/macros.h" #include "base/memory/weak_ptr.h" @@ -26,31 +25,53 @@ // Only pushed streams with cryptographic schemes (for example, https) are // allowed to be shared across connections. Non-cryptographic scheme pushes // (for example, http) are fully managed within each SpdySession. +// TODO(bnc): Move unclaimed pushed stream management out of SpdySession, +// regardless of scheme, to avoid redundant bookkeeping and complicated +// interactions between SpdySession::UnclaimedPushedStreamContainer and +// Http2PushPromiseIndex. https://crbug.com/791054. class NET_EXPORT Http2PushPromiseIndex { public: + // Interface for validating pushed streams, signaling when a pushed stream is + // claimed, and generating weak pointer. + class NET_EXPORT Delegate { + public: + Delegate() {} + virtual ~Delegate() {} + + // Return true if the pushed stream can be used for a request with |key|. + virtual bool ValidatePushedStream(const SpdySessionKey& key) const = 0; + + // Called when a pushed stream is claimed. + virtual void OnPushedStreamClaimed(const GURL& url) = 0; + + // Generate weak pointer. + virtual base::WeakPtr<SpdySession> GetWeakPtrToSession() = 0; + + private: + DISALLOW_COPY_AND_ASSIGN(Delegate); + }; + Http2PushPromiseIndex(); ~Http2PushPromiseIndex(); // Returns a session with |key| that has an unclaimed push stream for |url| if - // such exists. Returns nullptr otherwise. + // such exists. Makes no guarantee on which one it returns if there are + // multiple. Returns nullptr if no such session exists. base::WeakPtr<SpdySession> Find(const SpdySessionKey& key, const GURL& url) const; - // (Un)registers a SpdySession with an unclaimed pushed stream for |url|. - void RegisterUnclaimedPushedStream(const GURL& url, - base::WeakPtr<SpdySession> spdy_session); - void UnregisterUnclaimedPushedStream(const GURL& url, - SpdySession* spdy_session); + // (Un)registers a Delegate with an unclaimed pushed stream for |url|. + // Caller must make sure |delegate| stays valid by unregistering the exact + // same entry before |delegate| is destroyed. + void RegisterUnclaimedPushedStream(const GURL& url, Delegate* delegate); + void UnregisterUnclaimedPushedStream(const GURL& url, Delegate* delegate); private: - typedef std::vector<base::WeakPtr<SpdySession>> WeakSessionList; - typedef std::map<GURL, WeakSessionList> UnclaimedPushedStreamMap; + using UnclaimedPushedStreamMap = std::set<std::pair<GURL, Delegate*>>; - // A multimap of all SpdySessions that have an unclaimed pushed stream for a - // GURL. SpdySession must unregister its streams before destruction, - // therefore all weak pointers must be valid. A single SpdySession can only - // have at most one pushed stream for each GURL, but it is possible that - // multiple SpdySessions have pushed streams for the same GURL. + // A collection of all unclaimed pushed streams. Delegate must unregister its + // streams before destruction, so that all pointers remain valid. It is + // possible that multiple Delegates have pushed streams for the same GURL. UnclaimedPushedStreamMap unclaimed_pushed_streams_; DISALLOW_COPY_AND_ASSIGN(Http2PushPromiseIndex);
diff --git a/net/spdy/chromium/http2_push_promise_index_test.cc b/net/spdy/chromium/http2_push_promise_index_test.cc index d1cd077..2bc9c7e 100644 --- a/net/spdy/chromium/http2_push_promise_index_test.cc +++ b/net/spdy/chromium/http2_push_promise_index_test.cc
@@ -73,12 +73,12 @@ EXPECT_FALSE(index_.Find(key1_, url1_)); EXPECT_FALSE(index_.Find(key2_, url2_)); - index_.RegisterUnclaimedPushedStream(url1_, spdy_session1); + index_.RegisterUnclaimedPushedStream(url1_, spdy_session1.get()); EXPECT_EQ(spdy_session1.get(), index_.Find(key1_, url1_).get()); EXPECT_FALSE(index_.Find(key2_, url2_)); - index_.RegisterUnclaimedPushedStream(url2_, spdy_session2); + index_.RegisterUnclaimedPushedStream(url2_, spdy_session2.get()); EXPECT_EQ(spdy_session1.get(), index_.Find(key1_, url1_).get()); EXPECT_EQ(spdy_session2.get(), index_.Find(key2_, url2_).get()); @@ -131,7 +131,7 @@ EXPECT_FALSE(index_.Find(key1_, url2_)); EXPECT_FALSE(index_.Find(key2_, url2_)); - index_.RegisterUnclaimedPushedStream(url1_, spdy_session1); + index_.RegisterUnclaimedPushedStream(url1_, spdy_session1.get()); // Note that Find() only uses its SpdySessionKey argument to verify proxy and // privacy mode. Cross-origin pooling is supported, therefore HostPortPair of @@ -141,11 +141,14 @@ EXPECT_FALSE(index_.Find(key1_, url2_)); EXPECT_FALSE(index_.Find(key2_, url2_)); - index_.RegisterUnclaimedPushedStream(url1_, spdy_session2); + index_.RegisterUnclaimedPushedStream(url1_, spdy_session2.get()); - // Find returns the first SpdySession if there are multiple for the same URL. - EXPECT_EQ(spdy_session1.get(), index_.Find(key1_, url1_).get()); - EXPECT_EQ(spdy_session1.get(), index_.Find(key2_, url1_).get()); + // Find() makes no guarantee about which SpdySession it returns if there are + // multiple for the same URL. + SpdySession* result = index_.Find(key1_, url1_).get(); + EXPECT_TRUE(result == spdy_session1.get() || result == spdy_session2.get()); + result = index_.Find(key2_, url1_).get(); + EXPECT_TRUE(result == spdy_session1.get() || result == spdy_session2.get()); EXPECT_FALSE(index_.Find(key1_, url2_)); EXPECT_FALSE(index_.Find(key2_, url2_));
diff --git a/net/spdy/chromium/spdy_session.cc b/net/spdy/chromium/spdy_session.cc index 4b248c89..f0eac8d 100644 --- a/net/spdy/chromium/spdy_session.cc +++ b/net/spdy/chromium/spdy_session.cc
@@ -912,7 +912,7 @@ READ_STATE_DO_READ, OK)); } -bool SpdySession::VerifyDomainAuthentication(const SpdyString& domain) { +bool SpdySession::VerifyDomainAuthentication(const SpdyString& domain) const { if (availability_state_ == STATE_DRAINING) return false; @@ -1352,6 +1352,28 @@ return false; } +bool SpdySession::ValidatePushedStream(const SpdySessionKey& key) const { + return key.proxy_server() == spdy_session_key_.proxy_server() && + key.privacy_mode() == spdy_session_key_.privacy_mode() && + VerifyDomainAuthentication(key.host_port_pair().host()); +} + +void SpdySession::OnPushedStreamClaimed(const GURL& url) { + UnclaimedPushedStreamContainer::const_iterator unclaimed_it = + unclaimed_pushed_streams_.find(url); + // This is only possible in tests. + // TODO(bnc): Change to DCHECK once Http2PushPromiseIndexTest stops using + // actual SpdySession instances. https://crbug.com/791055. + if (unclaimed_it == unclaimed_pushed_streams_.end()) + return; + + LogPushStreamClaimed(url, unclaimed_it->second); +} + +base::WeakPtr<SpdySession> SpdySession::GetWeakPtrToSession() { + return GetWeakPtr(); +} + size_t SpdySession::DumpMemoryStats(StreamSocket::SocketMemoryStats* stats, bool* is_session_active) const { // TODO(xunjieli): Include |pending_create_stream_queues_| when WeakPtr is @@ -1415,7 +1437,7 @@ // Only allow cross-origin push for https resources. if (url.SchemeIsCryptographic()) { spdy_session_->pool_->push_promise_index()->RegisterUnclaimedPushedStream( - url, spdy_session_->GetWeakPtr()); + url, spdy_session_); } return true; } @@ -2432,11 +2454,9 @@ return nullptr; } - SpdyStream* stream = active_it->second; - net_log_.AddEvent( - NetLogEventType::HTTP2_STREAM_ADOPTED_PUSH_STREAM, - base::Bind(&NetLogSpdyAdoptedPushStreamCallback, stream_id, &url)); - return stream; + LogPushStreamClaimed(url, stream_id); + + return active_it->second; } void SpdySession::RecordPingRTTHistogram(base::TimeDelta duration) { @@ -2553,6 +2573,13 @@ // LogAbandonedActiveStream() will increment the counters. } +void SpdySession::LogPushStreamClaimed(const GURL& url, + SpdyStreamId stream_id) { + net_log_.AddEvent( + NetLogEventType::HTTP2_STREAM_ADOPTED_PUSH_STREAM, + base::Bind(&NetLogSpdyAdoptedPushStreamCallback, stream_id, &url)); +} + void SpdySession::LogAbandonedActiveStream(ActiveStreamMap::const_iterator it, Error status) { DCHECK_GT(it->first, 0u);
diff --git a/net/spdy/chromium/spdy_session.h b/net/spdy/chromium/spdy_session.h index d90c2b9d..0e173b4 100644 --- a/net/spdy/chromium/spdy_session.h +++ b/net/spdy/chromium/spdy_session.h
@@ -234,7 +234,8 @@ class NET_EXPORT SpdySession : public BufferedSpdyFramerVisitorInterface, public SpdyFramerDebugVisitorInterface, public MultiplexedSession, - public HigherLayeredPool { + public HigherLayeredPool, + public Http2PushPromiseIndex::Delegate { public: // TODO(akalin): Use base::TickClock when it becomes available. typedef base::TimeTicks (*TimeFunc)(void); @@ -316,7 +317,7 @@ // TODO(wtc): rename this function and the Net.SpdyIPPoolDomainMatch // histogram because this function does more than verifying domain // authentication now. - bool VerifyDomainAuthentication(const SpdyString& domain); + bool VerifyDomainAuthentication(const SpdyString& domain) const; // Pushes the given producer into the write queue for // |stream|. |stream| is guaranteed to be activated before the @@ -493,12 +494,17 @@ // standards for TLS. bool HasAcceptableTransportSecurity() const; - // Must be used only by |pool_|. + // Must be used only by |pool_| (including |pool_.push_promise_index_|). base::WeakPtr<SpdySession> GetWeakPtr(); // HigherLayeredPool implementation: bool CloseOneIdleConnection() override; + // Http2PushPromiseIndex::Delegate implementation: + bool ValidatePushedStream(const SpdySessionKey& key) const override; + void OnPushedStreamClaimed(const GURL& url) override; + base::WeakPtr<SpdySession> GetWeakPtrToSession() override; + // Dumps memory allocation stats to |stats|. Sets |*is_session_active| to // indicate whether session is active. // |stats| can be assumed as being default initialized upon entry. @@ -822,6 +828,9 @@ // reason other than being requested to by the stream. void LogAbandonedStream(SpdyStream* stream, Error status); + // Called when a pushed stream is claimed by a request. + void LogPushStreamClaimed(const GURL& url, SpdyStreamId stream_id); + // Called right before closing an active stream for a reason other // than being requested to by the stream. void LogAbandonedActiveStream(ActiveStreamMap::const_iterator it,
diff --git a/testing/buildbot/chromium.android.json b/testing/buildbot/chromium.android.json index f19c2cd..91945b2b 100644 --- a/testing/buildbot/chromium.android.json +++ b/testing/buildbot/chromium.android.json
@@ -2164,10 +2164,10 @@ "test": "components_policy_junit_tests" }, { - "test": "components_web_restrictions_junit_tests" + "test": "components_variations_junit_tests" }, { - "test": "components_variations_junit_tests" + "test": "components_web_restrictions_junit_tests" }, { "test": "content_junit_tests" @@ -3713,10 +3713,10 @@ "test": "components_policy_junit_tests" }, { - "test": "components_web_restrictions_junit_tests" + "test": "components_variations_junit_tests" }, { - "test": "components_variations_junit_tests" + "test": "components_web_restrictions_junit_tests" }, { "test": "content_junit_tests" @@ -5206,6 +5206,138 @@ "test": "cc_unittests" }, { + "args": [ + "--gs-results-bucket=chromium-result-details" + ], + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "chrome_public_test_apk" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "LMY48I", + "device_type": "hammerhead" + } + ], + "expiration": 10800, + "hard_timeout": 1800, + "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" + } + ], + "shards": 10 + }, + "test": "chrome_public_test_apk" + }, + { + "args": [ + "--shared-prefs-file=//chrome/android/shared_preference_files/test/vr_cardboard_skipdon_setupcomplete.json", + "--additional-apk=//third_party/gvr-android-sdk/test-apks/vr_services/vr_services_current.apk", + "--gs-results-bucket=chromium-result-details" + ], + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "chrome_public_test_vr_apk" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "LMY48I", + "device_type": "hammerhead" + } + ], + "expiration": 10800, + "hard_timeout": 1920, + "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": "chrome_public_test_vr_apk" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details" + ], + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "chrome_sync_shell_test_apk" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "LMY48I", + "device_type": "hammerhead" + } + ], + "expiration": 10800, + "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": "chrome_sync_shell_test_apk" + }, + { "merge": { "args": [ "--bucket", @@ -5328,6 +5460,50 @@ "test": "content_browsertests" }, { + "args": [ + "--gs-results-bucket=chromium-result-details" + ], + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "content_shell_test_apk" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "LMY48I", + "device_type": "hammerhead" + } + ], + "expiration": 10800, + "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" + } + ], + "shards": 2 + }, + "test": "content_shell_test_apk" + }, + { "merge": { "args": [ "--bucket", @@ -6218,182 +6394,6 @@ "--bucket", "chromium-result-details", "--test-name", - "chrome_public_test_apk" - ], - "script": "//build/android/pylib/results/presentation/test_results_presentation.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/luci/logdog/butler/${platform}", - "location": "bin", - "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" - } - ], - "dimension_sets": [ - { - "device_os": "LMY48I", - "device_type": "hammerhead" - } - ], - "expiration": 10800, - "hard_timeout": 1800, - "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" - } - ], - "shards": 10 - }, - "test": "chrome_public_test_apk" - }, - { - "args": [ - "--shared-prefs-file=//chrome/android/shared_preference_files/test/vr_cardboard_skipdon_setupcomplete.json", - "--additional-apk=//third_party/gvr-android-sdk/test-apks/vr_services/vr_services_current.apk", - "--gs-results-bucket=chromium-result-details" - ], - "merge": { - "args": [ - "--bucket", - "chromium-result-details", - "--test-name", - "chrome_public_test_vr_apk" - ], - "script": "//build/android/pylib/results/presentation/test_results_presentation.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/luci/logdog/butler/${platform}", - "location": "bin", - "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" - } - ], - "dimension_sets": [ - { - "device_os": "LMY48I", - "device_type": "hammerhead" - } - ], - "expiration": 10800, - "hard_timeout": 1920, - "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": "chrome_public_test_vr_apk" - }, - { - "args": [ - "--gs-results-bucket=chromium-result-details" - ], - "merge": { - "args": [ - "--bucket", - "chromium-result-details", - "--test-name", - "chrome_sync_shell_test_apk" - ], - "script": "//build/android/pylib/results/presentation/test_results_presentation.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/luci/logdog/butler/${platform}", - "location": "bin", - "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" - } - ], - "dimension_sets": [ - { - "device_os": "LMY48I", - "device_type": "hammerhead" - } - ], - "expiration": 10800, - "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": "chrome_sync_shell_test_apk" - }, - { - "args": [ - "--gs-results-bucket=chromium-result-details" - ], - "merge": { - "args": [ - "--bucket", - "chromium-result-details", - "--test-name", - "content_shell_test_apk" - ], - "script": "//build/android/pylib/results/presentation/test_results_presentation.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/luci/logdog/butler/${platform}", - "location": "bin", - "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" - } - ], - "dimension_sets": [ - { - "device_os": "LMY48I", - "device_type": "hammerhead" - } - ], - "expiration": 10800, - "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" - } - ], - "shards": 2 - }, - "test": "content_shell_test_apk" - }, - { - "args": [ - "--gs-results-bucket=chromium-result-details" - ], - "merge": { - "args": [ - "--bucket", - "chromium-result-details", - "--test-name", "webview_instrumentation_test_apk" ], "script": "//build/android/pylib/results/presentation/test_results_presentation.py" @@ -7271,8 +7271,8 @@ "device_type": "flo" } ], - "expiration": "10800", - "hard_timeout": "300", + "expiration": 10800, + "hard_timeout": 300, "output_links": [ { "link": [ @@ -11797,8 +11797,8 @@ "device_type": "flo" } ], - "expiration": "10800", - "hard_timeout": "300", + "expiration": 10800, + "hard_timeout": 300, "output_links": [ { "link": [
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json index fdcd4ff9..f5af41d 100644 --- a/testing/buildbot/chromium.fyi.json +++ b/testing/buildbot/chromium.fyi.json
@@ -4580,18 +4580,6 @@ "can_use_on_swarming_builders": true }, "test": "content_browsertests" - }, - { - "args": [ - "--enable-viz", - "--test-launcher-filter-file=../../testing/buildbot/filters/mojo.fyi.viz.content_browsertests.filter" - ], - "name": "viz_content_browsertests", - "swarming": { - "can_use_on_swarming_builders": true, - "shards": 2 - }, - "test": "content_browsertests" } ], "isolated_scripts": [
diff --git a/testing/buildbot/chromium.linux.json b/testing/buildbot/chromium.linux.json index 4779202..7928278e 100644 --- a/testing/buildbot/chromium.linux.json +++ b/testing/buildbot/chromium.linux.json
@@ -1504,10 +1504,10 @@ "test": "components_policy_junit_tests" }, { - "test": "components_web_restrictions_junit_tests" + "test": "components_variations_junit_tests" }, { - "test": "components_variations_junit_tests" + "test": "components_web_restrictions_junit_tests" }, { "test": "content_junit_tests" @@ -3022,10 +3022,10 @@ "test": "components_policy_junit_tests" }, { - "test": "components_web_restrictions_junit_tests" + "test": "components_variations_junit_tests" }, { - "test": "components_variations_junit_tests" + "test": "components_web_restrictions_junit_tests" }, { "test": "content_junit_tests"
diff --git a/testing/buildbot/filters/mojo.fyi.mash.browser_tests.filter b/testing/buildbot/filters/mojo.fyi.mash.browser_tests.filter index cd53f7b..ea38a16 100644 --- a/testing/buildbot/filters/mojo.fyi.mash.browser_tests.filter +++ b/testing/buildbot/filters/mojo.fyi.mash.browser_tests.filter
@@ -57,7 +57,7 @@ -AutomationManagerAuraBrowserTest.* # profile_destroyer.cc(57) Check failed: hosts.empty() || profile->IsOffTheRecord() || profile->HasOffTheRecordProfile() || content::RenderProcessHost::run_renderer_in_process(). Profile still has 1 hosts --BluetoothPairingUITest.* +-BluetoothPairingDialogTest.* -DemoAppLauncherTest.* -LoginWebDialogTest.* @@ -127,12 +127,8 @@ # TODO: Very slow (>25 seconds) and occasional timeouts. -ExecuteScriptApiTest/DestructiveScriptTest.* -# WindowPortMus check failed in fullscreen test: -# window_mus_type() == WindowMusType::TOP_LEVEL_IN_WM || window_mus_type() == WindowMusType::EMBED_IN_OWNER. -# http://crbug.com/786544 --ExtensionInstallUIBrowserTest.* --ImmersiveModeBrowserViewTest.* --WebstoreInlineInstallerTest.* +# Fails: immersive_controller->IsRevealed() returns false. +# http://crbug.com/791148 -ZoomBubbleBrowserTest.* # ozone_platform.cc(61) Check failed: instance_. OzonePlatform is not initialized
diff --git a/testing/buildbot/manage.py b/testing/buildbot/manage.py index dce6dd9..d36ff906 100755 --- a/testing/buildbot/manage.py +++ b/testing/buildbot/manage.py
@@ -42,13 +42,8 @@ # OS dimensions go into the recipe, they're set in the json file, and # jelly bean devices are in the pool. For now, just blacklist. 'Jelly Bean Tester', - 'KitKat Tablet Tester', 'Lollipop Consumer Tester', 'Lollipop Low-end Tester', - 'Lollipop Phone Tester', - 'Lollipop Tablet Tester', - 'Marshmallow 64 bit Tester', - 'Marshmallow Tablet Tester', # Android bots need custom dimension_sets entries for swarming, and capacity # is not there yet -- so don't let manage.py add swarming automatically there.
diff --git a/testing/test_env.py b/testing/test_env.py index 284185d5..76192d31 100755 --- a/testing/test_env.py +++ b/testing/test_env.py
@@ -172,14 +172,22 @@ def run_executable(cmd, env): """Runs an executable with: + - CHROME_HEADLESS set to indicate that the test is running on a + bot and shouldn't do anything interactive like show modal dialogs. - environment variable CR_SOURCE_ROOT set to the root directory. - environment variable LANGUAGE to en_US.UTF-8. - environment variable CHROME_DEVEL_SANDBOX set - Reuses sys.executable automatically. """ - extra_env = {} - # Many tests assume a English interface... - extra_env['LANG'] = 'en_US.UTF-8' + extra_env = { + # Set to indicate that the executable is running non-interactively on + # a bot. + 'CHROME_HEADLESS': '1', + + # Many tests assume a English interface... + 'LANG': 'en_US.UTF-8', + } + # Used by base/base_paths_linux.cc as an override. Just make sure the default # logic is used. env.pop('CR_SOURCE_ROOT', None)
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/root-layer-scrolls b/third_party/WebKit/LayoutTests/FlagExpectations/root-layer-scrolls index c546c81..313a61f 100644 --- a/third_party/WebKit/LayoutTests/FlagExpectations/root-layer-scrolls +++ b/third_party/WebKit/LayoutTests/FlagExpectations/root-layer-scrolls
@@ -9,8 +9,6 @@ crbug.com/417782 fast/dom/scroll-reveal-left-overflow.html [ Failure ] crbug.com/417782 fast/dom/scroll-reveal-top-overflow.html [ Failure ] crbug.com/417782 fast/events/clientXY-in-zoom-and-scroll.html [ Failure ] -crbug.com/417782 fast/events/drag-and-drop-autoscroll-frameset.html [ Timeout ] -crbug.com/417782 fast/events/drag-and-drop-autoscroll-mainframe.html [ Timeout ] crbug.com/417782 fast/events/pointerevents/pointer-event-mouse-coords-in-zoom-and-scroll.html [ Failure ] crbug.com/417782 fast/events/scale-and-scroll-iframe-window.html [ Failure ] crbug.com/417782 fast/events/touch/gesture/gesture-tap-frame-scrolled.html [ Failure ] @@ -90,9 +88,6 @@ crbug.com/417782 virtual/threaded/http/tests/devtools/tracing/timeline-paint/timeline-paint.js [ Failure ] # Tests known to be flaky -crbug.com/417782 virtual/mouseevent_fractional/fast/events/drag-and-drop-autoscroll-frameset.html [ Timeout Failure ] -crbug.com/417782 virtual/mouseevent_fractional/fast/events/drag-and-drop-autoscroll-inner-frame.html [ Timeout Failure ] -crbug.com/417782 virtual/mouseevent_fractional/fast/events/drag-and-drop-autoscroll-mainframe.html [ Timeout Failure ] crbug.com/417782 virtual/mouseevent_fractional/fast/events/mouse-coords-in-zoom-and-scroll.html [ Failure Timeout ] crbug.com/417782 virtual/mouseevent_fractional/fast/events/mouse-right-coords-in-zoom-and-scroll-right.html [ Failure Timeout ] crbug.com/417782 fast/events/pointerevents/pointer-event-pen-coords-in-zoom-and-scroll.html [ Failure Timeout ]
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations index f7a3490..064e5bd 100644 --- a/third_party/WebKit/LayoutTests/TestExpectations +++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -86,10 +86,8 @@ crbug.com/771643 virtual/spv175/compositing/fixed-body-background-positioned.html [ Failure Pass ] crbug.com/771643 virtual/spv175/compositing/geometry/repaint-foreground-layer.html [ Crash ] crbug.com/771643 virtual/spv175/compositing/images/direct-image-dynamic-border-radius.html [ Failure ] -crbug.com/771643 virtual/spv175/compositing/masks/direct-image-mask.html [ Failure ] crbug.com/771643 virtual/spv175/compositing/masks/mask-with-added-filters.html [ Failure Pass ] crbug.com/771643 virtual/spv175/compositing/masks/mask-with-removed-filters.html [ Failure ] -crbug.com/771643 virtual/spv175/compositing/masks/masked-ancestor.html [ Failure ] crbug.com/771643 virtual/spv175/compositing/masks/multiple-masks.html [ Failure ] crbug.com/771643 virtual/spv175/compositing/masks/simple-composited-mask.html [ Failure ] crbug.com/771643 virtual/spv175/compositing/overflow/border-radius-on-grandparent-composited-grandchild.html [ Failure ] @@ -115,10 +113,8 @@ crbug.com/771643 virtual/spv175/compositing/squashing/squash-with-ancestor-reflection.html [ Failure ] crbug.com/771643 virtual/spv175/compositing/squashing/visibility-composited-squashing.html [ Failure ] crbug.com/771643 virtual/spv175/compositing/visibility/visibility-image-layers.html [ Failure Pass ] -crbug.com/771643 virtual/spv175/paint/frames/iframe-with-mask.html [ Failure ] crbug.com/771643 virtual/spv175/paint/invalidation/offset-change-wrong-invalidation-with-float.html [ Failure ] crbug.com/771643 virtual/spv175/paint/invalidation/repaint-across-writing-mode-boundary.html [ Failure ] -crbug.com/771643 virtual/spv175/paint/invalidation/resize-mask.html [ Failure ] crbug.com/771643 virtual/spv175/paint/invalidation/compositing/newly-composited-repaint-rect.html [ Failure ] crbug.com/771643 virtual/spv175/paint/invalidation/compositing/resize-squashing-layer-that-needs-full-repaint.html [ Failure ] crbug.com/771643 virtual/spv175/paint/invalidation/compositing/subpixel-offset-scaled-transform-composited.html [ Failure ] @@ -145,10 +141,7 @@ crbug.com/771643 virtual/spv175/paint/invalidation/svg/text-viewbox-rescale.html [ Failure ] crbug.com/771643 virtual/spv175/paint/invalidation/svg/use-clipped-hit.svg [ Failure ] crbug.com/771643 virtual/spv175/paint/invalidation/svg/zoom-coords-viewattr-01-b.svg [ Failure ] -crbug.com/771643 virtual/spv175/paint/masks/fieldset-mask.html [ Failure ] -crbug.com/771643 virtual/spv175/paint/masks/table-cell-masks.html [ Failure ] crbug.com/771643 virtual/spv175/paint/pagination/pagination-change-clip-crash.html [ Failure ] -crbug.com/771643 virtual/spv175/paint/plugins/plugin-object-with-mask.html [ Failure ] ########## Ref tests can't be rebaselined ########## crbug.com/504613 crbug.com/524248 [ Mac ] paint/images/image-backgrounds-not-antialiased.html [ Failure ]
diff --git a/third_party/WebKit/LayoutTests/external/wpt/fetch/api/request/request-init-001.sub-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/fetch/api/request/request-init-001.sub-expected.txt index 5174ec97..fc13f288 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/fetch/api/request/request-init-001.sub-expected.txt +++ b/third_party/WebKit/LayoutTests/external/wpt/fetch/api/request/request-init-001.sub-expected.txt
@@ -27,6 +27,11 @@ PASS Check credentials init value of omit and associated getter PASS Check credentials init value of same-origin and associated getter PASS Check credentials init value of include and associated getter +PASS Check cache init value of default and associated getter +PASS Check cache init value of no-store and associated getter +PASS Check cache init value of reload and associated getter +PASS Check cache init value of no-cache and associated getter +PASS Check cache init value of force-cache and associated getter PASS Check redirect init value of follow and associated getter PASS Check redirect init value of error and associated getter PASS Check redirect init value of manual and associated getter
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/powerfulFeatureRestrictions/cachestorage-on-insecure-origin.html b/third_party/WebKit/LayoutTests/http/tests/security/powerfulFeatureRestrictions/cachestorage-on-insecure-origin.html index 953eb8b2..f578830a 100644 --- a/third_party/WebKit/LayoutTests/http/tests/security/powerfulFeatureRestrictions/cachestorage-on-insecure-origin.html +++ b/third_party/WebKit/LayoutTests/http/tests/security/powerfulFeatureRestrictions/cachestorage-on-insecure-origin.html
@@ -10,54 +10,8 @@ if (window.testRunner) testRunner.overridePreference("WebKitStrictPowerfulFeatureRestrictions", true); - promise_test(function(test) { - return window.caches.match('http://example.com/resource.html') - .then( - test.unreached_func('promise should not be fulfilled'), - function(reason) { - assert_equals(reason.name, 'SecurityError', - 'match should reject with SecurityError'); - }); - }, 'CacheStorage match() on insecure origin'); - - promise_test(function(test) { - return window.caches.has('name') - .then( - test.unreached_func('promise should not be fulfilled'), - function(reason) { - assert_equals(reason.name, 'SecurityError', - 'match should reject with SecurityError'); - }); - }, 'CacheStorage has() on insecure origin'); - - promise_test(function(test) { - return window.caches.open('name') - .then( - test.unreached_func('promise should not be fulfilled'), - function(reason) { - assert_equals(reason.name, 'SecurityError', - 'match should reject with SecurityError'); - }); - }, 'CacheStorage open() on insecure origin'); - - promise_test(function(test) { - return window.caches.delete('name') - .then( - test.unreached_func('promise should not be fulfilled'), - function(reason) { - assert_equals(reason.name, 'SecurityError', - 'match should reject with SecurityError'); - }); - }, 'CacheStorage delete() on insecure origin'); - - promise_test(function(test) { - return window.caches.keys() - .then( - test.unreached_func('promise should not be fulfilled'), - function(reason) { - assert_equals(reason.name, 'SecurityError', - 'match should reject with SecurityError'); - }); - }, 'CacheStorage keys() on insecure origin'); -} + test(t => { + assert_false('caches' in window, 'window.caches should not be present'); + }, 'window.caches requires a secure context'); + } </script>
diff --git a/third_party/WebKit/Source/core/layout/LayoutBox.cpp b/third_party/WebKit/Source/core/layout/LayoutBox.cpp index 267ce5ce5..2d41658d 100644 --- a/third_party/WebKit/Source/core/layout/LayoutBox.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutBox.cpp
@@ -1104,10 +1104,19 @@ if (!frame_view) return IntSize(); - IntRect box(AbsoluteBoundingBoxRect()); + LayoutRect box(AbsoluteBoundingBoxRect()); + // TODO(bokan): This is wrong. Subtracting the scroll offset would get you to + // frame coordinates (pre-RLS) but *adding* the scroll offset to an absolute + // location never makes sense (and we assume below it's in content + // coordinates). box.Move(View()->GetFrameView()->ScrollOffsetInt()); - IntRect window_box = View()->GetFrameView()->ContentsToRootFrame(box); + // Exclude scrollbars so the border belt (activation area) starts from the + // scrollbar-content edge rather than the window edge. + ExcludeScrollbars(box, kExcludeOverlayScrollbarSizeForHitTesting); + + IntRect window_box = + View()->GetFrameView()->ContentsToRootFrame(PixelSnappedIntRect(box)); IntPoint window_autoscroll_point = point_in_root_frame; if (window_autoscroll_point.X() < window_box.X() + kAutoscrollBeltSize)
diff --git a/third_party/WebKit/Source/core/paint/BoxPainter.cpp b/third_party/WebKit/Source/core/paint/BoxPainter.cpp index f1ddb94..5a995bd 100644 --- a/third_party/WebKit/Source/core/paint/BoxPainter.cpp +++ b/third_party/WebKit/Source/core/paint/BoxPainter.cpp
@@ -248,7 +248,8 @@ bool all_mask_images_loaded = true; - if (!mask_blending_applied_by_compositor) { + if (!mask_blending_applied_by_compositor && + !RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) { push_transparency_layer = true; StyleImage* mask_box_image = layout_box_.Style()->MaskBoxImage().GetImage(); const FillLayer& mask_layers = layout_box_.Style()->MaskLayers();
diff --git a/third_party/WebKit/Source/devtools/front_end/main/Main.js b/third_party/WebKit/Source/devtools/front_end/main/Main.js index 8b5a017..0e5a5f5 100644 --- a/third_party/WebKit/Source/devtools/front_end/main/Main.js +++ b/third_party/WebKit/Source/devtools/front_end/main/Main.js
@@ -93,9 +93,14 @@ storagePrefix = '__custom__'; else if (!Runtime.queryParam('can_dock') && !!Runtime.queryParam('debugFrontend') && !Host.isUnderTest(prefs)) storagePrefix = '__bundled__'; - var clearLocalStorage = window.localStorage ? window.localStorage.clear.bind(window.localStorage) : undefined; - var localStorage = - new Common.SettingsStorage(window.localStorage || {}, undefined, undefined, clearLocalStorage, storagePrefix); + + var localStorage; + if (!Host.isUnderTest(prefs) && window.localStorage) { + localStorage = new Common.SettingsStorage( + window.localStorage, undefined, undefined, () => window.localStorage.clear(), storagePrefix); + } else { + localStorage = new Common.SettingsStorage({}, undefined, undefined, undefined, storagePrefix); + } var globalStorage = new Common.SettingsStorage( prefs, InspectorFrontendHost.setPreference, InspectorFrontendHost.removePreference, InspectorFrontendHost.clearPreferences, storagePrefix);
diff --git a/third_party/WebKit/Source/devtools/front_end/network/NetworkLogView.js b/third_party/WebKit/Source/devtools/front_end/network/NetworkLogView.js index 11cdb18..613bd1d 100644 --- a/third_party/WebKit/Source/devtools/front_end/network/NetworkLogView.js +++ b/third_party/WebKit/Source/devtools/front_end/network/NetworkLogView.js
@@ -1169,15 +1169,18 @@ if (Host.isWin()) { footerSection.appendItem( + Common.UIString('Copy as PowerShell'), this._copyPowerShellCommand.bind(this, request)); + footerSection.appendItem( Common.UIString('Copy as cURL (cmd)'), this._copyCurlCommand.bind(this, request, 'win')); footerSection.appendItem( Common.UIString('Copy as cURL (bash)'), this._copyCurlCommand.bind(this, request, 'unix')); - footerSection.appendItem(Common.UIString('Copy All as cURL (cmd)'), this._copyAllCurlCommand.bind(this, 'win')); + footerSection.appendItem(Common.UIString('Copy all as PowerShell'), this._copyAllPowerShellCommand.bind(this)); + footerSection.appendItem(Common.UIString('Copy all as cURL (cmd)'), this._copyAllCurlCommand.bind(this, 'win')); footerSection.appendItem( - Common.UIString('Copy All as cURL (bash)'), this._copyAllCurlCommand.bind(this, 'unix')); + Common.UIString('Copy all as cURL (bash)'), this._copyAllCurlCommand.bind(this, 'unix')); } else { footerSection.appendItem(Common.UIString('Copy as cURL'), this._copyCurlCommand.bind(this, request, 'unix')); - footerSection.appendItem(Common.UIString('Copy All as cURL'), this._copyAllCurlCommand.bind(this, 'unix')); + footerSection.appendItem(Common.UIString('Copy all as cURL'), this._copyAllCurlCommand.bind(this, 'unix')); } } else { copyMenu = contextMenu.clipboardSection().appendSubMenuItem(Common.UIString('Copy')); @@ -1273,6 +1276,19 @@ InspectorFrontendHost.copyText(commands.join(' ;\n')); } + /** + * @param {!SDK.NetworkRequest} request + */ + _copyPowerShellCommand(request) { + InspectorFrontendHost.copyText(this._generatePowerShellCommand(request)); + } + + _copyAllPowerShellCommand() { + var requests = NetworkLog.networkLog.requests(); + var commands = requests.map(this._generatePowerShellCommand.bind(this)); + InspectorFrontendHost.copyText(commands.join(';\r\n')); + } + async _exportAll() { var url = SDK.targetManager.mainTarget().inspectedURL(); var parsedURL = url.asParsedURL(); @@ -1739,6 +1755,56 @@ command.push('--insecure'); return command.join(' '); } + + /** + * @param {!SDK.NetworkRequest} request + * @return {string} + */ + _generatePowerShellCommand(request) { + var command = ['Invoke-WebRequest']; + var ignoredHeaders = new Set(['host', 'connection', 'proxy-connection', 'content-length', 'expect', 'range']); + + /** + * @param {string} str + * @return {string} + */ + function escapeString(str) { + return '"' + + str.replace(/[`\$"]/g, '`$&').replace(/[^\x20-\x7E]/g, char => '$([char]' + char.charCodeAt(0) + ')') + '"'; + } + + command.push('-Uri'); + command.push(escapeString(request.url())); + + if (request.requestMethod !== 'GET') { + command.push('-Method'); + command.push(escapeString(request.requestMethod)); + } + + var requestHeaders = request.requestHeaders(); + var headerNameValuePairs = []; + for (var header of requestHeaders) { + var name = header.name.replace(/^:/, ''); // Translate h2 headers to HTTP headers. + if (ignoredHeaders.has(name.toLowerCase())) + continue; + headerNameValuePairs.push(escapeString(name) + '=' + escapeString(header.value)); + } + if (headerNameValuePairs.length) { + command.push('-Headers'); + command.push('@{' + headerNameValuePairs.join('; ') + '}'); + } + + if (request.requestFormData) { + command.push('-Body'); + var body = escapeString(request.requestFormData); + if (/[^\x20-\x7E]/.test(request.requestFormData)) + command.push('([System.Text.Encoding]::UTF8.GetBytes(' + body + '))'); + else + command.push(body); + } + + return command.join(' '); + } }; Network.NetworkLogView._isFilteredOutSymbol = Symbol('isFilteredOut');
diff --git a/third_party/WebKit/Source/modules/cachestorage/Cache.idl b/third_party/WebKit/Source/modules/cachestorage/Cache.idl index e05eff6..783d2ac 100644 --- a/third_party/WebKit/Source/modules/cachestorage/Cache.idl +++ b/third_party/WebKit/Source/modules/cachestorage/Cache.idl
@@ -5,6 +5,7 @@ // https://w3c.github.io/ServiceWorker/#cache-interface [ + SecureContext, Exposed=(Window,Worker) ] interface Cache { [CallWith=ScriptState, RaisesException] Promise<any> match(RequestInfo request, optional CacheQueryOptions options);
diff --git a/third_party/WebKit/Source/modules/cachestorage/CacheStorage.cpp b/third_party/WebKit/Source/modules/cachestorage/CacheStorage.cpp index 262c8ae..f05adba 100644 --- a/third_party/WebKit/Source/modules/cachestorage/CacheStorage.cpp +++ b/third_party/WebKit/Source/modules/cachestorage/CacheStorage.cpp
@@ -29,20 +29,6 @@ "No CacheStorage implementation provided."); } -bool CommonChecks(ScriptState* script_state, ExceptionState& exception_state) { - ExecutionContext* execution_context = ExecutionContext::From(script_state); - // FIXME: May be null due to worker termination: http://crbug.com/413518. - if (!execution_context) - return false; - - String error_message; - if (!execution_context->IsSecureContext(error_message)) { - exception_state.ThrowSecurityError(error_message); - return false; - } - return true; -} - } // namespace // FIXME: Consider using CallbackPromiseAdapter. @@ -238,11 +224,7 @@ } ScriptPromise CacheStorage::open(ScriptState* script_state, - const String& cache_name, - ExceptionState& exception_state) { - if (!CommonChecks(script_state, exception_state)) - return ScriptPromise(); - + const String& cache_name) { ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state); const ScriptPromise promise = resolver->Promise(); @@ -258,11 +240,7 @@ } ScriptPromise CacheStorage::has(ScriptState* script_state, - const String& cache_name, - ExceptionState& exception_state) { - if (!CommonChecks(script_state, exception_state)) - return ScriptPromise(); - + const String& cache_name) { ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state); const ScriptPromise promise = resolver->Promise(); @@ -277,11 +255,7 @@ } ScriptPromise CacheStorage::Delete(ScriptState* script_state, - const String& cache_name, - ExceptionState& exception_state) { - if (!CommonChecks(script_state, exception_state)) - return ScriptPromise(); - + const String& cache_name) { ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state); const ScriptPromise promise = resolver->Promise(); @@ -296,11 +270,7 @@ return promise; } -ScriptPromise CacheStorage::keys(ScriptState* script_state, - ExceptionState& exception_state) { - if (!CommonChecks(script_state, exception_state)) - return ScriptPromise(); - +ScriptPromise CacheStorage::keys(ScriptState* script_state) { ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state); const ScriptPromise promise = resolver->Promise(); @@ -317,8 +287,6 @@ const CacheQueryOptions& options, ExceptionState& exception_state) { DCHECK(!request.IsNull()); - if (!CommonChecks(script_state, exception_state)) - return ScriptPromise(); if (request.IsRequest()) return MatchImpl(script_state, request.GetAsRequest(), options);
diff --git a/third_party/WebKit/Source/modules/cachestorage/CacheStorage.h b/third_party/WebKit/Source/modules/cachestorage/CacheStorage.h index 93c50cf..9edbd43f 100644 --- a/third_party/WebKit/Source/modules/cachestorage/CacheStorage.h +++ b/third_party/WebKit/Source/modules/cachestorage/CacheStorage.h
@@ -32,10 +32,10 @@ ~CacheStorage(); void Dispose(); - ScriptPromise open(ScriptState*, const String& cache_name, ExceptionState&); - ScriptPromise has(ScriptState*, const String& cache_name, ExceptionState&); - ScriptPromise Delete(ScriptState*, const String& cache_name, ExceptionState&); - ScriptPromise keys(ScriptState*, ExceptionState&); + ScriptPromise open(ScriptState*, const String& cache_name); + ScriptPromise has(ScriptState*, const String& cache_name); + ScriptPromise Delete(ScriptState*, const String& cache_name); + ScriptPromise keys(ScriptState*); ScriptPromise match(ScriptState*, const RequestInfo&, const CacheQueryOptions&,
diff --git a/third_party/WebKit/Source/modules/cachestorage/CacheStorage.idl b/third_party/WebKit/Source/modules/cachestorage/CacheStorage.idl index cd7e31d..9e0c78a 100644 --- a/third_party/WebKit/Source/modules/cachestorage/CacheStorage.idl +++ b/third_party/WebKit/Source/modules/cachestorage/CacheStorage.idl
@@ -4,11 +4,12 @@ // See https://w3c.github.io/ServiceWorker/#cachestorage-interface [ + SecureContext, Exposed=(Window,Worker) ] interface CacheStorage { [CallWith=ScriptState, RaisesException] Promise<any> match(RequestInfo request, optional CacheQueryOptions options); - [CallWith=ScriptState, RaisesException] Promise<boolean> has(DOMString cacheName); - [CallWith=ScriptState, RaisesException] Promise<Cache> open(DOMString cacheName); - [CallWith=ScriptState, RaisesException, ImplementedAs=Delete] Promise<boolean> delete(DOMString cacheName); - [CallWith=ScriptState, RaisesException] Promise<sequence<DOMString>> keys(); + [CallWith=ScriptState] Promise<boolean> has(DOMString cacheName); + [CallWith=ScriptState] Promise<Cache> open(DOMString cacheName); + [CallWith=ScriptState, ImplementedAs=Delete] Promise<boolean> delete(DOMString cacheName); + [CallWith=ScriptState] Promise<sequence<DOMString>> keys(); };
diff --git a/third_party/WebKit/Source/modules/cachestorage/WindowCacheStorage.idl b/third_party/WebKit/Source/modules/cachestorage/WindowCacheStorage.idl index 5f1e045c..1cb3db5 100644 --- a/third_party/WebKit/Source/modules/cachestorage/WindowCacheStorage.idl +++ b/third_party/WebKit/Source/modules/cachestorage/WindowCacheStorage.idl
@@ -6,5 +6,5 @@ [ ImplementedAs=GlobalCacheStorage ] partial interface Window { - [MeasureAs=GlobalCacheStorage, RaisesException] readonly attribute CacheStorage caches; + [SecureContext, MeasureAs=GlobalCacheStorage, RaisesException] readonly attribute CacheStorage caches; };
diff --git a/third_party/WebKit/Source/modules/cachestorage/WorkerCacheStorage.idl b/third_party/WebKit/Source/modules/cachestorage/WorkerCacheStorage.idl index 62ebc323..c220d95ab 100644 --- a/third_party/WebKit/Source/modules/cachestorage/WorkerCacheStorage.idl +++ b/third_party/WebKit/Source/modules/cachestorage/WorkerCacheStorage.idl
@@ -6,5 +6,5 @@ [ ImplementedAs=GlobalCacheStorage ] partial interface WorkerGlobalScope { - [MeasureAs=GlobalCacheStorage, RaisesException] readonly attribute CacheStorage caches; + [SecureContext, MeasureAs=GlobalCacheStorage, RaisesException] readonly attribute CacheStorage caches; };
diff --git a/third_party/WebKit/Source/platform/graphics/LoggingCanvas.cpp b/third_party/WebKit/Source/platform/graphics/LoggingCanvas.cpp index 2a387c3..81f488e7 100644 --- a/third_party/WebKit/Source/platform/graphics/LoggingCanvas.cpp +++ b/third_party/WebKit/Source/platform/graphics/LoggingCanvas.cpp
@@ -482,6 +482,8 @@ paint_item->SetString("textEncoding", TextEncodingName(paint.getTextEncoding())); paint_item->SetString("hinting", HintingName(paint.getHinting())); + if (paint.getBlendMode() != SkBlendMode::kSrcOver) + paint_item->SetString("blendMode", SkBlendMode_Name(paint.getBlendMode())); return paint_item; }
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/baseline_optimizer.py b/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/baseline_optimizer.py index 7ea7410..332f28a5 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/baseline_optimizer.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/baseline_optimizer.py
@@ -31,9 +31,12 @@ from webkitpy.common.memoized import memoized from webkitpy.layout_tests.controllers.test_result_writer import baseline_name as get_baseline_name +from webkitpy.layout_tests.models.testharness_results import is_all_pass_testharness_result _log = logging.getLogger(__name__) +ALL_PASS = '<PASS> testharness.js' + class BaselineOptimizer(object): @@ -79,6 +82,7 @@ _log.debug('Optimizing non-virtual fallback path.') succeeded &= self._optimize_subtree(non_virtual_baseline_name) + self._remove_all_pass_testharness_result_at_root(non_virtual_baseline_name) if not succeeded: _log.error('Heuristics failed to optimize %s', baseline_name) @@ -93,7 +97,7 @@ """Reads the baselines with the given file name in all directories. Returns: - A dict from directory names to file content SHA1. + A dict from directory names to the digest of file content. """ results_by_directory = {} directories = set() @@ -103,7 +107,7 @@ for directory in directories: path = self._join_directory(directory, baseline_name) if self._filesystem.exists(path): - results_by_directory[directory] = self._filesystem.sha1(path) + results_by_directory[directory] = self._digest_result(path) return results_by_directory def _optimize_subtree(self, baseline_name): @@ -121,6 +125,7 @@ self.new_results_by_directory.append(results_by_directory) return True + # Check if the results before and after optimization are equivalent. if (self._results_by_port_name(results_by_directory) != self._results_by_port_name(new_results_by_directory)): # This really should never happen. Just a sanity check to make @@ -204,8 +209,8 @@ For each immediate predecessor, we call worker_func(virtual_baseline, non_virtual_fallback) - where the two arguments are the paths to the virtual platform baseline - and the non-virtual fallback respectively. + where the two arguments are the absolute paths to the virtual platform + baseline and the non-virtual fallback respectively. """ actual_test_name = self._virtual_base(test_name) assert actual_test_name, '%s is not a virtual test.' % test_name @@ -257,18 +262,17 @@ # See if all the successors of the virtual root (i.e. all non-virtual # platforms) have the same baseline as the virtual root. If so, the # virtual root is redundant and can be safely removed. - root_sha1 = self._filesystem.sha1(virtual_root_baseline_path) + virtual_root_digest = self._digest_result(virtual_root_baseline_path) # Read the base (non-virtual) results. results_by_directory = self.read_results_by_directory(self._virtual_base(baseline_name)) + # Since implicit_all_pass defaults to True, we can also optimize away + # redundant all-PASS testharness.js results at the virtual root. results_by_port_name = self._results_by_port_name(results_by_directory) for port_name in self._ports.keys(): - if port_name not in results_by_port_name: - # No baseline is found for this port. Conservatively abort as it - # may be an implicit all-PASS for a testharness.js test. - return - if results_by_port_name[port_name] != root_sha1: + assert port_name in results_by_port_name + if results_by_port_name[port_name] != virtual_root_digest: return _log.debug('Deleting redundant virtual root baseline.') @@ -281,7 +285,7 @@ # of the work done in _patch_virtual_subtree. def unpatcher(virtual_baseline, non_virtual_fallback): if self._filesystem.exists(virtual_baseline) and \ - self._filesystem.sha1(virtual_baseline) == self._filesystem.sha1(non_virtual_fallback): + self._digest_result(virtual_baseline) == self._digest_result(non_virtual_fallback): _log.debug(' Deleting (file system): %s (redundant with %s).', virtual_baseline, non_virtual_fallback) self._filesystem.remove(virtual_baseline) self._walk_immediate_predecessors_of_virtual_root(test_name, suffix, baseline_name, unpatcher) @@ -318,14 +322,30 @@ """Returns the absolute path to the baseline in the given directory.""" return self._filesystem.join(self._parent_of_tests, directory, baseline_name) - def _results_by_port_name(self, results_by_directory): - """Transforms a by-directory result dict to by-port-name.""" + def _results_by_port_name(self, results_by_directory, implicit_all_pass=True): + """Transforms a by-directory result dict to by-port-name. + + The method mimicks the baseline search behaviour, i.e. results[port] is + the first baseline found on the baseline search path of the port. + + Args: + results_by_directory: A dictionary returned by read_results_by_directory(). + implicit_all_pass: If True, ports with no baselines found will have + all-PASS testharness.js results, which matches the real-world + behaviour of run-webkit-tests for testharness.js tests. + Otherwise, such ports will not be found in the dict. + + Returns: + A dictionary mapping port names to their baselines. + """ results_by_port_name = {} for port_name, port in self._ports.items(): for directory in self._relative_baseline_search_path(port): if directory in results_by_directory: results_by_port_name[port_name] = results_by_directory[directory] break + if port_name not in results_by_port_name and implicit_all_pass: + results_by_port_name[port_name] = ALL_PASS return results_by_port_name @memoized @@ -378,7 +398,9 @@ def _find_optimal_result_placement(self, baseline_name): results_by_directory = self.read_results_by_directory(baseline_name) - results_by_port_name = self._results_by_port_name(results_by_directory) + # Set implicit_all_pass=False so that we won't get non-existent all-PASS + # testharness.js results, which would break _find_in_search_path. + results_by_port_name = self._results_by_port_name(results_by_directory, implicit_all_pass=False) new_results_by_directory = self._remove_redundant_results( results_by_directory, results_by_port_name) @@ -401,6 +423,7 @@ search_path = self._relative_baseline_search_path(port) current_index, current_directory = self._find_in_search_path(search_path, current_result, new_results_by_directory) + found_different_result = False for index in range(current_index + 1, len(search_path)): new_directory = search_path[index] if new_directory not in new_results_by_directory: @@ -415,8 +438,19 @@ current_directory = new_directory else: # A different result is found, so stop. + found_different_result = True break + # If we did not find a different fallback and current_result is an + # all-PASS testharness.js result, we can safely remove it, as it is + # the implicit result. + # Note that we do not remove the generic all-PASS result here. + # Roots (virtual and non-virtual) are treated specially later. + if (not found_different_result and current_result == ALL_PASS + and current_directory != self._baseline_root() + and current_directory in new_results_by_directory): + del new_results_by_directory[current_directory] + return new_results_by_directory def _find_in_search_path(self, search_path, current_result, results_by_directory): @@ -425,3 +459,36 @@ if directory in results_by_directory and (results_by_directory[directory] == current_result): return index, directory assert False, 'result %s not found in search path %s, %s' % (current_result, search_path, results_by_directory) + + def _remove_all_pass_testharness_result_at_root(self, baseline_name): + """Removes the all-PASS testharness.js result at the non-virtual root.""" + assert not self._virtual_base(baseline_name), 'A virtual baseline is passed in.' + path = self._join_directory(self._baseline_root(), baseline_name) + if self._filesystem.exists(path) and self._is_all_pass_testharness_result(path): + _log.debug('Deleting redundant all-PASS root baseline.') + _log.debug(' Deleting (file system): ' + path) + self._filesystem.remove(path) + + def _digest_result(self, path): + """Digests a result file into a string suitable for comparison. + + Args: + An absolute path. + + Returns: + In most cases, the SHA1 sum of the content is returned, but if the + file is an all-PASS testharness.js result, ALL_PASS is returned. + """ + # Unfortunately, we may read the file twice, once in text mode and once + # in binary mode. + if self._is_all_pass_testharness_result(path): + return ALL_PASS + return self._filesystem.sha1(path) + + def _is_all_pass_testharness_result(self, path): + """Checks if a baseline is an all-PASS testharness.js result.""" + # TODO(robertma): Find an appropriate constant for this (or make one). + if not path.endswith('-expected.txt'): + return False + content = self._filesystem.read_text_file(path) + return is_all_pass_testharness_result(content)
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/baseline_optimizer_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/baseline_optimizer_unittest.py index 36c38cc6..24b6926 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/baseline_optimizer_unittest.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/baseline_optimizer_unittest.py
@@ -41,6 +41,11 @@ _log.level = logging.DEBUG _log.addHandler(logging.StreamHandler(sys.stderr)) +ALL_PASS_TESTHARNESS_RESULT = """This is a testharness.js-based test. +PASS woohoo +Harness: the test ran to completion. +""" + class BaselineOptimizerTest(unittest.TestCase): @@ -296,6 +301,53 @@ }, baseline_dirname='virtual/gpu/fast/canvas') + def test_all_pass_testharness_at_root(self): + self._assert_optimization( + {'': ALL_PASS_TESTHARNESS_RESULT}, + {'': None}) + + def test_all_pass_testharness_at_linux(self): + self._assert_optimization( + {'platform/linux': ALL_PASS_TESTHARNESS_RESULT}, + {'platform/linux': None}) + + def test_all_pass_testharness_at_virtual_root(self): + self._assert_optimization( + {'virtual/gpu/fast/canvas': ALL_PASS_TESTHARNESS_RESULT}, + {'virtual/gpu/fast/canvas': None}, + baseline_dirname='virtual/gpu/fast/canvas') + + def test_all_pass_testharness_at_virtual_linux(self): + self._assert_optimization( + {'platform/linux/virtual/gpu/fast/canvas': ALL_PASS_TESTHARNESS_RESULT}, + {'platform/linux/virtual/gpu/fast/canvas': None}, + baseline_dirname='virtual/gpu/fast/canvas') + + def test_all_pass_testharness_falls_back_to_non_pass(self): + # The all-PASS baseline needs to be preserved in this case. + self._assert_optimization( + { + 'platform/linux': ALL_PASS_TESTHARNESS_RESULT, + '': '1' + }, + { + 'platform/linux': ALL_PASS_TESTHARNESS_RESULT, + '': '1' + }) + + def test_virtual_all_pass_testharness_falls_back_to_base(self): + # The all-PASS baseline needs to be preserved in this case. + self._assert_optimization( + { + 'virtual/gpu/fast/canvas': ALL_PASS_TESTHARNESS_RESULT, + 'platform/linux/fast/canvas': '1', + }, + { + 'virtual/gpu/fast/canvas': ALL_PASS_TESTHARNESS_RESULT, + 'platform/linux/fast/canvas': '1', + }, + baseline_dirname='virtual/gpu/fast/canvas') + # Tests for protected methods - pylint: disable=protected-access def test_move_baselines(self):
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/common/net/git_cl.py b/third_party/WebKit/Tools/Scripts/webkitpy/common/net/git_cl.py index 2f6ffe3d..edcae84 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/common/net/git_cl.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/common/net/git_cl.py
@@ -184,9 +184,7 @@ for result in raw_results: if builder_names and result['builder_name'] not in builder_names: continue - is_swarming_task = result['url'] and ( - '/task/' in result['url'] or - '//ci.chromium.org' in result['url']) + is_swarming_task = result['url'] and '/task/' in result['url'] if is_swarming_task and not include_swarming_tasks: continue build_to_status[self._build(result)] = self._try_job_status(result) @@ -214,7 +212,7 @@ url = result_dict['url'] if url is None: return Build(builder_name, None) - match = re.match(r'.*/builds/(\d+)/?$', url) + match = re.match(r'.*/(\d+)/?$', url) if match: build_number = match.group(1) return Build(builder_name, int(build_number))
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/common/net/git_cl_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/common/net/git_cl_unittest.py index f904a506..6d47f8d 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/common/net/git_cl_unittest.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/common/net/git_cl_unittest.py
@@ -180,7 +180,7 @@ 'builder_name': 'some-builder', 'status': 'COMPLETED', 'result': 'FAILURE', - 'url': 'http://build.chromium.org/p/master/builders/some-builder/builds/100', + 'url': 'http://ci.chromium.org/master/some-builder/100', }, ] self.assertEqual( @@ -277,7 +277,7 @@ 'builder_name': 'builder-c', 'status': 'COMPLETED', 'result': 'SUCCESS', - 'url': 'http://build.chromium.org/p/master/builders/builder-c/builds/123', + 'url': 'http://ci.chromium.org/master/builder-c/123', }, ] self.assertEqual( @@ -287,14 +287,28 @@ Build('builder-b', 100): TryJobStatus('COMPLETED', 'SUCCESS'), }) - def test_latest_try_builds_started_builds(self): + def test_latest_try_builds_started_build_luci_url(self): git_cl = GitCL(MockHost()) git_cl.fetch_raw_try_job_results = lambda: [ { 'builder_name': 'builder-a', 'status': 'STARTED', 'result': None, - 'url': 'http://build.chromium.org/p/master/builders/some-builder/builds/100', + 'url': 'http://ci.chromium.org/p/master/some-builder/100', + }, + ] + self.assertEqual( + git_cl.latest_try_jobs(['builder-a']), + {Build('builder-a', 100): TryJobStatus('STARTED')}) + + def test_latest_try_builds_started_build_buildbot_url(self): + git_cl = GitCL(MockHost()) + git_cl.fetch_raw_try_job_results = lambda: [ + { + 'builder_name': 'builder-a', + 'status': 'STARTED', + 'result': None, + 'url': 'http://build.chromium.org/master/builders/some-builder/builds/100', }, ] self.assertEqual( @@ -309,14 +323,14 @@ 'status': 'COMPLETED', 'result': 'FAILURE', 'failure_reason': 'BUILD_FAILURE', - 'url': 'http://build.chromium.org/p/master/builders/builder-a/builds/100', + 'url': 'http://ci.chromium.org/p/master/builder-a/100', }, { 'builder_name': 'builder-b', 'status': 'COMPLETED', 'result': 'FAILURE', 'failure_reason': 'INFRA_FAILURE', - 'url': 'http://build.chromium.org/p/master/builders/builder-b/builds/200', + 'url': 'http://ci.chromium.org/p/master/builder-b/200', }, ] self.assertEqual( @@ -326,26 +340,27 @@ Build('builder-b', 200): TryJobStatus('COMPLETED', 'FAILURE'), }) - def test_latest_try_builds_ignores_swarming(self): + def test_latest_try_builds_ignores_swarming_task(self): git_cl = GitCL(MockHost()) git_cl.fetch_raw_try_job_results = lambda: [ { 'builder_name': 'builder-b', 'status': 'COMPLETED', 'result': 'SUCCESS', - 'url': 'http://build.chromium.org/p/master/builders/builder-b/builds/100', + 'url': 'https://ci.chromium.org/buildbot/mymaster/builder-b/10', }, { 'builder_name': 'builder-b', 'status': 'COMPLETED', 'result': 'SUCCESS', - 'url': 'https://ci.chromium.org/swarming/task/1234abcd1234abcd?server=chromium-swarm.appspot.com', + 'url': ('https://ci.chromium.org/swarming/task/' + '1234abcd1234abcd?server=chromium-swarm.appspot.com'), } ] self.assertEqual( git_cl.latest_try_jobs(['builder-b']), { - Build('builder-b', 100): TryJobStatus('COMPLETED', 'SUCCESS'), + Build('builder-b', 10): TryJobStatus('COMPLETED', 'SUCCESS'), }) def test_filter_latest(self): @@ -372,13 +387,15 @@ 'status': 'COMPLETED', 'result': 'FAILURE', 'failure_reason': 'BUILD_FAILURE', - 'url': 'https://luci-milo.appspot.com/swarming/task/36a767f405d9ee10', + 'url': ('https://ci.chromium.org/swarming/task/' + '36a767f405d9ee10'), }, { 'builder_name': 'builder-b', 'status': 'COMPLETED', 'result': 'SUCCESS', - 'url': 'https://ci.chromium.org/swarming/task/38740befcd9c0010?server=chromium-swarm.appspot.com', + 'url': ('https://ci.chromium.org/swarming/task/' + '38740befcd9c0010?server=chromium-swarm.appspot.com'), }, ] self.assertEqual( @@ -403,5 +420,6 @@ with self.assertRaisesRegexp(AssertionError, 'https://example.com/ did not match expected format'): git_cl.try_job_results() # We ignore builders that we explicitly don't care about; - # in this case we only care about other-builder, not builder-a. + # so if we only care about other-builder, not builder-a, + # then no exception is raised. self.assertEqual(git_cl.try_job_results(['other-builder']), {})
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/tool/commands/rebaseline.py b/third_party/WebKit/Tools/Scripts/webkitpy/tool/commands/rebaseline.py index dac8479..e4afaf6 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/tool/commands/rebaseline.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/tool/commands/rebaseline.py
@@ -35,7 +35,6 @@ from webkitpy.common.net.buildbot import Build from webkitpy.layout_tests.models.test_expectations import BASELINE_SUFFIX_LIST from webkitpy.layout_tests.models.test_expectations import TestExpectations -from webkitpy.layout_tests.models.testharness_results import is_all_pass_testharness_result from webkitpy.layout_tests.port import factory from webkitpy.tool.commands.command import Command @@ -415,8 +414,6 @@ if options.optimize: self._run_in_parallel(self._optimize_baselines(test_baseline_set, options.verbose)) - self._remove_all_pass_testharness_baselines(test_baseline_set) - self._tool.git().add_list(self.unstaged_baselines()) def unstaged_baselines(self): @@ -425,26 +422,6 @@ unstaged_changes = self._tool.git().unstaged_changes() return sorted(self._tool.git().absolute_path(path) for path in unstaged_changes if re.match(baseline_re, path)) - def _remove_all_pass_testharness_baselines(self, test_baseline_set): - """Removes all of the generic all-PASS baselines for the given tests. - - For testharness.js tests, the absence of a baseline indicates that the - test is expected to pass. When rebaselining, new all-PASS baselines may - be downloaded to platform directories. After optimization, some of them - may be pushed to the root layout test directory and become generic - baselines, which can be safely removed. Non-generic all-PASS baselines - need to be preserved; otherwise the fallback may be wrong. - """ - filesystem = self._tool.filesystem - baseline_paths = self._generic_baseline_paths(test_baseline_set) - for path in baseline_paths: - if not (filesystem.exists(path) and filesystem.splitext(path)[1] == '.txt'): - continue - contents = filesystem.read_text_file(path) - if is_all_pass_testharness_result(contents): - _log.info('Removing all-PASS testharness baseline: %s', path) - filesystem.remove(path) - def _generic_baseline_paths(self, test_baseline_set): """Returns absolute paths for generic baselines for the given tests.
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/tool/commands/rebaseline_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/tool/commands/rebaseline_unittest.py index a2c01c11..5e85a19 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/tool/commands/rebaseline_unittest.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/tool/commands/rebaseline_unittest.py
@@ -126,30 +126,6 @@ '/test.checkout/LayoutTests/passes/text-expected.wav', ]) - def test_remove_all_pass_testharness_generic_baselines(self): - self.tool.filesystem.write_text_file( - '/test.checkout/LayoutTests/passes/text-expected.txt', - ('This is a testharness.js-based test.\n' - 'PASS: foo\n' - 'Harness: the test ran to completion.\n')) - test_baseline_set = TestBaselineSet(self.tool) - test_baseline_set.add('passes/text.html', Build('MOCK Win7')) - self.command._remove_all_pass_testharness_baselines(test_baseline_set) - self.assertFalse(self.tool.filesystem.exists( - '/test.checkout/LayoutTests/passes/text-expected.txt')) - - def test_keep_all_pass_testharness_platform_baselines(self): - self.tool.filesystem.write_text_file( - '/test.checkout/LayoutTests/platform/test-win-win7/passes/text-expected.txt', - ('This is a testharness.js-based test.\n' - 'PASS: foo\n' - 'Harness: the test ran to completion.\n')) - test_baseline_set = TestBaselineSet(self.tool) - test_baseline_set.add('passes/text.html', Build('MOCK Win7')) - self.command._remove_all_pass_testharness_baselines(test_baseline_set) - self.assertTrue(self.tool.filesystem.exists( - '/test.checkout/LayoutTests/platform/test-win-win7/passes/text-expected.txt')) - class TestRebaseline(BaseTestCase): """Tests for the rebaseline method which is used by multiple rebaseline commands."""
diff --git a/third_party/libwebp/README.chromium b/third_party/libwebp/README.chromium index 9bcced9e..b3f1d64d 100644 --- a/third_party/libwebp/README.chromium +++ b/third_party/libwebp/README.chromium
@@ -23,3 +23,4 @@ (crbug.com/654974) Cherry-picks: Revert patch f7fc4bc: dec/webp.c: don't wait for data before reporting w/h + 296c7dc4 fix lossless decoding w/WEBP_REDUCE_SIZE
diff --git a/third_party/libwebp/src/dec/vp8l_dec.c b/third_party/libwebp/src/dec/vp8l_dec.c index 42ea3b5..0570f53 100644 --- a/third_party/libwebp/src/dec/vp8l_dec.c +++ b/third_party/libwebp/src/dec/vp8l_dec.c
@@ -1643,17 +1643,17 @@ #if !defined(WEBP_REDUCE_SIZE) if (io->use_scaling && !AllocateAndInitRescaler(dec, io)) goto Err; - - if (io->use_scaling || WebPIsPremultipliedMode(dec->output_->colorspace)) { - // need the alpha-multiply functions for premultiplied output or rescaling - WebPInitAlphaProcessing(); - } #else if (io->use_scaling) { dec->status_ = VP8_STATUS_INVALID_PARAM; goto Err; } #endif + if (io->use_scaling || WebPIsPremultipliedMode(dec->output_->colorspace)) { + // need the alpha-multiply functions for premultiplied output or rescaling + WebPInitAlphaProcessing(); + } + if (!WebPIsRGBMode(dec->output_->colorspace)) { WebPInitConvertARGBToYUV(); if (dec->output_->u.YUVA.a != NULL) WebPInitAlphaProcessing();
diff --git a/ui/app_list/BUILD.gn b/ui/app_list/BUILD.gn index 6039287f9..f72e9916 100644 --- a/ui/app_list/BUILD.gn +++ b/ui/app_list/BUILD.gn
@@ -143,6 +143,7 @@ # TODO(hejq): Remove this once app_list is migrated. http://crbug.com/733662 public_deps = [ "//ash/app_list/model:app_list_model", + "//ash/app_list/model:search_model", ] }
diff --git a/ui/app_list/app_list_util.h b/ui/app_list/app_list_util.h index cda7acb..aa1099f 100644 --- a/ui/app_list/app_list_util.h +++ b/ui/app_list/app_list_util.h
@@ -5,7 +5,7 @@ #ifndef UI_APP_LIST_APP_LIST_UTIL_H_ #define UI_APP_LIST_APP_LIST_UTIL_H_ -#include "ash/app_list/model/search_result.h" +#include "ash/app_list/model/search/search_result.h" #include "ui/app_list/app_list_export.h" #include "ui/events/event.h"
diff --git a/ui/app_list/app_list_view_delegate.h b/ui/app_list/app_list_view_delegate.h index 2dce75d..933276d 100644 --- a/ui/app_list/app_list_view_delegate.h +++ b/ui/app_list/app_list_view_delegate.h
@@ -23,6 +23,7 @@ class AppListModel; class AppListViewDelegateObserver; +class SearchModel; class SearchResult; class SpeechUIModel; @@ -33,6 +34,10 @@ // by the delegate, or owned elsewhere (e.g. a profile keyed service). virtual AppListModel* GetModel() = 0; + // Gets the search model associated with the view delegate. The model may be + // owned by the delegate, or owned elsewhere (e.g. a profile keyed service). + virtual SearchModel* GetSearchModel() = 0; + // Gets the SpeechUIModel for the app list. Owned by the AppListViewDelegate. virtual SpeechUIModel* GetSpeechUI() = 0;
diff --git a/ui/app_list/search/mixer.cc b/ui/app_list/search/mixer.cc index 8f71ba6..3fa7e30 100644 --- a/ui/app_list/search/mixer.cc +++ b/ui/app_list/search/mixer.cc
@@ -8,9 +8,10 @@ #include <map> #include <set> #include <string> +#include <utility> #include <vector> -#include "ash/app_list/model/search_result.h" +#include "ash/app_list/model/search/search_result.h" #include "base/macros.h" #include "base/memory/ptr_util.h" #include "ui/app_list/app_list_features.h" @@ -133,9 +134,8 @@ DISALLOW_COPY_AND_ASSIGN(Group); }; -Mixer::Mixer(AppListModel::SearchResults* ui_results) - : ui_results_(ui_results) { -} +Mixer::Mixer(SearchModel::SearchResults* ui_results) + : ui_results_(ui_results) {} Mixer::~Mixer() { } @@ -193,7 +193,7 @@ } void Mixer::Publish(const SortedResults& new_results, - AppListModel::SearchResults* ui_results) { + SearchModel::SearchResults* ui_results) { // The following algorithm is used: // 1. Transform the |ui_results| list into an unordered map from result ID // to item.
diff --git a/ui/app_list/search/mixer.h b/ui/app_list/search/mixer.h index 1387a774..1f7adb5 100644 --- a/ui/app_list/search/mixer.h +++ b/ui/app_list/search/mixer.h
@@ -11,6 +11,7 @@ #include <vector> #include "ash/app_list/model/app_list_model.h" +#include "ash/app_list/model/search/search_model.h" #include "base/gtest_prod_util.h" #include "base/macros.h" #include "ui/app_list/app_list_export.h" @@ -31,7 +32,7 @@ // different number of results and priority boost. class APP_LIST_EXPORT Mixer { public: - explicit Mixer(AppListModel::SearchResults* ui_results); + explicit Mixer(SearchModel::SearchResults* ui_results); ~Mixer(); // Adds a new mixer group. A "soft" maximum of |max_results| results will be @@ -72,7 +73,7 @@ // results that are not in |new_results|. Results that already exist in // |ui_results| are reused to avoid flickering caused by icon reload. static void Publish(const SortedResults& results, - AppListModel::SearchResults* ui_results); + SearchModel::SearchResults* ui_results); // Removes entries from |results| with duplicate IDs. When two or more results // have the same ID, the earliest one in the |results| list is kept. @@ -82,7 +83,7 @@ void FetchResults(bool is_voice_query, const KnownResults& known_results); - AppListModel::SearchResults* ui_results_; // Not owned. + SearchModel::SearchResults* ui_results_; // Not owned. Groups groups_; DISALLOW_COPY_AND_ASSIGN(Mixer);
diff --git a/ui/app_list/search/mixer_unittest.cc b/ui/app_list/search/mixer_unittest.cc index 9a69302..fe3afdc3 100644 --- a/ui/app_list/search/mixer_unittest.cc +++ b/ui/app_list/search/mixer_unittest.cc
@@ -12,7 +12,7 @@ #include <vector> #include "ash/app_list/model/app_list_model.h" -#include "ash/app_list/model/search_result.h" +#include "ash/app_list/model/search/search_result.h" #include "base/macros.h" #include "base/memory/ptr_util.h" #include "base/strings/string16.h" @@ -121,7 +121,7 @@ // testing::Test overrides: void SetUp() override { - results_.reset(new AppListModel::SearchResults); + results_.reset(new SearchModel::SearchResults); providers_.push_back(std::make_unique<TestSearchProvider>("app")); providers_.push_back(std::make_unique<TestSearchProvider>("omnibox")); @@ -180,7 +180,7 @@ private: std::unique_ptr<Mixer> mixer_; - std::unique_ptr<AppListModel::SearchResults> results_; + std::unique_ptr<SearchModel::SearchResults> results_; KnownResults known_results_; bool is_voice_query_; @@ -340,7 +340,7 @@ std::unique_ptr<SearchResult> result4(new TestSearchResult("app4", 0)); std::unique_ptr<SearchResult> result5(new TestSearchResult("app5", 0)); - AppListModel::SearchResults ui_results; + SearchModel::SearchResults ui_results; // Publish the first three results to |ui_results|. Mixer::SortedResults new_results;
diff --git a/ui/app_list/search_controller.cc b/ui/app_list/search_controller.cc index f29b64b6..d6a9aa6 100644 --- a/ui/app_list/search_controller.cc +++ b/ui/app_list/search_controller.cc
@@ -9,8 +9,8 @@ #include <utility> #include <vector> -#include "ash/app_list/model/search_box_model.h" -#include "ash/app_list/model/search_result.h" +#include "ash/app_list/model/search/search_box_model.h" +#include "ash/app_list/model/search/search_result.h" #include "base/bind.h" #include "base/metrics/histogram_macros.h" #include "base/metrics/user_metrics.h" @@ -23,7 +23,7 @@ namespace app_list { SearchController::SearchController(SearchBoxModel* search_box, - AppListModel::SearchResults* results, + SearchModel::SearchResults* results, History* history) : search_box_(search_box), mixer_(new Mixer(results)), history_(history) {}
diff --git a/ui/app_list/search_controller.h b/ui/app_list/search_controller.h index 8c3c01fd..72073039 100644 --- a/ui/app_list/search_controller.h +++ b/ui/app_list/search_controller.h
@@ -8,6 +8,7 @@ #include <stddef.h> #include <memory> +#include <vector> #include "ash/app_list/model/app_list_model.h" #include "base/macros.h" @@ -28,7 +29,7 @@ class APP_LIST_EXPORT SearchController { public: SearchController(SearchBoxModel* search_box, - AppListModel::SearchResults* results, + SearchModel::SearchResults* results, History* history); virtual ~SearchController();
diff --git a/ui/app_list/search_provider.cc b/ui/app_list/search_provider.cc index 38ee52a..42bf6f81 100644 --- a/ui/app_list/search_provider.cc +++ b/ui/app_list/search_provider.cc
@@ -6,7 +6,7 @@ #include <utility> -#include "ash/app_list/model/search_result.h" +#include "ash/app_list/model/search/search_result.h" namespace app_list {
diff --git a/ui/app_list/test/app_list_test_view_delegate.cc b/ui/app_list/test/app_list_test_view_delegate.cc index 31dce54..b8162448 100644 --- a/ui/app_list/test/app_list_test_view_delegate.cc +++ b/ui/app_list/test/app_list_test_view_delegate.cc
@@ -11,18 +11,14 @@ #include "base/callback.h" #include "base/files/file_path.h" #include "ui/app_list/app_list_switches.h" -#include "ui/app_list/test/app_list_test_model.h" #include "ui/gfx/image/image_skia.h" namespace app_list { namespace test { AppListTestViewDelegate::AppListTestViewDelegate() - : dismiss_count_(0), - stop_speech_recognition_count_(0), - open_search_result_count_(0), - next_profile_app_count_(0), - model_(new AppListTestModel) { + : model_(std::make_unique<AppListTestModel>()), + search_model_(std::make_unique<SearchModel>()) { model_->SetFoldersEnabled(true); } @@ -38,6 +34,10 @@ return model_.get(); } +SearchModel* AppListTestViewDelegate::GetSearchModel() { + return search_model_.get(); +} + SpeechUIModel* AppListTestViewDelegate::GetSpeechUI() { return &speech_ui_; } @@ -45,7 +45,7 @@ void AppListTestViewDelegate::OpenSearchResult(SearchResult* result, bool auto_launch, int event_flags) { - const AppListModel::SearchResults* results = model_->results(); + const SearchModel::SearchResults* results = search_model_->results(); for (size_t i = 0; i < results->item_count(); ++i) { if (results->GetItemAt(i) == result) { open_search_result_counts_[i]++; @@ -85,12 +85,13 @@ } void AppListTestViewDelegate::ReplaceTestModel(int item_count) { - model_.reset(new AppListTestModel); + model_ = std::make_unique<AppListTestModel>(); model_->PopulateApps(item_count); + search_model_ = std::make_unique<SearchModel>(); } void AppListTestViewDelegate::SetSearchEngineIsGoogle(bool is_google) { - model_->SetSearchEngineIsGoogle(is_google); + search_model_->SetSearchEngineIsGoogle(is_google); } } // namespace test
diff --git a/ui/app_list/test/app_list_test_view_delegate.h b/ui/app_list/test/app_list_test_view_delegate.h index f3efd07a..e4c7026 100644 --- a/ui/app_list/test/app_list_test_view_delegate.h +++ b/ui/app_list/test/app_list_test_view_delegate.h
@@ -12,11 +12,13 @@ #include <string> #include <vector> +#include "ash/app_list/model/search/search_model.h" #include "base/callback_forward.h" #include "base/compiler_specific.h" #include "base/macros.h" #include "ui/app_list/app_list_view_delegate.h" #include "ui/app_list/speech_ui_model.h" +#include "ui/app_list/test/app_list_test_model.h" namespace app_list { namespace test { @@ -52,6 +54,7 @@ // AppListViewDelegate overrides: AppListModel* GetModel() override; + SearchModel* GetSearchModel() override; SpeechUIModel* GetSpeechUI() override; void StartSearch() override {} void OpenSearchResult(SearchResult* result, @@ -85,12 +88,13 @@ AppListTestModel* GetTestModel() { return model_.get(); } private: - int dismiss_count_; - int stop_speech_recognition_count_; - int open_search_result_count_; - int next_profile_app_count_; + int dismiss_count_ = 0; + int stop_speech_recognition_count_ = 0; + int open_search_result_count_ = 0; + int next_profile_app_count_ = 0; std::map<size_t, int> open_search_result_counts_; std::unique_ptr<AppListTestModel> model_; + std::unique_ptr<SearchModel> search_model_; SpeechUIModel speech_ui_; std::vector<SkColor> wallpaper_prominent_colors_; base::TimeDelta auto_launch_timeout_;
diff --git a/ui/app_list/test/test_search_result.h b/ui/app_list/test/test_search_result.h index bd69371..6102ec03 100644 --- a/ui/app_list/test/test_search_result.h +++ b/ui/app_list/test/test_search_result.h
@@ -5,7 +5,9 @@ #ifndef UI_APP_LIST_TEST_TEST_SEARCH_RESULT_H_ #define UI_APP_LIST_TEST_TEST_SEARCH_RESULT_H_ -#include "ash/app_list/model/search_result.h" +#include <memory> + +#include "ash/app_list/model/search/search_result.h" #include "base/macros.h" namespace app_list {
diff --git a/ui/app_list/views/app_list_main_view.cc b/ui/app_list/views/app_list_main_view.cc index 51f7634..fe5410d 100644 --- a/ui/app_list/views/app_list_main_view.cc +++ b/ui/app_list/views/app_list_main_view.cc
@@ -9,7 +9,7 @@ #include "ash/app_list/model/app_list_folder_item.h" #include "ash/app_list/model/app_list_item.h" #include "ash/app_list/model/app_list_model.h" -#include "ash/app_list/model/search_box_model.h" +#include "ash/app_list/model/search/search_box_model.h" #include "base/bind.h" #include "base/callback.h" #include "base/files/file_path.h" @@ -45,6 +45,7 @@ AppListView* app_list_view) : delegate_(delegate), model_(delegate->GetModel()), + search_model_(delegate->GetSearchModel()), search_box_view_(nullptr), contents_view_(nullptr), app_list_view_(app_list_view) { @@ -104,6 +105,7 @@ model_->RemoveObserver(this); model_ = delegate_->GetModel(); model_->AddObserver(this); + search_model_ = delegate_->GetSearchModel(); search_box_view_->ModelChanged(); delete contents_view_; contents_view_ = nullptr; @@ -164,7 +166,8 @@ void AppListMainView::QueryChanged(SearchBoxView* sender) { base::string16 query; - base::TrimWhitespace(model_->search_box()->text(), base::TRIM_ALL, &query); + base::TrimWhitespace(search_model_->search_box()->text(), base::TRIM_ALL, + &query); bool should_show_search = !query.empty(); contents_view_->ShowSearchResults(should_show_search);
diff --git a/ui/app_list/views/app_list_main_view.h b/ui/app_list/views/app_list_main_view.h index a658172..c4e9bbe 100644 --- a/ui/app_list/views/app_list_main_view.h +++ b/ui/app_list/views/app_list_main_view.h
@@ -8,6 +8,7 @@ #include <string> #include "ash/app_list/model/app_list_model_observer.h" +#include "ash/app_list/model/search/search_model.h" #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "base/timer/timer.h" @@ -54,6 +55,7 @@ ContentsView* contents_view() const { return contents_view_; } AppListModel* model() { return model_; } + SearchModel* search_model() { return search_model_; } AppListViewDelegate* view_delegate() { return delegate_; } // Called when the search box's visibility is changed. @@ -88,6 +90,7 @@ AppListViewDelegate* delegate_; // Owned by parent view (AppListView). AppListModel* model_; // Unowned; ownership is handled by |delegate_|. + SearchModel* search_model_; // Unowned; ownership is handled by |delegate_|. // Created by AppListView. Owned by views hierarchy. SearchBoxView* search_box_view_;
diff --git a/ui/app_list/views/app_list_view.cc b/ui/app_list/views/app_list_view.cc index 045d8f74..b5954bd 100644 --- a/ui/app_list/views/app_list_view.cc +++ b/ui/app_list/views/app_list_view.cc
@@ -245,6 +245,7 @@ AppListView::AppListView(AppListViewDelegate* delegate) : delegate_(delegate), model_(delegate->GetModel()), + search_model_(delegate->GetSearchModel()), short_animations_for_testing_(false), is_fullscreen_app_list_enabled_(features::IsFullscreenAppListEnabled()), is_background_blur_enabled_(features::IsBackgroundBlurEnabled()), @@ -1141,7 +1142,7 @@ void AppListView::OnTabletModeChanged(bool started) { is_tablet_mode_ = started; search_box_view_->OnTabletModeChanged(started); - model_->SetTabletMode(started); + search_model_->SetTabletMode(started); if (is_tablet_mode_ && !is_fullscreen()) { // Set |app_list_state_| to a tablet mode friendly state. SetState(app_list_state_ == AppListViewState::PEEKING
diff --git a/ui/app_list/views/app_list_view.h b/ui/app_list/views/app_list_view.h index 57ba2164..b210b5c1 100644 --- a/ui/app_list/views/app_list_view.h +++ b/ui/app_list/views/app_list_view.h
@@ -6,6 +6,7 @@ #define UI_APP_LIST_VIEWS_APP_LIST_VIEW_H_ #include <memory> +#include <vector> #include "ash/app_list/model/app_list_view_state.h" #include "base/callback.h" @@ -45,6 +46,7 @@ class HideViewAnimationObserver; class PaginationModel; class SearchBoxView; +class SearchModel; class SpeechView; namespace test { @@ -327,6 +329,7 @@ AppListViewDelegate* delegate_; // Weak. Owned by AppListService. AppListModel* const model_; // Not Owned. + SearchModel* const search_model_; // Not Owned. AppListMainView* app_list_main_view_ = nullptr; SpeechView* speech_view_ = nullptr;
diff --git a/ui/app_list/views/app_list_view_unittest.cc b/ui/app_list/views/app_list_view_unittest.cc index 3568f92..0765277 100644 --- a/ui/app_list/views/app_list_view_unittest.cc +++ b/ui/app_list/views/app_list_view_unittest.cc
@@ -7,10 +7,12 @@ #include <stddef.h> #include <algorithm> +#include <map> #include <string> +#include <utility> #include <vector> -#include "ash/app_list/model/search_box_model.h" +#include "ash/app_list/model/search/search_box_model.h" #include "base/macros.h" #include "base/memory/ptr_util.h" #include "base/run_loop.h" @@ -132,7 +134,7 @@ (contents_view->GetPageView(i)->GetPageBoundsForState(state) == contents_view->GetPageView(i)->bounds()); } - return success && state == delegate_->GetTestModel()->state(); + return success && state == delegate_->GetModel()->state(); } // Checks the search box widget is at |expected| in the contents view's @@ -201,8 +203,11 @@ const int kItemNumInFolder = 8; const int kAppListItemNum = test_api_->TilesPerPage(0) + 1; AppListTestModel* model = delegate_->GetTestModel(); - for (size_t i = 0; i < kSuggestionAppNum; i++) - model->results()->Add(std::make_unique<TestStartPageSearchResult>()); + SearchModel* search_model = delegate_->GetSearchModel(); + for (size_t i = 0; i < kSuggestionAppNum; i++) { + search_model->results()->Add( + std::make_unique<TestStartPageSearchResult>()); + } AppListFolderItem* folder_item = model->CreateAndPopulateFolderWithApps(kItemNumInFolder); model->PopulateApps(kAppListItemNum); @@ -254,7 +259,8 @@ result_types.push_back( std::make_pair(SearchResult::DISPLAY_LIST, list_results_num)); - AppListModel::SearchResults* results = delegate_->GetTestModel()->results(); + SearchModel::SearchResults* results = + delegate_->GetSearchModel()->results(); results->DeleteAll(); double relevance = result_types.size(); for (const auto& data : result_types) { @@ -1488,7 +1494,7 @@ AppListModel::State expected = AppListModel::STATE_START; EXPECT_TRUE(main_view->contents_view()->IsStateActive(expected)); - EXPECT_EQ(expected, delegate_->GetTestModel()->state()); + EXPECT_EQ(expected, delegate_->GetModel()->state()); } // Tests that the start page view operates correctly. @@ -1614,7 +1620,7 @@ main_view->search_box_view()->search_box()->SetText(base::string16()); main_view->search_box_view()->search_box()->InsertText(search_text); // Check that the current search is using |search_text|. - EXPECT_EQ(search_text, delegate_->GetTestModel()->search_box()->text()); + EXPECT_EQ(search_text, delegate_->GetSearchModel()->search_box()->text()); EXPECT_EQ(search_text, main_view->search_box_view()->search_box()->text()); contents_view->Layout(); EXPECT_TRUE(contents_view->IsStateActive(AppListModel::STATE_SEARCH_RESULTS)); @@ -1630,7 +1636,7 @@ main_view->search_box_view()->search_box()->SetText(base::string16()); main_view->search_box_view()->search_box()->InsertText(new_search_text); // Check that the current search is using |new_search_text|. - EXPECT_EQ(new_search_text, delegate_->GetTestModel()->search_box()->text()); + EXPECT_EQ(new_search_text, delegate_->GetSearchModel()->search_box()->text()); EXPECT_EQ(new_search_text, main_view->search_box_view()->search_box()->text()); contents_view->Layout();
diff --git a/ui/app_list/views/apps_grid_view.cc b/ui/app_list/views/apps_grid_view.cc index e314e7f..604f067 100644 --- a/ui/app_list/views/apps_grid_view.cc +++ b/ui/app_list/views/apps_grid_view.cc
@@ -5,8 +5,10 @@ #include "ui/app_list/views/apps_grid_view.h" #include <algorithm> +#include <memory> #include <set> #include <string> +#include <vector> #include "ash/app_list/model/app_list_folder_item.h" #include "ash/app_list/model/app_list_item.h" @@ -1162,7 +1164,7 @@ return; suggestions_container_->SetResults(contents_view_->app_list_main_view() ->view_delegate() - ->GetModel() + ->GetSearchModel() ->results()); }
diff --git a/ui/app_list/views/apps_grid_view_unittest.cc b/ui/app_list/views/apps_grid_view_unittest.cc index b7c586c..8272b60 100644 --- a/ui/app_list/views/apps_grid_view_unittest.cc +++ b/ui/app_list/views/apps_grid_view_unittest.cc
@@ -134,10 +134,13 @@ app_list_view_->GetWidget()->Show(); model_ = delegate_->GetTestModel(); + search_model_ = delegate_->GetSearchModel(); suggestions_container_ = apps_grid_view_->suggestions_container_for_test(); expand_arrow_view_ = apps_grid_view_->expand_arrow_view_for_test(); - for (size_t i = 0; i < kNumOfSuggestedApps; ++i) - model_->results()->Add(std::make_unique<TestSuggestedSearchResult>()); + for (size_t i = 0; i < kNumOfSuggestedApps; ++i) { + search_model_->results()->Add( + std::make_unique<TestSuggestedSearchResult>()); + } // Needed to update suggestions from |model_|. apps_grid_view_->ResetForShowApps(); app_list_view_->SetState(AppListViewState::FULLSCREEN_ALL_APPS); @@ -244,6 +247,7 @@ ExpandArrowView* expand_arrow_view_ = nullptr; // Owned by |apps_grid_view_|. std::unique_ptr<AppListTestViewDelegate> delegate_; AppListTestModel* model_ = nullptr; // Owned by |delegate_|. + SearchModel* search_model_ = nullptr; // Owned by |delegate_|. std::unique_ptr<AppsGridViewTestApi> test_api_; bool is_rtl_ = false; base::test::ScopedFeatureList scoped_feature_list_;
diff --git a/ui/app_list/views/contents_view.cc b/ui/app_list/views/contents_view.cc index bb818e0..8cb6cbf6 100644 --- a/ui/app_list/views/contents_view.cc +++ b/ui/app_list/views/contents_view.cc
@@ -74,7 +74,8 @@ search_results_page_view_ = new SearchResultPageView(); // Search result containers. - AppListModel::SearchResults* results = view_delegate->GetModel()->results(); + SearchModel::SearchResults* results = + view_delegate->GetSearchModel()->results(); if (features::IsAnswerCardEnabled()) { search_result_answer_card_view_ =
diff --git a/ui/app_list/views/contents_view.h b/ui/app_list/views/contents_view.h index 9f4bb60..b24858a 100644 --- a/ui/app_list/views/contents_view.h +++ b/ui/app_list/views/contents_view.h
@@ -8,8 +8,10 @@ #include <map> #include <memory> #include <utility> +#include <vector> #include "ash/app_list/model/app_list_model.h" +#include "ash/app_list/model/search/search_model.h" #include "base/compiler_specific.h" #include "base/macros.h" #include "ui/app_list/app_list_export.h"
diff --git a/ui/app_list/views/search_box_view.cc b/ui/app_list/views/search_box_view.cc index b791697..dc8ed585 100644 --- a/ui/app_list/views/search_box_view.cc +++ b/ui/app_list/views/search_box_view.cc
@@ -8,7 +8,7 @@ #include <memory> #include <vector> -#include "ash/app_list/model/search_box_model.h" +#include "ash/app_list/model/search/search_box_model.h" #include "base/macros.h" #include "base/memory/ptr_util.h" #include "build/build_config.h" @@ -293,18 +293,18 @@ SearchBoxView::~SearchBoxView() { view_delegate_->GetSpeechUI()->RemoveObserver(this); - model_->search_box()->RemoveObserver(this); + search_model_->search_box()->RemoveObserver(this); view_delegate_->RemoveObserver(this); } void SearchBoxView::ModelChanged() { - if (model_) - model_->search_box()->RemoveObserver(this); + if (search_model_) + search_model_->search_box()->RemoveObserver(this); - model_ = view_delegate_->GetModel(); - DCHECK(model_); + search_model_ = view_delegate_->GetSearchModel(); + DCHECK(search_model_); UpdateSearchIcon(); - model_->search_box()->AddObserver(this); + search_model_->search_box()->AddObserver(this); SpeechRecognitionButtonPropChanged(); HintTextChanged(); @@ -734,10 +734,11 @@ void SearchBoxView::UpdateModel() { // Temporarily remove from observer to ignore notifications caused by us. - model_->search_box()->RemoveObserver(this); - model_->search_box()->Update(search_box_->text(), false); - model_->search_box()->SetSelectionModel(search_box_->GetSelectionModel()); - model_->search_box()->AddObserver(this); + search_model_->search_box()->RemoveObserver(this); + search_model_->search_box()->Update(search_box_->text(), false); + search_model_->search_box()->SetSelectionModel( + search_box_->GetSelectionModel()); + search_model_->search_box()->AddObserver(this); } void SearchBoxView::NotifyQueryChanged() { @@ -869,7 +870,7 @@ void SearchBoxView::SpeechRecognitionButtonPropChanged() { const SearchBoxModel::SpeechButtonProperty* speech_button_prop = - model_->search_box()->speech_button(); + search_model_->search_box()->speech_button(); if (speech_button_prop) { if (!speech_button_) { speech_button_ = new SearchBoxImageButton(this); @@ -895,17 +896,18 @@ } void SearchBoxView::HintTextChanged() { - const app_list::SearchBoxModel* search_box = model_->search_box(); + const app_list::SearchBoxModel* search_box = search_model_->search_box(); search_box_->set_placeholder_text(search_box->hint_text()); search_box_->SetAccessibleName(search_box->accessible_name()); } void SearchBoxView::SelectionModelChanged() { - search_box_->SelectSelectionModel(model_->search_box()->selection_model()); + search_box_->SelectSelectionModel( + search_model_->search_box()->selection_model()); } void SearchBoxView::Update() { - search_box_->SetText(model_->search_box()->text()); + search_box_->SetText(search_model_->search_box()->text()); UpdateCloseButtonVisisbility(); NotifyQueryChanged(); } @@ -946,7 +948,7 @@ void SearchBoxView::UpdateSearchIcon() { const gfx::VectorIcon& google_icon = is_search_box_active() ? kIcGoogleColorIcon : kIcGoogleBlackIcon; - const gfx::VectorIcon& icon = model_->search_engine_is_google() + const gfx::VectorIcon& icon = search_model_->search_engine_is_google() ? google_icon : kIcSearchEngineNotGoogleIcon; search_icon_->SetImage(
diff --git a/ui/app_list/views/search_box_view.h b/ui/app_list/views/search_box_view.h index dce9acb7..1c02eb3 100644 --- a/ui/app_list/views/search_box_view.h +++ b/ui/app_list/views/search_box_view.h
@@ -6,9 +6,11 @@ #define UI_APP_LIST_VIEWS_SEARCH_BOX_VIEW_H_ #include <string> +#include <vector> #include "ash/app_list/model/app_list_model.h" -#include "ash/app_list/model/search_box_model_observer.h" +#include "ash/app_list/model/search/search_box_model_observer.h" +#include "ash/app_list/model/search/search_model.h" #include "base/macros.h" #include "ui/app_list/app_list_constants.h" #include "ui/app_list/app_list_view_delegate_observer.h" @@ -226,7 +228,7 @@ SearchBoxViewDelegate* delegate_; // Not owned. AppListViewDelegate* view_delegate_; // Not owned. - AppListModel* model_ = nullptr; // Owned by the profile-keyed service. + SearchModel* search_model_ = nullptr; // Owned by the profile-keyed service. // Owned by views hierarchy. views::View* content_container_;
diff --git a/ui/app_list/views/search_result_actions_view.h b/ui/app_list/views/search_result_actions_view.h index 71d8517..b6c3e15 100644 --- a/ui/app_list/views/search_result_actions_view.h +++ b/ui/app_list/views/search_result_actions_view.h
@@ -5,7 +5,7 @@ #ifndef UI_APP_LIST_VIEWS_SEARCH_RESULT_ACTIONS_VIEW_H_ #define UI_APP_LIST_VIEWS_SEARCH_RESULT_ACTIONS_VIEW_H_ -#include "ash/app_list/model/search_result.h" +#include "ash/app_list/model/search/search_result.h" #include "base/macros.h" #include "ui/views/controls/button/button.h" #include "ui/views/view.h"
diff --git a/ui/app_list/views/search_result_answer_card_view.cc b/ui/app_list/views/search_result_answer_card_view.cc index f1be44ed..f4c7958d 100644 --- a/ui/app_list/views/search_result_answer_card_view.cc +++ b/ui/app_list/views/search_result_answer_card_view.cc
@@ -4,7 +4,9 @@ #include "ui/app_list/views/search_result_answer_card_view.h" -#include "ash/app_list/model/search_result_observer.h" +#include <vector> + +#include "ash/app_list/model/search/search_result_observer.h" #include "ui/accessibility/ax_node.h" #include "ui/accessibility/ax_node_data.h" #include "ui/app_list/app_list_constants.h" @@ -178,7 +180,7 @@ int SearchResultAnswerCardView::DoUpdate() { std::vector<SearchResult*> display_results = - AppListModel::FilterSearchResultsByDisplayType( + SearchModel::FilterSearchResultsByDisplayType( results(), SearchResult::DISPLAY_CARD, 1); const bool have_result = !display_results.empty();
diff --git a/ui/app_list/views/search_result_answer_card_view_unittest.cc b/ui/app_list/views/search_result_answer_card_view_unittest.cc index faa0c2d..5b10d55 100644 --- a/ui/app_list/views/search_result_answer_card_view_unittest.cc +++ b/ui/app_list/views/search_result_answer_card_view_unittest.cc
@@ -5,6 +5,7 @@ #include "ui/app_list/views/search_result_answer_card_view.h" #include <memory> +#include <utility> #include "base/macros.h" #include "base/memory/ptr_util.h" @@ -37,7 +38,8 @@ result_container_view_ = new SearchResultAnswerCardView(&view_delegate_); search_card_view_->AddChildView(result_container_view_); - result_container_view_->SetResults(view_delegate_.GetModel()->results()); + result_container_view_->SetResults( + view_delegate_.GetSearchModel()->results()); result_view_ = std::make_unique<views::View>(); result_view_->set_owned_by_client(); @@ -47,7 +49,7 @@ protected: void SetUpSearchResult() { - AppListModel::SearchResults* results = GetResults(); + SearchModel::SearchResults* results = GetResults(); std::unique_ptr<TestSearchResult> result = std::make_unique<TestSearchResult>(); result->set_display_type(SearchResult::DISPLAY_CARD); @@ -80,8 +82,8 @@ return result_container_view_->OnKeyPressed(event); } - AppListModel::SearchResults* GetResults() { - return view_delegate_.GetModel()->results(); + SearchModel::SearchResults* GetResults() { + return view_delegate_.GetSearchModel()->results(); } views::View* search_card_view() const { return search_card_view_.get(); }
diff --git a/ui/app_list/views/search_result_container_view.cc b/ui/app_list/views/search_result_container_view.cc index b3aa3f2..7fe4f2b 100644 --- a/ui/app_list/views/search_result_container_view.cc +++ b/ui/app_list/views/search_result_container_view.cc
@@ -25,7 +25,7 @@ } void SearchResultContainerView::SetResults( - AppListModel::SearchResults* results) { + SearchModel::SearchResults* results) { if (results_) results_->RemoveObserver(this);
diff --git a/ui/app_list/views/search_result_container_view.h b/ui/app_list/views/search_result_container_view.h index 1fe4a38..e1eedf68 100644 --- a/ui/app_list/views/search_result_container_view.h +++ b/ui/app_list/views/search_result_container_view.h
@@ -8,6 +8,7 @@ #include <stddef.h> #include "ash/app_list/model/app_list_model.h" +#include "ash/app_list/model/search/search_model.h" #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "ui/app_list/app_list_export.h" @@ -33,8 +34,8 @@ void set_delegate(Delegate* delegate) { delegate_ = delegate; } // Sets the search results to listen to. - void SetResults(AppListModel::SearchResults* results); - AppListModel::SearchResults* results() { return results_; } + void SetResults(SearchModel::SearchResults* results); + SearchModel::SearchResults* results() { return results_; } // Sets the index of the selected search result within this container. This // must be a valid index. @@ -110,7 +111,7 @@ double container_score_; - AppListModel::SearchResults* results_; // Owned by AppListModel. + SearchModel::SearchResults* results_; // Owned by SearchModel. // The factory that consolidates multiple Update calls into one. base::WeakPtrFactory<SearchResultContainerView> update_factory_;
diff --git a/ui/app_list/views/search_result_list_view.cc b/ui/app_list/views/search_result_list_view.cc index bbc0e2a0..3c20d10c 100644 --- a/ui/app_list/views/search_result_list_view.cc +++ b/ui/app_list/views/search_result_list_view.cc
@@ -7,7 +7,7 @@ #include <algorithm> #include <vector> -#include "ash/app_list/model/search_result.h" +#include "ash/app_list/model/search/search_result.h" #include "base/bind.h" #include "base/message_loop/message_loop.h" #include "base/time/time.h" @@ -183,7 +183,7 @@ int SearchResultListView::DoUpdate() { std::vector<SearchResult*> display_results = - AppListModel::FilterSearchResultsByDisplayType( + SearchModel::FilterSearchResultsByDisplayType( results(), SearchResult::DISPLAY_LIST, results_container_->child_count());
diff --git a/ui/app_list/views/search_result_list_view_unittest.cc b/ui/app_list/views/search_result_list_view_unittest.cc index 7eb3f617..ebcc1c4 100644 --- a/ui/app_list/views/search_result_list_view_unittest.cc +++ b/ui/app_list/views/search_result_list_view_unittest.cc
@@ -8,8 +8,9 @@ #include <map> #include <memory> +#include <utility> -#include "ash/app_list/model/app_list_model.h" +#include "ash/app_list/model/search/search_model.h" #include "base/macros.h" #include "base/memory/ptr_util.h" #include "base/strings/stringprintf.h" @@ -37,7 +38,7 @@ void SetUp() override { views::ViewsTestBase::SetUp(); view_.reset(new SearchResultListView(nullptr, &view_delegate_)); - view_->SetResults(view_delegate_.GetModel()->results()); + view_->SetResults(view_delegate_.GetSearchModel()->results()); } protected: @@ -47,8 +48,8 @@ return view_->GetResultViewAt(index); } - AppListModel::SearchResults* GetResults() { - return view_delegate_.GetModel()->results(); + SearchModel::SearchResults* GetResults() { + return view_delegate_.GetSearchModel()->results(); } void SetLongAutoLaunchTimeout() { @@ -61,7 +62,7 @@ } void SetUpSearchResults() { - AppListModel::SearchResults* results = GetResults(); + SearchModel::SearchResults* results = GetResults(); for (int i = 0; i < kDefaultSearchItems; ++i) { std::unique_ptr<TestSearchResult> result = std::make_unique<TestSearchResult>(); @@ -109,7 +110,7 @@ // Adding results will schedule Update(). RunPendingMessages(); - AppListModel::SearchResults* results = GetResults(); + SearchModel::SearchResults* results = GetResults(); for (size_t i = 0; i < results->item_count(); ++i) { EXPECT_EQ(results->GetItemAt(i), GetResultViewAt(i)->result()); }
diff --git a/ui/app_list/views/search_result_page_view.cc b/ui/app_list/views/search_result_page_view.cc index 0fe3a43..54ad6d2 100644 --- a/ui/app_list/views/search_result_page_view.cc +++ b/ui/app_list/views/search_result_page_view.cc
@@ -7,6 +7,7 @@ #include <stddef.h> #include <algorithm> +#include <memory> #include "base/memory/ptr_util.h" #include "ui/app_list/app_list_constants.h" @@ -182,7 +183,7 @@ } void SearchResultPageView::AddSearchResultContainerView( - AppListModel::SearchResults* results_model, + SearchModel::SearchResults* results_model, SearchResultContainerView* result_container) { if (!result_container_views_.empty()) { HorizontalSeparator* separator = new HorizontalSeparator(bounds().width());
diff --git a/ui/app_list/views/search_result_page_view.h b/ui/app_list/views/search_result_page_view.h index 082f9d7..e6a0e3f 100644 --- a/ui/app_list/views/search_result_page_view.h +++ b/ui/app_list/views/search_result_page_view.h
@@ -29,7 +29,7 @@ void SetSelection(bool select); // Set or unset result selection. void AddSearchResultContainerView( - AppListModel::SearchResults* result_model, + SearchModel::SearchResults* result_model, SearchResultContainerView* result_container); const std::vector<SearchResultContainerView*>& result_container_views() {
diff --git a/ui/app_list/views/search_result_page_view_unittest.cc b/ui/app_list/views/search_result_page_view_unittest.cc index 6e4d42e..0fa6bf7 100644 --- a/ui/app_list/views/search_result_page_view_unittest.cc +++ b/ui/app_list/views/search_result_page_view_unittest.cc
@@ -95,14 +95,14 @@ } SearchResultListView* list_view() const { return list_view_; } - AppListModel::SearchResults* GetResults() const { - return delegate_->GetModel()->results(); + SearchModel::SearchResults* GetResults() const { + return delegate_->GetSearchModel()->results(); } void SetUpSearchResults( const std::vector<std::pair<SearchResult::DisplayType, int>>& result_types) { - AppListModel::SearchResults* results = GetResults(); + SearchModel::SearchResults* results = GetResults(); results->DeleteAll(); double relevance = result_types.size(); for (const auto& data : result_types) { @@ -226,7 +226,7 @@ } TEST_P(SearchResultPageViewTest, ResultsSorted) { - AppListModel::SearchResults* results = GetResults(); + SearchModel::SearchResults* results = GetResults(); // Add 3 results and expect the tile list view to be the first result // container view.
diff --git a/ui/app_list/views/search_result_tile_item_list_view.cc b/ui/app_list/views/search_result_tile_item_list_view.cc index b66f31a..b5bb56a 100644 --- a/ui/app_list/views/search_result_tile_item_list_view.cc +++ b/ui/app_list/views/search_result_tile_item_list_view.cc
@@ -6,7 +6,7 @@ #include <stddef.h> -#include "ash/app_list/model/search_result.h" +#include "ash/app_list/model/search/search_result.h" #include "base/i18n/rtl.h" #include "ui/app_list/app_list_constants.h" #include "ui/app_list/app_list_features.h" @@ -113,7 +113,7 @@ int SearchResultTileItemListView::DoUpdate() { std::vector<SearchResult*> display_results = - AppListModel::FilterSearchResultsByDisplayType( + SearchModel::FilterSearchResultsByDisplayType( results(), SearchResult::DISPLAY_TILE, kMaxNumSearchResultTiles); SearchResult::ResultType previous_type = SearchResult::RESULT_UNKNOWN;
diff --git a/ui/app_list/views/search_result_tile_item_list_view_unittest.cc b/ui/app_list/views/search_result_tile_item_list_view_unittest.cc index 171e760..dc3e039 100644 --- a/ui/app_list/views/search_result_tile_item_list_view_unittest.cc +++ b/ui/app_list/views/search_result_tile_item_list_view_unittest.cc
@@ -56,19 +56,19 @@ textfield_ = std::make_unique<views::Textfield>(); view_ = std::make_unique<SearchResultTileItemListView>( nullptr, textfield_.get(), &view_delegate_); - view_->SetResults(view_delegate_.GetModel()->results()); + view_->SetResults(view_delegate_.GetSearchModel()->results()); } bool IsPlayStoreAppSearchEnabled() const { return GetParam(); } SearchResultTileItemListView* view() { return view_.get(); } - AppListModel::SearchResults* GetResults() { - return view_delegate_.GetModel()->results(); + SearchModel::SearchResults* GetResults() { + return view_delegate_.GetSearchModel()->results(); } void SetUpSearchResults() { - AppListModel::SearchResults* results = GetResults(); + SearchModel::SearchResults* results = GetResults(); // Populate results for installed applications. for (int i = 0; i < kInstalledApps; ++i) {
diff --git a/ui/app_list/views/search_result_tile_item_view.cc b/ui/app_list/views/search_result_tile_item_view.cc index 1f3c710..9d1209b3 100644 --- a/ui/app_list/views/search_result_tile_item_view.cc +++ b/ui/app_list/views/search_result_tile_item_view.cc
@@ -4,7 +4,7 @@ #include "ui/app_list/views/search_result_tile_item_view.h" -#include "ash/app_list/model/search_result.h" +#include "ash/app_list/model/search/search_result.h" #include "base/i18n/number_formatting.h" #include "base/metrics/histogram_macros.h" #include "base/strings/utf_string_conversions.h"
diff --git a/ui/app_list/views/search_result_tile_item_view.h b/ui/app_list/views/search_result_tile_item_view.h index 28745c4..24d4ff5 100644 --- a/ui/app_list/views/search_result_tile_item_view.h +++ b/ui/app_list/views/search_result_tile_item_view.h
@@ -7,7 +7,7 @@ #include <memory> -#include "ash/app_list/model/search_result_observer.h" +#include "ash/app_list/model/search/search_result_observer.h" #include "base/macros.h" #include "ui/app_list/views/tile_item_view.h" #include "ui/views/context_menu_controller.h"
diff --git a/ui/app_list/views/search_result_view.cc b/ui/app_list/views/search_result_view.cc index 322113c..32f515a 100644 --- a/ui/app_list/views/search_result_view.cc +++ b/ui/app_list/views/search_result_view.cc
@@ -5,8 +5,9 @@ #include "ui/app_list/views/search_result_view.h" #include <algorithm> +#include <utility> -#include "ash/app_list/model/search_result.h" +#include "ash/app_list/model/search/search_result.h" #include "base/strings/utf_string_conversions.h" #include "ui/app_list/app_list_constants.h" #include "ui/app_list/app_list_features.h"
diff --git a/ui/app_list/views/search_result_view.h b/ui/app_list/views/search_result_view.h index de67ba0..1637982 100644 --- a/ui/app_list/views/search_result_view.h +++ b/ui/app_list/views/search_result_view.h
@@ -11,7 +11,7 @@ #include <string> #include <vector> -#include "ash/app_list/model/search_result_observer.h" +#include "ash/app_list/model/search/search_result_observer.h" #include "base/compiler_specific.h" #include "base/macros.h" #include "base/strings/string16.h" @@ -115,7 +115,7 @@ // SearchResultActionsViewDelegate overrides: void OnSearchResultActionActivated(size_t index, int event_flags) override; - SearchResult* result_ = nullptr; // Owned by AppListModel::SearchResults. + SearchResult* result_ = nullptr; // Owned by SearchModel::SearchResults. bool is_last_result_ = false;
diff --git a/ui/app_list/views/suggestions_container_view.cc b/ui/app_list/views/suggestions_container_view.cc index e77203a..552b5f68 100644 --- a/ui/app_list/views/suggestions_container_view.cc +++ b/ui/app_list/views/suggestions_container_view.cc
@@ -48,7 +48,7 @@ } std::vector<SearchResult*> display_results = - AppListModel::FilterSearchResultsByDisplayType( + SearchModel::FilterSearchResultsByDisplayType( results(), SearchResult::DISPLAY_RECOMMENDATION, kNumStartPageTiles); if (display_results.size() != search_result_tile_views_.size()) { // We should recreate the grid layout in this case.
diff --git a/ui/strings/translations/app_locale_settings_ar.xtb b/ui/strings/translations/app_locale_settings_ar.xtb index e9416df6..ec9f1f5e 100644 --- a/ui/strings/translations/app_locale_settings_ar.xtb +++ b/ui/strings/translations/app_locale_settings_ar.xtb
@@ -3,7 +3,7 @@ <translationbundle lang="ar"> <translation id="IDS_MINIMUM_UI_FONT_SIZE">10</translation> <if expr="chromeos"> - <translation id="IDS_UI_FONT_FAMILY_CROS">Roboto, Noto Naskh Arabic UI, 13px</translation> - <translation id="IDS_WEB_FONT_FAMILY">Roboto, Noto Naskh Arabic UI, sans-serif</translation> + <translation id="IDS_UI_FONT_FAMILY_CROS">Roboto, Noto Sans Arabic UI, 13px</translation> + <translation id="IDS_WEB_FONT_FAMILY">Roboto, Noto Sans Arabic UI, sans-serif</translation> </if> </translationbundle>
diff --git a/ui/views/controls/button/button.cc b/ui/views/controls/button/button.cc index 9440f00b..dcb2a44 100644 --- a/ui/views/controls/button/button.cc +++ b/ui/views/controls/button/button.cc
@@ -106,6 +106,7 @@ void Button::SetAccessibleName(const base::string16& name) { accessible_name_ = name; + NotifyAccessibilityEvent(ui::AX_EVENT_TEXT_CHANGED, true); } void Button::SetState(ButtonState state) {
diff --git a/ui/webui/resources/cr_components/chromeos/network/network_siminfo.js b/ui/webui/resources/cr_components/chromeos/network/network_siminfo.js index 62e270d..ed702897 100644 --- a/ui/webui/resources/cr_components/chromeos/network/network_siminfo.js +++ b/ui/webui/resources/cr_components/chromeos/network/network_siminfo.js
@@ -19,6 +19,7 @@ var PIN_MIN_LENGTH = 4; var PUK_MIN_LENGTH = 8; +var TOGGLE_DEBOUNCE_MS = 500; Polymer({ is: 'network-siminfo', @@ -71,8 +72,12 @@ }, }, + /** @private {boolean} */ sendSimLockEnabled_: false, + /** @private {boolean|undefined} */ + setLockEnabled_: undefined, + /** @override */ detached: function() { if (this.$.enterPinDialog.open) @@ -92,16 +97,48 @@ var simLockStatus = this.networkProperties.Cellular.SIMLockStatus; this.pukRequired_ = !!simLockStatus && simLockStatus.LockType == CrOnc.LockType.PUK; - this.lockEnabled_ = !!simLockStatus && simLockStatus.LockEnabled; + var lockEnabled = !!simLockStatus && simLockStatus.LockEnabled; + if (lockEnabled != this.lockEnabled_) { + this.setLockEnabled_ = lockEnabled; + this.updateLockEnabled_(); + } else { + this.setLockEnabled_ = undefined; + } + }, + + /** + * Wrapper method to prevent changing |lockEnabled_| while a dialog is open + * to avoid confusion while a SIM operation is in progress. This must be + * called after closing any dialog (and not opening another) to set the + * correct state. + * @private + */ + updateLockEnabled_: function() { + if (this.setLockEnabled_ === undefined || this.$.enterPinDialog.open || + this.$.changePinDialog.open || this.$.unlockPinDialog.open || + this.$.unlockPukDialog.open) { + return; + } + this.lockEnabled_ = this.setLockEnabled_; + this.setLockEnabled_ = undefined; + }, + + /** @private */ + delayUpdateLockEnabled_: function() { + setTimeout(() => { + this.updateLockEnabled_(); + }, TOGGLE_DEBOUNCE_MS); }, /** @private */ pukRequiredChanged_: function() { if (this.$.unlockPukDialog.open) { - if (this.pukRequired_) + if (this.pukRequired_) { this.$.unlockPuk.focus(); - else + } else { this.$.unlockPukDialog.close(); + this.delayUpdateLockEnabled_(); + } return; } @@ -167,6 +204,7 @@ } else { this.error_ = ErrorType.NONE; this.$.enterPinDialog.close(); + this.delayUpdateLockEnabled_(); } }); }, @@ -211,6 +249,7 @@ } else { this.error_ = ErrorType.NONE; this.$.changePinDialog.close(); + this.delayUpdateLockEnabled_(); } }); }, @@ -248,6 +287,7 @@ } else { this.error_ = ErrorType.NONE; this.$.unlockPinDialog.close(); + this.delayUpdateLockEnabled_(); } }); }, @@ -290,6 +330,7 @@ } else { this.error_ = ErrorType.NONE; this.$.unlockPukDialog.close(); + this.delayUpdateLockEnabled_(); } }); },
diff --git a/ui/webui/resources/cr_elements/chromeos/cr_picture/cr_picture_list.js b/ui/webui/resources/cr_elements/chromeos/cr_picture/cr_picture_list.js index a980621..174a48a2 100644 --- a/ui/webui/resources/cr_elements/chromeos/cr_picture/cr_picture_list.js +++ b/ui/webui/resources/cr_elements/chromeos/cr_picture/cr_picture_list.js
@@ -230,8 +230,7 @@ selected.dataset.type == CrPicture.SelectionTypes.CAMERA; this.selectedItem = selected; - if (selected.dataset.type == CrPicture.SelectionTypes.OLD || - selected.dataset.type == CrPicture.SelectionTypes.CAMERA) { + if (selected.dataset.type == CrPicture.SelectionTypes.CAMERA) { if (activate) this.fire('focus-action', selected); } else if ( @@ -246,9 +245,8 @@ */ onIronActivate_: function(event) { var type = event.detail.item.dataset.type; - // Don't change focus when activating the camera or current image via mouse. - var activate = type != CrPicture.SelectionTypes.OLD && - type != CrPicture.SelectionTypes.CAMERA; + // Don't change focus when activating the camera via mouse. + var activate = type != CrPicture.SelectionTypes.CAMERA; this.selectImage_(event.detail.item, activate); },
diff --git a/url/mojo/BUILD.gn b/url/mojo/BUILD.gn index 970ed7a..7d5e5d69 100644 --- a/url/mojo/BUILD.gn +++ b/url/mojo/BUILD.gn
@@ -8,9 +8,6 @@ sources = [ "url.mojom", ] - - # TODO(crbug.com/699569): Convert to use the new JS bindings. - js_bindings_mode = "both" } mojom("url_mojom_origin") { @@ -21,9 +18,6 @@ public_deps = [ ":url_mojom_gurl", ] - - # TODO(crbug.com/699569): Convert to use the new JS bindings. - js_bindings_mode = "both" } mojom("test_url_mojom_gurl") {