diff --git a/BUILD.gn b/BUILD.gn index 9378182..a4625d7 100644 --- a/BUILD.gn +++ b/BUILD.gn
@@ -456,7 +456,10 @@ } if (enable_extensions) { - deps += [ "//extensions/shell:app_shell" ] + deps += [ + "//extensions/shell:app_shell", + "//extensions/shell/installer:app_shell_installer", + ] } if (enable_nacl) {
diff --git a/DEPS b/DEPS index 43d68cd..3c75e871e 100644 --- a/DEPS +++ b/DEPS
@@ -64,7 +64,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': '748793bd30ef25919c069f1856cc7e6ee0aee181', + 'pdfium_revision': '897c4b922f1fb50b942cda6cab0f4605f8afac3c', # 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. @@ -96,7 +96,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling catapult # and whatever else without interference from each other. - 'catapult_revision': '1ffc3ed0526747eded946b2970a50046603b9272', + 'catapult_revision': '4ef4b9509fe15a757ad506be6bac48070eb945d3', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other.
diff --git a/android_webview/java/src/org/chromium/android_webview/AwSafeBrowsingConfigHelper.java b/android_webview/java/src/org/chromium/android_webview/AwSafeBrowsingConfigHelper.java index c6b6a14..1177fea 100644 --- a/android_webview/java/src/org/chromium/android_webview/AwSafeBrowsingConfigHelper.java +++ b/android_webview/java/src/org/chromium/android_webview/AwSafeBrowsingConfigHelper.java
@@ -4,13 +4,9 @@ package org.chromium.android_webview; -import android.annotation.SuppressLint; -import android.content.ContentResolver; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; -import android.os.AsyncTask; -import android.provider.Settings; import org.chromium.base.CommandLine; import org.chromium.base.Log; @@ -26,25 +22,15 @@ private static final String OPT_IN_META_DATA_STR = "android.webkit.WebView.EnableSafeBrowsing"; public static void maybeInitSafeBrowsingFromSettings(final Context appContext) { - if (AwSafeBrowsingConfigHelper.shouldEnableSafeBrowsingSupport(appContext)) { - // Assume safebrowsing on by default initially. + if (CommandLine.getInstance().hasSwitch(AwSwitches.WEBVIEW_ENABLE_SAFEBROWSING_SUPPORT) + || appHasOptedIn(appContext)) { + // Assume safebrowsing on by default initially. If GMS is available, we later use + // isVerifyAppsEnabled() to check if "Scan device for security threats" has been checked + // by the user. AwContentsStatics.setSafeBrowsingEnabled(true); - // Fetch Android settings related to safe-browsing in the background. - AsyncTask.THREAD_POOL_EXECUTOR.execute(new Runnable() { - @Override - public void run() { - AwContentsStatics.setSafeBrowsingEnabled( - isScanDeviceForSecurityThreatsEnabled(appContext)); - } - }); } } - private static boolean shouldEnableSafeBrowsingSupport(Context appContext) { - return CommandLine.getInstance().hasSwitch(AwSwitches.WEBVIEW_ENABLE_SAFEBROWSING_SUPPORT) - || appHasOptedIn(appContext); - } - private static boolean appHasOptedIn(Context appContext) { try { ApplicationInfo info = appContext.getPackageManager().getApplicationInfo( @@ -63,14 +49,6 @@ } } - @SuppressLint("NewApi") // android.provider.Settings.Global#getInt requires API level 17 - private static boolean isScanDeviceForSecurityThreatsEnabled(Context applicationContext) { - // Determine if the "Scan device for security threats" functionality is enabled in - // Android->System->Google->Security settings. - ContentResolver contentResolver = applicationContext.getContentResolver(); - return Settings.Secure.getInt(contentResolver, "package_verifier_user_consent", 1) > 0; - } - // Not meant to be instantiated. private AwSafeBrowsingConfigHelper() {} }
diff --git a/ash/BUILD.gn b/ash/BUILD.gn index 04c1ca6..26914aa 100644 --- a/ash/BUILD.gn +++ b/ash/BUILD.gn
@@ -188,6 +188,8 @@ "host/root_window_transformer.h", "host/transformer_helper.cc", "host/transformer_helper.h", + "ime/ime_controller.cc", + "ime/ime_controller.h", "ime/ime_switch_type.h", "key_event_watcher.cc", "key_event_watcher.h",
diff --git a/ash/app_list/app_list_delegate_impl.cc b/ash/app_list/app_list_delegate_impl.cc index 1ff3bfc3..ef2f8c9 100644 --- a/ash/app_list/app_list_delegate_impl.cc +++ b/ash/app_list/app_list_delegate_impl.cc
@@ -5,13 +5,15 @@ #include "ash/app_list/app_list_delegate_impl.h" #include "ash/root_window_controller.h" +#include "ash/shelf/app_list_button.h" +#include "ash/shelf/shelf.h" +#include "ash/shelf/shelf_widget.h" #include "ash/shell.h" #include "ash/shell_port.h" -#include "ui/app_list/app_list_features.h" #include "ui/app_list/presenter/app_list.h" namespace ash { -// TODO(newcomer): Remove this class as a part of crbug.com/726838 + AppListDelegateImpl::AppListDelegateImpl() { Shell::Get()->app_list()->set_delegate(this); } @@ -22,11 +24,17 @@ void AppListDelegateImpl::OnAppListVisibilityChanged(bool visible, int64_t display_id) { - if (app_list::features::IsFullscreenAppListEnabled()) { - aura::Window* root_window = - ShellPort::Get()->GetRootWindowForDisplayId(display_id); - Shell::Get()->OnAppListVisibilityChanged(visible, root_window); - } + aura::Window* root_window = + ShellPort::Get()->GetRootWindowForDisplayId(display_id); + AppListButton* app_list_button = + Shelf::ForWindow(root_window)->shelf_widget()->GetAppListButton(); + if (!app_list_button) + return; + + if (visible) + app_list_button->OnAppListShown(); + else + app_list_button->OnAppListDismissed(); } } // namespace ash
diff --git a/ash/app_list/app_list_presenter_delegate.cc b/ash/app_list/app_list_presenter_delegate.cc index fc81a0ab..01b2bcc5 100644 --- a/ash/app_list/app_list_presenter_delegate.cc +++ b/ash/app_list/app_list_presenter_delegate.cc
@@ -119,9 +119,13 @@ void AppListPresenterDelegate::OnShown(int64_t display_id) { is_visible_ = true; + // Update applist button status when app list visibility is changed. aura::Window* root_window = ShellPort::Get()->GetRootWindowForDisplayId(display_id); - Shell::Get()->OnAppListVisibilityChanged(is_visible_, root_window); + AppListButton* app_list_button = + Shelf::ForWindow(root_window)->shelf_widget()->GetAppListButton(); + if (app_list_button) + app_list_button->OnAppListShown(); } void AppListPresenterDelegate::OnDismissed() { @@ -129,9 +133,12 @@ DCHECK(view_); is_visible_ = false; - aura::Window* root_window = - RootWindowController::ForTargetRootWindow()->GetRootWindow(); - Shell::Get()->OnAppListVisibilityChanged(is_visible_, root_window); + + // Update applist button status when app list visibility is changed. + Shelf* shelf = Shelf::ForWindow(view_->GetWidget()->GetNativeWindow()); + AppListButton* app_list_button = shelf->shelf_widget()->GetAppListButton(); + if (app_list_button) + app_list_button->OnAppListDismissed(); } void AppListPresenterDelegate::UpdateBounds() {
diff --git a/ash/app_list/app_list_presenter_delegate_unittest.cc b/ash/app_list/app_list_presenter_delegate_unittest.cc index 3d27aa20..ab85c94 100644 --- a/ash/app_list/app_list_presenter_delegate_unittest.cc +++ b/ash/app_list/app_list_presenter_delegate_unittest.cc
@@ -5,7 +5,6 @@ #include <memory> #include "ash/ash_switches.h" -#include "ash/public/cpp/config.h" #include "ash/public/cpp/shell_window_ids.h" #include "ash/shell.h" #include "ash/test/ash_test_base.h" @@ -15,8 +14,6 @@ #include "base/macros.h" #include "base/test/scoped_feature_list.h" #include "ui/app_list/app_list_features.h" -#include "ui/app_list/app_list_switches.h" -#include "ui/app_list/views/app_list_main_view.h" #include "ui/app_list/views/app_list_view.h" #include "ui/aura/test/test_windows.h" #include "ui/aura/window.h" @@ -57,12 +54,12 @@ UpdateDisplay("1024x768"); } + private: void EnableFullscreenAppList() { scoped_feature_list_.InitAndEnableFeature( app_list::features::kEnableFullscreenAppList); } - private: test::TestAppListViewPresenterImpl app_list_presenter_impl_; bool test_with_fullscreen_; base::test::ScopedFeatureList scoped_feature_list_; @@ -74,7 +71,7 @@ // the parameterized tests. INSTANTIATE_TEST_CASE_P(, AppListPresenterDelegateTest, testing::Bool()); -// Tests that app list hides when focus moves to a normal window. +// Tests that app launcher hides when focus moves to a normal window. TEST_P(AppListPresenterDelegateTest, HideOnFocusOut) { app_list_presenter_impl()->Show(GetPrimaryDisplayId()); EXPECT_TRUE(app_list_presenter_impl()->GetTargetVisibility()); @@ -85,7 +82,7 @@ EXPECT_FALSE(app_list_presenter_impl()->GetTargetVisibility()); } -// Tests that app list remains visible when focus is moved to a different +// Tests that app launcher remains visible when focus is moved to a different // window in kShellWindowId_AppListContainer. TEST_P(AppListPresenterDelegateTest, RemainVisibleWhenFocusingToApplistContainer) { @@ -143,7 +140,7 @@ EXPECT_FALSE(app_list_presenter_impl()->GetTargetVisibility()); } -// Tests opening the app list on a non-primary display, then deleting the +// Tests opening the app launcher on a non-primary display, then deleting the // display. TEST_P(AppListPresenterDelegateTest, NonPrimaryDisplay) { // Set up a screen with two displays (horizontally adjacent). @@ -166,7 +163,7 @@ EXPECT_FALSE(app_list_presenter_impl()->GetTargetVisibility()); } -// Tests opening the app list on a tiny display that is too small to contain +// Tests opening the app launcher on a tiny display that is too small to contain // it. TEST_F(AppListPresenterDelegateTest, TinyDisplay) { // Set up a screen with a tiny display (height smaller than the app list). @@ -189,67 +186,4 @@ EXPECT_GE(app_list_view_top, kMinimalAppListMargin); } -// Tests that the peeking app list is enlarged to fullscreen after the user -// types in the search box. -TEST_F(AppListPresenterDelegateTest, SnapToFullscreenAfterSearchboxInput) { - // TODO(newcomer): investigate failure in mash. http://crbug.com/726838. - if (Shell::GetAshConfig() == Config::MASH) - return; - - EnableFullscreenAppList(); - UpdateDisplay("1024x768"); - EXPECT_TRUE(app_list::features::IsFullscreenAppListEnabled()); - app_list_presenter_impl()->Show(GetPrimaryDisplayId()); - app_list::AppListView* app_list = app_list_presenter_impl()->GetView(); - // Check that it is in peeking mode. - EXPECT_FALSE(app_list->is_fullscreen()); - - // Dummy key event to search box. - ui::test::EventGenerator& generator = GetEventGenerator(); - generator.PressKey(ui::KeyboardCode::VKEY_0, 0); - // Check that it is in fullscreen mode. - EXPECT_TRUE(app_list->is_fullscreen()); -} - -// Tests that the peeking app list closes if the user taps outside its -// bounds. -TEST_F(AppListPresenterDelegateTest, TapAndClickOutsideClosesPeekingAppList) { - EnableFullscreenAppList(); - - app_list_presenter_impl()->Show(GetPrimaryDisplayId()); - EXPECT_TRUE(app_list_presenter_impl()->GetTargetVisibility()); - ui::test::EventGenerator& generator = GetEventGenerator(); - - // Grab the bounds of the search box, - // which is guaranteed to be inside the app list. - gfx::Point tap_point = app_list_presenter_impl() - ->GetView() - ->search_box_widget() - ->GetContentsView() - ->GetBoundsInScreen() - .CenterPoint(); - - // Tapping inside the bounds doesn't close the app list. - generator.GestureTapAt(tap_point); - EXPECT_TRUE(app_list_presenter_impl()->GetTargetVisibility()); - - // Clicking inside the bounds doesn't close the app list. - generator.MoveMouseTo(tap_point); - generator.ClickLeftButton(); - EXPECT_TRUE(app_list_presenter_impl()->GetTargetVisibility()); - - // Tapping outside the bounds closes the app list. - tap_point.set_x(tap_point.x() + 750); - generator.GestureTapAt(tap_point); - EXPECT_FALSE(app_list_presenter_impl()->GetTargetVisibility()); - - app_list_presenter_impl()->Show(GetPrimaryDisplayId()); - EXPECT_TRUE(app_list_presenter_impl()->GetTargetVisibility()); - - // Clicking outside the bounds closes the app list. - generator.MoveMouseTo(tap_point); - generator.ClickLeftButton(); - EXPECT_FALSE(app_list_presenter_impl()->GetTargetVisibility()); -} - } // namespace ash
diff --git a/ash/ash_strings.grd b/ash/ash_strings.grd index f4b54e9b..68fe43c 100644 --- a/ash/ash_strings.grd +++ b/ash/ash_strings.grd
@@ -300,6 +300,9 @@ <message name="IDS_ASH_STATUS_TRAY_IME_SETTINGS" desc="The label used for IME settings entry."> Customize languages and input... </message> + <message name="IDS_ASH_STATUS_TRAY_IME_MANAGED" desc="Tooltip for the icon displayed when input methods are managed by enterprise policy"> + Input methods are configured by your administrator. + </message> <message name="IDS_ASH_STATUS_TRAY_IME_EMOJI" desc="The label used for IME emoji entry."> Emoji palette </message>
diff --git a/ash/content/display/screen_orientation_controller_chromeos_unittest.cc b/ash/content/display/screen_orientation_controller_chromeos_unittest.cc index 60fca91..8a708ec 100644 --- a/ash/content/display/screen_orientation_controller_chromeos_unittest.cc +++ b/ash/content/display/screen_orientation_controller_chromeos_unittest.cc
@@ -19,7 +19,6 @@ #include "ash/test/content/test_shell_content_state.h" #include "ash/test/screen_orientation_controller_test_api.h" #include "ash/test/test_shell_delegate.h" -#include "ash/test/test_system_tray_delegate.h" #include "ash/wm/maximize_mode/maximize_mode_controller.h" #include "ash/wm/window_state.h" #include "base/command_line.h"
diff --git a/ash/ime/ime_controller.cc b/ash/ime/ime_controller.cc new file mode 100644 index 0000000..4fc7be5 --- /dev/null +++ b/ash/ime/ime_controller.cc
@@ -0,0 +1,29 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ash/ime/ime_controller.h" + +namespace ash { + +ImeController::ImeController() = default; + +ImeController::~ImeController() = default; + +IMEInfo ImeController::GetCurrentIme() const { + return IMEInfo(); +} + +std::vector<IMEPropertyInfo> ImeController::GetCurrentImeProperties() const { + return std::vector<IMEPropertyInfo>(); +} + +std::vector<IMEInfo> ImeController::GetAvailableImes() const { + return std::vector<IMEInfo>(); +} + +bool ImeController::IsImeManaged() const { + return false; +} + +} // namespace ash
diff --git a/ash/ime/ime_controller.h b/ash/ime/ime_controller.h new file mode 100644 index 0000000..dce021b --- /dev/null +++ b/ash/ime/ime_controller.h
@@ -0,0 +1,44 @@ +// 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_IME_IME_CONTROLLER_H_ +#define ASH_IME_IME_CONTROLLER_H_ + +#include <vector> + +#include "ash/ash_export.h" +#include "ash/system/tray/ime_info.h" +#include "base/macros.h" + +namespace ash { +struct IMEInfo; + +// Connects ash IME users (e.g. the system tray) to the IME implementation, +// which might live in Chrome browser or in a separate mojo service. +// TODO(jamescook): Convert to use mojo IME interface to Chrome browser. +class ASH_EXPORT ImeController { + public: + ImeController(); + virtual ~ImeController(); + + // Returns the currently selected IME. + virtual IMEInfo GetCurrentIme() const; + + // Returns a list of properties for the currently selected IME. + virtual std::vector<IMEPropertyInfo> GetCurrentImeProperties() const; + + // Returns a list of available IMEs. "Available" IMEs are both installed and + // enabled by the user in settings. + virtual std::vector<IMEInfo> GetAvailableImes() const; + + // Returns true if the available IMEs are managed by enterprise policy. + virtual bool IsImeManaged() const; + + private: + DISALLOW_COPY_AND_ASSIGN(ImeController); +}; + +} // namespace ash + +#endif // ASH_IME_IME_CONTROLLER_H_
diff --git a/ash/mus/shell_delegate_mus.cc b/ash/mus/shell_delegate_mus.cc index 744ec66..e6a79c8 100644 --- a/ash/mus/shell_delegate_mus.cc +++ b/ash/mus/shell_delegate_mus.cc
@@ -87,6 +87,10 @@ return new SystemTrayDelegateMus(); } +ImeController* ShellDelegateMus::GetImeController() { + return &stub_ime_controller_; +} + std::unique_ptr<WallpaperDelegate> ShellDelegateMus::CreateWallpaperDelegate() { return base::MakeUnique<WallpaperDelegateMus>(); }
diff --git a/ash/mus/shell_delegate_mus.h b/ash/mus/shell_delegate_mus.h index 7736d37..4c9f266 100644 --- a/ash/mus/shell_delegate_mus.h +++ b/ash/mus/shell_delegate_mus.h
@@ -7,6 +7,7 @@ #include <memory> +#include "ash/ime/ime_controller.h" #include "ash/shell_delegate.h" #include "base/macros.h" @@ -36,6 +37,7 @@ void ShelfInit() override; void ShelfShutdown() override; SystemTrayDelegate* CreateSystemTrayDelegate() override; + ImeController* GetImeController() override; std::unique_ptr<WallpaperDelegate> CreateWallpaperDelegate() override; AccessibilityDelegate* CreateAccessibilityDelegate() override; std::unique_ptr<PaletteDelegate> CreatePaletteDelegate() override; @@ -53,6 +55,7 @@ private: // |connector_| may be null in tests. service_manager::Connector* connector_; + ImeController stub_ime_controller_; DISALLOW_COPY_AND_ASSIGN(ShellDelegateMus); };
diff --git a/ash/public/cpp/shell_window_ids.h b/ash/public/cpp/shell_window_ids.h index 7d0b3f1..d5ae3c0 100644 --- a/ash/public/cpp/shell_window_ids.h +++ b/ash/public/cpp/shell_window_ids.h
@@ -56,9 +56,6 @@ // The container for top-level windows with the 'always-on-top' flag set. kShellWindowId_AlwaysOnTopContainer, - // The container for the app list. - kShellWindowId_AppListContainer, - // The container for the shelf. kShellWindowId_ShelfContainer, @@ -68,6 +65,9 @@ // The container for panel windows. kShellWindowId_PanelContainer, + // The container for the app list. + kShellWindowId_AppListContainer, + // The container for user-specific modal windows. kShellWindowId_SystemModalContainer, @@ -137,10 +137,10 @@ kShellWindowId_VirtualKeyboardContainer, kShellWindowId_DefaultContainer, kShellWindowId_AlwaysOnTopContainer, - kShellWindowId_AppListContainer, kShellWindowId_ShelfContainer, kShellWindowId_ShelfBubbleContainer, kShellWindowId_PanelContainer, + kShellWindowId_AppListContainer, kShellWindowId_SystemModalContainer, kShellWindowId_LockScreenWallpaperContainer, kShellWindowId_LockScreenContainer,
diff --git a/ash/root_window_controller.cc b/ash/root_window_controller.cc index 14c0548..7910744 100644 --- a/ash/root_window_controller.cc +++ b/ash/root_window_controller.cc
@@ -897,12 +897,6 @@ wm::SetSnapsChildrenToPhysicalPixelBoundary(always_on_top_container); always_on_top_container->SetProperty(kUsesScreenCoordinatesKey, true); - aura::Window* app_list_container = - CreateContainer(kShellWindowId_AppListContainer, "AppListContainer", - non_lock_screen_containers); - wm::SetSnapsChildrenToPhysicalPixelBoundary(app_list_container); - app_list_container->SetProperty(kUsesScreenCoordinatesKey, true); - aura::Window* shelf_container = CreateContainer(kShellWindowId_ShelfContainer, "ShelfContainer", non_lock_screen_containers); @@ -923,6 +917,12 @@ shelf_bubble_container->SetProperty(kUsesScreenCoordinatesKey, true); shelf_bubble_container->SetProperty(kLockedToRootKey, true); + aura::Window* app_list_container = + CreateContainer(kShellWindowId_AppListContainer, "AppListContainer", + non_lock_screen_containers); + wm::SetSnapsChildrenToPhysicalPixelBoundary(app_list_container); + app_list_container->SetProperty(kUsesScreenCoordinatesKey, true); + aura::Window* modal_container = CreateContainer(kShellWindowId_SystemModalContainer, "SystemModalContainer", non_lock_screen_containers);
diff --git a/ash/shelf/app_list_button.cc b/ash/shelf/app_list_button.cc index efecc29..584d9d8 100644 --- a/ash/shelf/app_list_button.cc +++ b/ash/shelf/app_list_button.cc
@@ -44,7 +44,7 @@ DCHECK(listener_); DCHECK(shelf_view_); DCHECK(shelf_); - Shell::Get()->AddShellObserver(this); + SetInkDropMode(InkDropMode::ON_NO_GESTURE_HANDLER); set_ink_drop_base_color(kShelfInkDropBaseColor); set_ink_drop_visible_opacity(kShelfInkDropVisibleOpacity); @@ -55,9 +55,7 @@ set_notify_action(CustomButton::NOTIFY_ON_PRESS); } -AppListButton::~AppListButton() { - Shell::Get()->RemoveShellObserver(this); -} +AppListButton::~AppListButton() {} void AppListButton::OnAppListShown() { AnimateInkDrop(views::InkDropState::ACTIVATED, nullptr); @@ -241,15 +239,4 @@ } } -void AppListButton::OnAppListVisibilityChanged(bool shown, - aura::Window* root_window) { - if (shelf_ != Shelf::ForWindow(root_window)) - return; - - if (shown) - OnAppListShown(); - else - OnAppListDismissed(); -} - } // namespace ash
diff --git a/ash/shelf/app_list_button.h b/ash/shelf/app_list_button.h index fa9a35b..02c69c2 100644 --- a/ash/shelf/app_list_button.h +++ b/ash/shelf/app_list_button.h
@@ -8,7 +8,6 @@ #include <memory> #include "ash/ash_export.h" -#include "ash/shell_observer.h" #include "base/macros.h" #include "third_party/skia/include/core/SkColor.h" #include "ui/views/controls/button/image_button.h" @@ -19,8 +18,7 @@ class ShelfView; // Button used for the AppList icon on the shelf. -class ASH_EXPORT AppListButton : public views::ImageButton, - public ShellObserver { +class ASH_EXPORT AppListButton : public views::ImageButton { public: AppListButton(InkDropButtonListener* listener, ShelfView* shelf_view, @@ -57,10 +55,6 @@ // ink drops. gfx::Point GetCenterPoint() const; - // ShellObserver overrides: - void OnAppListVisibilityChanged(bool shown, - aura::Window* root_window) override; - // True if the app list is currently showing for this display. // This is useful because other IsApplistVisible functions aren't per-display. bool is_showing_app_list_;
diff --git a/ash/shelf/shelf_layout_manager.cc b/ash/shelf/shelf_layout_manager.cc index d5474587..3b2c170 100644 --- a/ash/shelf/shelf_layout_manager.cc +++ b/ash/shelf/shelf_layout_manager.cc
@@ -28,7 +28,6 @@ #include "base/auto_reset.h" #include "base/command_line.h" #include "base/i18n/rtl.h" -#include "ui/app_list/app_list_features.h" #include "ui/base/ui_base_switches.h" #include "ui/compositor/layer.h" #include "ui/compositor/layer_animation_observer.h" @@ -426,16 +425,6 @@ &keyboard_observer_); } -void ShelfLayoutManager::OnAppListVisibilityChanged(bool shown, - aura::Window* root_window) { - if (shelf_ != Shelf::ForWindow(root_window)) - return; - - is_app_list_visible_ = shown; - if (app_list::features::IsFullscreenAppListEnabled()) - MaybeUpdateShelfBackground(AnimationChangeType::IMMEDIATE); -} - void ShelfLayoutManager::OnWindowActivated(ActivationReason reason, aura::Window* gained_active, aura::Window* lost_active) { @@ -479,10 +468,6 @@ if (state_.session_state != session_manager::SessionState::ACTIVE) return SHELF_BACKGROUND_OVERLAP; - // If the app list is active, hide the shelf background to prevent overlap. - if (is_app_list_visible_ && app_list::features::IsFullscreenAppListEnabled()) - return SHELF_BACKGROUND_DEFAULT; - if (state_.visibility_state != SHELF_AUTO_HIDE && state_.window_state == wm::WORKSPACE_WINDOW_STATE_MAXIMIZED) { return SHELF_BACKGROUND_MAXIMIZED;
diff --git a/ash/shelf/shelf_layout_manager.h b/ash/shelf/shelf_layout_manager.h index 7c3731a..7e66fb2 100644 --- a/ash/shelf/shelf_layout_manager.h +++ b/ash/shelf/shelf_layout_manager.h
@@ -64,6 +64,7 @@ // Clears internal data for shutdown process. void PrepareForShutdown(); + // Returns whether the shelf and its contents (shelf, status) are visible // on the screen. bool IsVisible() const; @@ -137,8 +138,6 @@ void OnPinnedStateChanged(aura::Window* pinned_window) override; void OnVirtualKeyboardStateChanged(bool activated, aura::Window* root_window) override; - void OnAppListVisibilityChanged(bool shown, - aura::Window* root_window) override; // Overridden from wm::ActivationChangeObserver: void OnWindowActivated(ActivationReason reason, @@ -318,10 +317,6 @@ // Do any windows overlap the shelf? This is maintained by WorkspaceManager. bool window_overlaps_shelf_; - // Is the AppList visible? This is maintained by - // OnAppListVisibilityChanged. - bool is_app_list_visible_ = false; - base::OneShotTimer auto_hide_timer_; // Whether the mouse was over the shelf when the auto hide timer started.
diff --git a/ash/shelf/shelf_view_unittest.cc b/ash/shelf/shelf_view_unittest.cc index 361a947..4ee61920 100644 --- a/ash/shelf/shelf_view_unittest.cc +++ b/ash/shelf/shelf_view_unittest.cc
@@ -34,7 +34,6 @@ #include "ash/test/shelf_view_test_api.h" #include "ash/test/shell_test_api.h" #include "ash/test/test_shell_delegate.h" -#include "ash/test/test_system_tray_delegate.h" #include "ash/test/wallpaper_controller_test_api.h" #include "ash/wallpaper/wallpaper_controller.h" #include "base/i18n/rtl.h"
diff --git a/ash/shell.cc b/ash/shell.cc index 1186c21..e7e58d4 100644 --- a/ash/shell.cc +++ b/ash/shell.cc
@@ -42,6 +42,7 @@ #include "ash/frame/custom_frame_view_ash.h" #include "ash/gpu_support.h" #include "ash/high_contrast/high_contrast_controller.h" +#include "ash/ime/ime_controller.h" #include "ash/keyboard/keyboard_ui.h" #include "ash/laser/laser_pointer_controller.h" #include "ash/login/lock_screen_controller.h" @@ -553,12 +554,6 @@ g_is_browser_process_with_mash = true; } -void Shell::OnAppListVisibilityChanged(bool visible, - aura::Window* root_window) { - for (auto& observer : shell_observers_) - observer.OnAppListVisibilityChanged(visible, root_window); -} - //////////////////////////////////////////////////////////////////////////////// // Shell, private: @@ -570,6 +565,7 @@ base::MakeUnique<system::BrightnessControllerChromeos>()), cast_config_(base::MakeUnique<CastConfigController>()), focus_cycler_(base::MakeUnique<FocusCycler>()), + ime_controller_(shell_delegate->GetImeController()), immersive_context_(base::MakeUnique<ImmersiveContextAsh>()), keyboard_brightness_control_delegate_( base::MakeUnique<KeyboardBrightnessController>()), @@ -595,6 +591,7 @@ native_cursor_manager_(nullptr), simulate_modal_window_open_for_testing_(false), is_touch_hud_projection_enabled_(false) { + DCHECK(ime_controller_); // TODO(sky): better refactor cash/mash dependencies. Perhaps put all cash // state on ShellPortClassic. http://crbug.com/671246. @@ -922,9 +919,11 @@ if (!display_initialized) display_manager_->InitDefaultDisplay(); - if (config == Config::CLASSIC) { + // TODO(sky): move this to chrome for mash. http://crbug.com/729824. + if (ShouldEnableSimplifiedDisplayManagement()) display_manager_->RefreshFontParams(); + if (config == Config::CLASSIC) { aura::Env::GetInstance()->set_context_factory(init_params.context_factory); aura::Env::GetInstance()->set_context_factory_private( init_params.context_factory_private);
diff --git a/ash/shell.h b/ash/shell.h index 6be67bc5..910315c 100644 --- a/ash/shell.h +++ b/ash/shell.h
@@ -18,7 +18,6 @@ #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "base/observer_list.h" -#include "ui/app_list/presenter/app_list_delegate.h" #include "ui/aura/window.h" #include "ui/display/screen.h" #include "ui/events/event_target.h" @@ -110,6 +109,7 @@ class FocusCycler; class GPUSupport; class HighContrastController; +class ImeController; class ImmersiveContextAsh; class ImmersiveHandlerFactoryAsh; class KeyboardBrightnessControlDelegate; @@ -324,6 +324,7 @@ } ::wm::CompoundEventFilter* env_filter() { return env_filter_.get(); } FocusCycler* focus_cycler() { return focus_cycler_.get(); } + ImeController* ime_controller() { return ime_controller_; } KeyboardBrightnessControlDelegate* keyboard_brightness_control_delegate() { return keyboard_brightness_control_delegate_.get(); } @@ -610,8 +611,6 @@ // Used to provide better error messages for Shell::Get() under mash. static void SetIsBrowserProcessWithMash(); - void OnAppListVisibilityChanged(bool visible, aura::Window* root_window); - private: FRIEND_TEST_ALL_PREFIXES(ExtendedDesktopTest, TestCursor); FRIEND_TEST_ALL_PREFIXES(WindowManagerTest, MouseEventCursors); @@ -692,6 +691,7 @@ std::unique_ptr<CastConfigController> cast_config_; std::unique_ptr<DragDropController> drag_drop_controller_; std::unique_ptr<FocusCycler> focus_cycler_; + ImeController* const ime_controller_; std::unique_ptr<ImmersiveContextAsh> immersive_context_; std::unique_ptr<KeyboardBrightnessControlDelegate> keyboard_brightness_control_delegate_;
diff --git a/ash/shell/shell_delegate_impl.cc b/ash/shell/shell_delegate_impl.cc index 6958fe8..5dc0147 100644 --- a/ash/shell/shell_delegate_impl.cc +++ b/ash/shell/shell_delegate_impl.cc
@@ -14,8 +14,8 @@ #include "ash/shell/context_menu.h" #include "ash/shell/example_factory.h" #include "ash/shell/toplevel_window.h" +#include "ash/system/tray/system_tray_delegate.h" #include "ash/test/test_keyboard_ui.h" -#include "ash/test/test_system_tray_delegate.h" #include "ash/wm/window_state.h" #include "base/memory/ptr_util.h" #include "base/message_loop/message_loop.h" @@ -107,7 +107,11 @@ void ShellDelegateImpl::ShelfShutdown() {} SystemTrayDelegate* ShellDelegateImpl::CreateSystemTrayDelegate() { - return new test::TestSystemTrayDelegate; + return new SystemTrayDelegate; +} + +ImeController* ShellDelegateImpl::GetImeController() { + return &stub_ime_controller_; } std::unique_ptr<WallpaperDelegate>
diff --git a/ash/shell/shell_delegate_impl.h b/ash/shell/shell_delegate_impl.h index 0074e50c..ba873a7 100644 --- a/ash/shell/shell_delegate_impl.h +++ b/ash/shell/shell_delegate_impl.h
@@ -8,6 +8,7 @@ #include <memory> #include <string> +#include "ash/ime/ime_controller.h" #include "ash/shell_delegate.h" #include "base/macros.h" @@ -38,6 +39,7 @@ void ShelfInit() override; void ShelfShutdown() override; SystemTrayDelegate* CreateSystemTrayDelegate() override; + ImeController* GetImeController() override; std::unique_ptr<WallpaperDelegate> CreateWallpaperDelegate() override; AccessibilityDelegate* CreateAccessibilityDelegate() override; std::unique_ptr<PaletteDelegate> CreatePaletteDelegate() override; @@ -53,6 +55,8 @@ void UpdateTouchscreenStatusFromPrefs() override; private: + ImeController stub_ime_controller_; + DISALLOW_COPY_AND_ASSIGN(ShellDelegateImpl); };
diff --git a/ash/shell_delegate.h b/ash/shell_delegate.h index f5c62c3b..583a852 100644 --- a/ash/shell_delegate.h +++ b/ash/shell_delegate.h
@@ -39,6 +39,7 @@ class AccessibilityDelegate; class GPUSupport; +class ImeController; class PaletteDelegate; class Shelf; struct ShelfItem; @@ -98,6 +99,9 @@ // Creates a system-tray delegate. Shell takes ownership of the delegate. virtual SystemTrayDelegate* CreateSystemTrayDelegate() = 0; + // TODO(jamescook): Remove in favor of chrome using a mojo interface on ash. + virtual ImeController* GetImeController() = 0; + // Creates a wallpaper delegate. Shell takes ownership of the delegate. virtual std::unique_ptr<WallpaperDelegate> CreateWallpaperDelegate() = 0;
diff --git a/ash/shell_observer.h b/ash/shell_observer.h index fc0bbaf8..563f2a59 100644 --- a/ash/shell_observer.h +++ b/ash/shell_observer.h
@@ -16,10 +16,6 @@ class ASH_EXPORT ShellObserver { public: - // Called when the AppList is shown or dismissed. - virtual void OnAppListVisibilityChanged(bool shown, - aura::Window* root_window) {} - // Called when a casting session is started or stopped. virtual void OnCastingSessionStartedOrStopped(bool started) {}
diff --git a/ash/system/ime/tray_ime_chromeos.cc b/ash/system/ime/tray_ime_chromeos.cc index 9ecec4f7..abd34c2 100644 --- a/ash/system/ime/tray_ime_chromeos.cc +++ b/ash/system/ime/tray_ime_chromeos.cc
@@ -7,13 +7,13 @@ #include <memory> #include <vector> +#include "ash/ime/ime_controller.h" #include "ash/resources/vector_icons/vector_icons.h" #include "ash/shell.h" #include "ash/shell_port.h" #include "ash/strings/grit/ash_strings.h" #include "ash/system/tray/system_tray.h" #include "ash/system/tray/system_tray_controller.h" -#include "ash/system/tray/system_tray_delegate.h" #include "ash/system/tray/system_tray_notifier.h" #include "ash/system/tray/tray_constants.h" #include "ash/system/tray/tray_details_view.h" @@ -75,13 +75,15 @@ // enterprise-controlled icon). class IMEDetailedView : public ImeListView { public: - explicit IMEDetailedView(SystemTrayItem* owner) - : ImeListView(owner), settings_button_(nullptr) {} + IMEDetailedView(SystemTrayItem* owner, ImeController* ime_controller) + : ImeListView(owner), ime_controller_(ime_controller) { + DCHECK(ime_controller_); + } ~IMEDetailedView() override {} - void SetImeManagedMessage(base::string16 ime_managed_message) { - ime_managed_message_ = ime_managed_message; + views::ImageView* controlled_setting_icon() { + return controlled_setting_icon_; } void Update(const IMEInfoList& list, @@ -110,11 +112,12 @@ } void CreateExtraTitleRowButtons() override { - if (!ime_managed_message_.empty()) { + if (ime_controller_->IsImeManaged()) { controlled_setting_icon_ = TrayPopupUtils::CreateMainImageView(); controlled_setting_icon_->SetImage( gfx::CreateVectorIcon(kSystemMenuBusinessIcon, kMenuIconColor)); - controlled_setting_icon_->SetTooltipText(ime_managed_message_); + controlled_setting_icon_->SetTooltipText( + l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_IME_MANAGED)); tri_view()->AddView(TriView::Container::END, controlled_setting_icon_); } @@ -131,13 +134,13 @@ owner()->system_tray()->CloseSystemBubble(); } - views::Button* settings_button_; + ImeController* const ime_controller_; + + // Gear icon that takes the user to IME settings. + views::Button* settings_button_ = nullptr; // This icon says that the IMEs are managed by policy. - views::ImageView* controlled_setting_icon_; - // If non-empty, a controlled setting icon should be displayed with this - // string as tooltip. - base::string16 ime_managed_message_; + views::ImageView* controlled_setting_icon_ = nullptr; DISALLOW_COPY_AND_ASSIGN(IMEDetailedView); }; @@ -146,11 +149,13 @@ TrayIME::TrayIME(SystemTray* system_tray) : SystemTrayItem(system_tray, UMA_IME), + ime_controller_(Shell::Get()->ime_controller()), tray_label_(nullptr), default_(nullptr), detailed_(nullptr), keyboard_suppressed_(false), is_visible_(true) { + DCHECK(ime_controller_); SystemTrayNotifier* tray_notifier = Shell::Get()->system_tray_notifier(); tray_notifier->AddVirtualKeyboardObserver(this); tray_notifier->AddAccessibilityObserver(this); @@ -181,7 +186,6 @@ default_->UpdateLabel(GetDefaultViewLabel(ime_list_.size() > 1)); } if (detailed_) { - detailed_->SetImeManagedMessage(ime_managed_message_); detailed_->Update(ime_list_, property_list_, ShouldShowKeyboardToggle(), GetSingleImeBehavior()); } @@ -211,9 +215,7 @@ base::string16 TrayIME::GetDefaultViewLabel(bool show_ime_label) { if (show_ime_label) { - IMEInfo current; - Shell::Get()->system_tray_delegate()->GetCurrentIME(¤t); - return current.name; + return ime_controller_->GetCurrentIme().name; } else { // Display virtual keyboard status instead. int id = keyboard::IsKeyboardEnabled() @@ -244,8 +246,7 @@ views::View* TrayIME::CreateDetailedView(LoginStatus status) { CHECK(detailed_ == nullptr); - detailed_ = new tray::IMEDetailedView(this); - detailed_->SetImeManagedMessage(ime_managed_message_); + detailed_ = new tray::IMEDetailedView(this, ime_controller_); detailed_->Init(ShouldShowKeyboardToggle(), GetSingleImeBehavior()); return detailed_; } @@ -264,13 +265,9 @@ void TrayIME::OnIMERefresh() { // Caches the current ime state. - SystemTrayDelegate* delegate = Shell::Get()->system_tray_delegate(); - ime_list_.clear(); - property_list_.clear(); - delegate->GetCurrentIME(¤t_ime_); - delegate->GetAvailableIMEList(&ime_list_); - delegate->GetCurrentIMEProperties(&property_list_); - ime_managed_message_ = delegate->GetIMEManagedMessage(); + current_ime_ = ime_controller_->GetCurrentIme(); + property_list_ = ime_controller_->GetCurrentImeProperties(); + ime_list_ = ime_controller_->GetAvailableImes(); Update(); } @@ -284,7 +281,7 @@ } bool TrayIME::IsIMEManaged() { - return !ime_managed_message_.empty(); + return ime_controller_->IsImeManaged(); } bool TrayIME::ShouldDefaultViewBeVisible() { @@ -306,4 +303,8 @@ : ImeListView::HIDE_SINGLE_IME; } +views::View* TrayIME::GetControlledSettingIconForTesting() { + return detailed_ ? detailed_->controlled_setting_icon() : nullptr; +} + } // namespace ash
diff --git a/ash/system/ime/tray_ime_chromeos.h b/ash/system/ime/tray_ime_chromeos.h index ac60097..699f9696 100644 --- a/ash/system/ime/tray_ime_chromeos.h +++ b/ash/system/ime/tray_ime_chromeos.h
@@ -22,6 +22,7 @@ class IMEDetailedView; } +class ImeController; class TrayItemView; // Controller for IME options in the system menu. Note this is separate from @@ -67,7 +68,7 @@ void OnIMERefresh() override; void OnIMEMenuActivationChanged(bool is_active) override; - // Returns true input methods are managed by policy. + // Returns true if input methods are managed by policy. bool IsIMEManaged(); // Whether the default view should be shown. @@ -79,6 +80,10 @@ // sub-view. ImeListView::SingleImeBehavior GetSingleImeBehavior(); + // Returns the icon used when the IME is managed. + views::View* GetControlledSettingIconForTesting(); + + ImeController* ime_controller_; TrayItemView* tray_label_; tray::IMEDefaultView* default_; tray::IMEDetailedView* detailed_; @@ -88,9 +93,6 @@ IMEInfoList ime_list_; IMEInfo current_ime_; IMEPropertyInfoList property_list_; - // If non-empty, a controlled-setting icon should be displayed with a tooltip - // text defined by this string. - base::string16 ime_managed_message_; // Whether the IME label and tray items should be visible. bool is_visible_;
diff --git a/ash/system/ime/tray_ime_chromeos_unittest.cc b/ash/system/ime/tray_ime_chromeos_unittest.cc index a7b2fe47..9bbad2f 100644 --- a/ash/system/ime/tray_ime_chromeos_unittest.cc +++ b/ash/system/ime/tray_ime_chromeos_unittest.cc
@@ -6,6 +6,7 @@ #include "ash/accessibility_delegate.h" #include "ash/accessibility_types.h" +#include "ash/ime/ime_controller.h" #include "ash/public/cpp/config.h" #include "ash/shell.h" #include "ash/system/ime_menu/ime_list_view.h" @@ -16,6 +17,31 @@ #include "ui/keyboard/keyboard_util.h" namespace ash { +namespace { + +class TestImeController : public ImeController { + public: + TestImeController() = default; + ~TestImeController() override = default; + + // ImeController: + std::vector<IMEPropertyInfo> GetCurrentImeProperties() const override { + return current_ime_properties_; + } + std::vector<IMEInfo> GetAvailableImes() const override { + return available_imes_; + } + bool IsImeManaged() const override { return is_ime_managed_; } + + std::vector<IMEPropertyInfo> current_ime_properties_; + std::vector<IMEInfo> available_imes_; + bool is_ime_managed_ = false; + + private: + DISALLOW_COPY_AND_ASSIGN(TestImeController); +}; + +} // namespace class TrayIMETest : public test::AshTestBase { public: @@ -30,15 +56,18 @@ // is not created in ash tests. void SetAccessibilityKeyboardEnabled(bool enabled); - // Sets the current number of active IMEs. - void SetIMELength(int length); + // Creates |count| simulated active IMEs. + void SetActiveImeCount(int count); // Returns the view responsible for toggling virtual keyboard. views::View* GetToggleView() const; - // Sets the managed IMEs tooltip message (and thus also if IMEs are managed = - // non-empty or not = empty) - void SetManagedMessage(base::string16 managed_message); + // Simulates IME being managed by policy. + void SetImeManaged(bool managed); + + views::View* GetImeManagedIcon(); + + void AddPropertyToCurrentIme(IMEPropertyInfo property); void SuppressKeyboard(); void RestoreKeyboard(); @@ -48,6 +77,7 @@ void TearDown() override; private: + TestImeController test_ime_controller_; std::unique_ptr<TrayIME> tray_; std::unique_ptr<views::View> default_view_; std::unique_ptr<views::View> detailed_view_; @@ -68,13 +98,13 @@ notification); } -void TrayIMETest::SetIMELength(int length) { - tray_->ime_list_.clear(); +void TrayIMETest::SetActiveImeCount(int count) { + test_ime_controller_.available_imes_.clear(); IMEInfo ime; - for (int i = 0; i < length; i++) { - tray_->ime_list_.push_back(ime); + for (int i = 0; i < count; i++) { + test_ime_controller_.available_imes_.push_back(ime); } - tray_->Update(); + tray_->OnIMERefresh(); } views::View* TrayIMETest::GetToggleView() const { @@ -82,9 +112,18 @@ return test_api.GetToggleView(); } -void TrayIMETest::SetManagedMessage(base::string16 managed_message) { - tray_->ime_managed_message_ = managed_message; - tray_->Update(); +void TrayIMETest::SetImeManaged(bool managed) { + test_ime_controller_.is_ime_managed_ = true; + tray_->OnIMERefresh(); +} + +views::View* TrayIMETest::GetImeManagedIcon() { + return tray_->GetControlledSettingIconForTesting(); +} + +void TrayIMETest::AddPropertyToCurrentIme(IMEPropertyInfo property) { + test_ime_controller_.current_ime_properties_.push_back(property); + tray_->OnIMERefresh(); } void TrayIMETest::SuppressKeyboard() { @@ -120,6 +159,7 @@ void TrayIMETest::SetUp() { test::AshTestBase::SetUp(); tray_.reset(new TrayIME(GetPrimarySystemTray())); + tray_->ime_controller_ = &test_ime_controller_; default_view_.reset(tray_->CreateDefaultView(LoginStatus::USER)); detailed_view_.reset(tray_->CreateDetailedView(LoginStatus::USER)); } @@ -137,26 +177,57 @@ // Tests that if the keyboard is not suppressed the default view is hidden // if less than 2 IMEs are present. TEST_F(TrayIMETest, HiddenWithNoIMEs) { - SetIMELength(0); + SetActiveImeCount(0); EXPECT_FALSE(default_view()->visible()); - SetIMELength(1); + SetActiveImeCount(1); EXPECT_FALSE(default_view()->visible()); - SetIMELength(2); + SetActiveImeCount(2); EXPECT_TRUE(default_view()->visible()); } // Tests that if IMEs are managed, the default view is displayed even for a // single IME. TEST_F(TrayIMETest, ShownWithSingleIMEWhenManaged) { - SetManagedMessage(base::ASCIIToUTF16("managed")); - SetIMELength(0); + SetImeManaged(true); + SetActiveImeCount(0); EXPECT_FALSE(default_view()->visible()); - SetIMELength(1); + SetActiveImeCount(1); EXPECT_TRUE(default_view()->visible()); - SetIMELength(2); + SetActiveImeCount(2); EXPECT_TRUE(default_view()->visible()); } +// Tests that if an IME has multiple properties the default view is +// displayed even for a single IME. +TEST_F(TrayIMETest, ShownWithSingleImeWithProperties) { + SetActiveImeCount(1); + EXPECT_FALSE(default_view()->visible()); + + IMEPropertyInfo property1; + AddPropertyToCurrentIme(property1); + EXPECT_FALSE(default_view()->visible()); + + IMEPropertyInfo property2; + AddPropertyToCurrentIme(property2); + EXPECT_TRUE(default_view()->visible()); +} + +// Tests that when IMEs are managed an icon appears in the tray with an +// appropriate tooltip. +TEST_F(TrayIMETest, ImeManagedIcon) { + SetActiveImeCount(1); + EXPECT_FALSE(GetImeManagedIcon()); + + SetImeManaged(true); + views::View* icon = GetImeManagedIcon(); + ASSERT_TRUE(icon); + base::string16 tooltip; + icon->GetTooltipText(gfx::Point(), &tooltip); + EXPECT_EQ( + base::ASCIIToUTF16("Input methods are configured by your administrator."), + tooltip); +} + // Tests that if no IMEs are present the default view is hidden when a11y is // enabled. TEST_F(TrayIMETest, HidesOnA11yEnabled) { @@ -164,7 +235,7 @@ if (Shell::GetAshConfig() == Config::MASH) return; - SetIMELength(0); + SetActiveImeCount(0); SuppressKeyboard(); EXPECT_TRUE(default_view()->visible()); // Enable a11y keyboard. @@ -182,7 +253,7 @@ if (Shell::GetAshConfig() == Config::MASH) return; - SetIMELength(0); + SetActiveImeCount(0); SuppressKeyboard(); EXPECT_FALSE(keyboard::IsKeyboardEnabled()); views::View* toggle = GetToggleView();
diff --git a/ash/system/ime_menu/ime_list_view.cc b/ash/system/ime_menu/ime_list_view.cc index 8f2e655f..5600479 100644 --- a/ash/system/ime_menu/ime_list_view.cc +++ b/ash/system/ime_menu/ime_list_view.cc
@@ -4,6 +4,7 @@ #include "ash/system/ime_menu/ime_list_view.h" +#include "ash/ime/ime_controller.h" #include "ash/ime/ime_switch_type.h" #include "ash/resources/vector_icons/vector_icons.h" #include "ash/shell.h" @@ -12,7 +13,6 @@ #include "ash/system/tray/actionable_view.h" #include "ash/system/tray/ime_info.h" #include "ash/system/tray/system_menu_button.h" -#include "ash/system/tray/system_tray_delegate.h" #include "ash/system/tray/tray_constants.h" #include "ash/system/tray/tray_details_view.h" #include "ash/system/tray/tray_popup_header_button.h" @@ -195,11 +195,9 @@ void ImeListView::Init(bool show_keyboard_toggle, SingleImeBehavior single_ime_behavior) { - SystemTrayDelegate* delegate = Shell::Get()->system_tray_delegate(); - IMEInfoList list; - delegate->GetAvailableIMEList(&list); - IMEPropertyInfoList property_list; - delegate->GetCurrentIMEProperties(&property_list); + ImeController* ime_controller = Shell::Get()->ime_controller(); + IMEInfoList list = ime_controller->GetAvailableImes(); + IMEPropertyInfoList property_list = ime_controller->GetCurrentImeProperties(); Update(list, property_list, show_keyboard_toggle, single_ime_behavior); }
diff --git a/ash/system/ime_menu/ime_menu_tray.cc b/ash/system/ime_menu/ime_menu_tray.cc index 17720b43..ce3f458 100644 --- a/ash/system/ime_menu/ime_menu_tray.cc +++ b/ash/system/ime_menu/ime_menu_tray.cc
@@ -6,6 +6,7 @@ #include "ash/accessibility_delegate.h" #include "ash/ash_constants.h" +#include "ash/ime/ime_controller.h" #include "ash/root_window_controller.h" #include "ash/session/session_controller.h" #include "ash/shelf/shelf.h" @@ -15,7 +16,6 @@ #include "ash/system/ime_menu/ime_list_view.h" #include "ash/system/tray/system_menu_button.h" #include "ash/system/tray/system_tray_controller.h" -#include "ash/system/tray/system_tray_delegate.h" #include "ash/system/tray/system_tray_notifier.h" #include "ash/system/tray/tray_constants.h" #include "ash/system/tray/tray_container.h" @@ -279,12 +279,14 @@ ImeMenuTray::ImeMenuTray(Shelf* shelf) : TrayBackgroundView(shelf), + ime_controller_(Shell::Get()->ime_controller()), label_(new ImeMenuLabel()), show_keyboard_(false), force_show_keyboard_(false), keyboard_suppressed_(false), show_bubble_after_keyboard_hidden_(false), weak_ptr_factory_(this) { + DCHECK(ime_controller_); SetInkDropMode(InkDropMode::ON); SetupLabelForTray(label_); label_->SetElideBehavior(gfx::TRUNCATE); @@ -443,11 +445,9 @@ void ImeMenuTray::OnIMERefresh() { UpdateTrayLabel(); if (bubble_ && ime_list_view_) { - SystemTrayDelegate* delegate = Shell::Get()->system_tray_delegate(); - IMEInfoList list; - delegate->GetAvailableIMEList(&list); - IMEPropertyInfoList property_list; - delegate->GetCurrentIMEProperties(&property_list); + std::vector<IMEInfo> list = ime_controller_->GetAvailableImes(); + IMEPropertyInfoList property_list = + ime_controller_->GetCurrentImeProperties(); ime_list_view_->Update(list, property_list, false, ImeListView::SHOW_SINGLE_IME); } @@ -534,7 +534,7 @@ } void ImeMenuTray::UpdateTrayLabel() { - Shell::Get()->system_tray_delegate()->GetCurrentIME(¤t_ime_); + current_ime_ = ime_controller_->GetCurrentIme(); // Updates the tray label based on the current input method. if (current_ime_.third_party)
diff --git a/ash/system/ime_menu/ime_menu_tray.h b/ash/system/ime_menu/ime_menu_tray.h index 3019158ca..d2c9eda 100644 --- a/ash/system/ime_menu/ime_menu_tray.h +++ b/ash/system/ime_menu/ime_menu_tray.h
@@ -20,6 +20,7 @@ } // namespace views namespace ash { +class ImeController; class ImeListView; // A button in the tray which displays the short name of the currently-activated @@ -95,6 +96,8 @@ // Disables the virtual keyboard. void DisableVirtualKeyboard(); + ImeController* ime_controller_; + // Bubble for default and detailed views. std::unique_ptr<TrayBubbleWrapper> bubble_; ImeListView* ime_list_view_;
diff --git a/ash/system/ime_menu/ime_menu_tray_unittest.cc b/ash/system/ime_menu/ime_menu_tray_unittest.cc index 10ea62d8..7bc17e95 100644 --- a/ash/system/ime_menu/ime_menu_tray_unittest.cc +++ b/ash/system/ime_menu/ime_menu_tray_unittest.cc
@@ -6,6 +6,7 @@ #include "ash/accelerators/accelerator_controller.h" #include "ash/accessibility_delegate.h" +#include "ash/ime/ime_controller.h" #include "ash/shell.h" #include "ash/system/ime_menu/ime_list_view.h" #include "ash/system/status_area_widget.h" @@ -13,7 +14,6 @@ #include "ash/system/tray/system_tray_notifier.h" #include "ash/test/ash_test_base.h" #include "ash/test/status_area_widget_test_helper.h" -#include "ash/test/test_system_tray_delegate.h" #include "base/run_loop.h" #include "base/strings/utf_string_conversions.h" #include "ui/accessibility/ax_node_data.h" @@ -27,16 +27,43 @@ using base::UTF8ToUTF16; namespace ash { +namespace { + +class TestImeController : public ImeController { + public: + TestImeController() = default; + ~TestImeController() override = default; + + // ImeController: + IMEInfo GetCurrentIme() const override { return current_ime_; } + std::vector<IMEInfo> GetAvailableImes() const override { + return available_imes_; + } + + IMEInfo current_ime_; + std::vector<IMEInfo> available_imes_; + + private: + DISALLOW_COPY_AND_ASSIGN(TestImeController); +}; ImeMenuTray* GetTray() { return StatusAreaWidgetTestHelper::GetStatusAreaWidget()->ime_menu_tray(); } +} // namespace + class ImeMenuTrayTest : public test::AshTestBase { public: ImeMenuTrayTest() {} ~ImeMenuTrayTest() override {} + // test::AshTestBase: + void SetUp() override { + test::AshTestBase::SetUp(); + GetTray()->ime_controller_ = &test_ime_controller_; + } + protected: // Returns true if the IME menu tray is visible. bool IsVisible() { return GetTray()->visible(); } @@ -50,13 +77,12 @@ // Returns true if the IME menu bubble has been shown. bool IsBubbleShown() { return GetTray()->IsImeMenuBubbleShown(); } - // Returns true if the IME menu list has been updated with the right IME list. - bool IsTrayImeListValid(const std::vector<IMEInfo>& expected_imes, + // Verifies the IME menu list has been updated with the right IME list. + void ExpectValidImeList(const std::vector<IMEInfo>& expected_imes, const IMEInfo& expected_current_ime) { const std::map<views::View*, std::string>& ime_map = ImeListViewTestApi(GetTray()->ime_list_view_).ime_map(); - if (ime_map.size() != expected_imes.size()) - return false; + EXPECT_EQ(expected_imes.size(), ime_map.size()); std::vector<std::string> expected_ime_ids; for (const auto& ime : expected_imes) { @@ -64,22 +90,16 @@ } for (const auto& ime : ime_map) { // Tests that all the IMEs on the view is in the list of selected IMEs. - if (std::find(expected_ime_ids.begin(), expected_ime_ids.end(), - ime.second) == expected_ime_ids.end()) { - return false; - } + EXPECT_TRUE(base::ContainsValue(expected_ime_ids, ime.second)); // Tests that the checked IME is the current IME. ui::AXNodeData node_data; ime.first->GetAccessibleNodeData(&node_data); const auto checked_state = static_cast<ui::AXCheckedState>( node_data.GetIntAttribute(ui::AX_ATTR_CHECKED_STATE)); - if (checked_state == ui::AX_CHECKED_STATE_TRUE) { - if (ime.second != expected_current_ime.id) - return false; - } + if (checked_state == ui::AX_CHECKED_STATE_TRUE) + EXPECT_EQ(expected_current_ime.id, ime.second); } - return true; } // Focuses in the given type of input context. @@ -89,7 +109,15 @@ ui::IMEBridge::Get()->SetCurrentInputContext(input_context); } + void SetCurrentIme(IMEInfo ime) { test_ime_controller_.current_ime_ = ime; } + + void SetAvailableImes(const std::vector<IMEInfo>& imes) { + test_ime_controller_.available_imes_ = imes; + } + private: + TestImeController test_ime_controller_; + DISALLOW_COPY_AND_ASSIGN(ImeMenuTrayTest); }; @@ -118,7 +146,7 @@ info1.short_name = UTF8ToUTF16("US"); info1.third_party = false; info1.selected = true; - GetSystemTrayDelegate()->SetCurrentIME(info1); + SetCurrentIme(info1); Shell::Get()->system_tray_notifier()->NotifyRefreshIME(); EXPECT_EQ(UTF8ToUTF16("US"), GetTrayText()); @@ -130,7 +158,7 @@ info2.short_name = UTF8ToUTF16("UK"); info2.third_party = true; info2.selected = true; - GetSystemTrayDelegate()->SetCurrentIME(info2); + SetCurrentIme(info2); Shell::Get()->system_tray_notifier()->NotifyRefreshIME(); EXPECT_EQ(UTF8ToUTF16("UK*"), GetTrayText()); } @@ -206,19 +234,19 @@ std::vector<IMEInfo> ime_info_list{info1, info2, info3}; - GetSystemTrayDelegate()->SetAvailableIMEList(ime_info_list); - GetSystemTrayDelegate()->SetCurrentIME(info1); + SetAvailableImes(ime_info_list); + SetCurrentIme(info1); Shell::Get()->system_tray_notifier()->NotifyRefreshIME(); EXPECT_EQ(UTF8ToUTF16("US"), GetTrayText()); - EXPECT_TRUE(IsTrayImeListValid(ime_info_list, info1)); + ExpectValidImeList(ime_info_list, info1); ime_info_list[0].selected = false; ime_info_list[2].selected = true; - GetSystemTrayDelegate()->SetAvailableIMEList(ime_info_list); - GetSystemTrayDelegate()->SetCurrentIME(info3); + SetAvailableImes(ime_info_list); + SetCurrentIme(info3); Shell::Get()->system_tray_notifier()->NotifyRefreshIME(); EXPECT_EQ(UTF8ToUTF16("拼"), GetTrayText()); - EXPECT_TRUE(IsTrayImeListValid(ime_info_list, info3)); + ExpectValidImeList(ime_info_list, info3); // Closes the menu before quitting. GetTray()->PerformAction(tap);
diff --git a/ash/system/screen_layout_observer_unittest.cc b/ash/system/screen_layout_observer_unittest.cc index 08e71ff..502fb39b 100644 --- a/ash/system/screen_layout_observer_unittest.cc +++ b/ash/system/screen_layout_observer_unittest.cc
@@ -9,7 +9,6 @@ #include "ash/system/devicetype_utils.h" #include "ash/system/tray/system_tray.h" #include "ash/test/ash_test_base.h" -#include "ash/test/test_system_tray_delegate.h" #include "ash/wm/maximize_mode/maximize_mode_controller.h" #include "base/strings/string16.h" #include "base/strings/string_util.h"
diff --git a/ash/system/supervised/tray_supervised_user_unittest.cc b/ash/system/supervised/tray_supervised_user_unittest.cc index 683df04..8faf755 100644 --- a/ash/system/supervised/tray_supervised_user_unittest.cc +++ b/ash/system/supervised/tray_supervised_user_unittest.cc
@@ -12,7 +12,6 @@ #include "ash/system/tray/system_tray_test_api.h" #include "ash/test/ash_test_base.h" #include "ash/test/test_session_controller_client.h" -#include "ash/test/test_system_tray_delegate.h" #include "base/memory/ptr_util.h" #include "base/strings/utf_string_conversions.h" #include "ui/message_center/message_center.h"
diff --git a/ash/system/tray/system_tray_delegate.cc b/ash/system/tray/system_tray_delegate.cc index 82c4ced6..c2d3b6e 100644 --- a/ash/system/tray/system_tray_delegate.cc +++ b/ash/system/tray/system_tray_delegate.cc
@@ -4,8 +4,6 @@ #include "ash/system/tray/system_tray_delegate.h" -#include "ash/system/tray/ime_info.h" - namespace ash { SystemTrayDelegate::SystemTrayDelegate() = default; @@ -16,16 +14,6 @@ void SystemTrayDelegate::ShowUserLogin() {} -void SystemTrayDelegate::GetCurrentIME(IMEInfo* info) {} - -void SystemTrayDelegate::GetAvailableIMEList(IMEInfoList* list) {} - -void SystemTrayDelegate::GetCurrentIMEProperties(IMEPropertyInfoList* list) {} - -base::string16 SystemTrayDelegate::GetIMEManagedMessage() { - return base::string16(); -} - NetworkingConfigDelegate* SystemTrayDelegate::GetNetworkingConfigDelegate() const { return nullptr;
diff --git a/ash/system/tray/system_tray_delegate.h b/ash/system/tray/system_tray_delegate.h index 81ba1b1..a363254 100644 --- a/ash/system/tray/system_tray_delegate.h +++ b/ash/system/tray/system_tray_delegate.h
@@ -5,18 +5,9 @@ #ifndef ASH_SYSTEM_TRAY_SYSTEM_TRAY_DELEGATE_H_ #define ASH_SYSTEM_TRAY_SYSTEM_TRAY_DELEGATE_H_ -#include <string> -#include <vector> - #include "ash/ash_export.h" -#include "base/strings/string16.h" namespace ash { -struct IMEInfo; -struct IMEPropertyInfo; - -using IMEInfoList = std::vector<IMEInfo>; -using IMEPropertyInfoList = std::vector<IMEPropertyInfo>; class NetworkingConfigDelegate; @@ -38,18 +29,6 @@ // Shows login UI to add other users to this session. virtual void ShowUserLogin(); - // Returns the currently selected IME. - virtual void GetCurrentIME(IMEInfo* info); - - // Returns a list of availble IMEs. - virtual void GetAvailableIMEList(IMEInfoList* list); - - // Returns a list of properties for the currently selected IME. - virtual void GetCurrentIMEProperties(IMEPropertyInfoList* list); - - // Returns a non-empty string if IMEs are managed by policy. - virtual base::string16 GetIMEManagedMessage(); - // Returns NetworkingConfigDelegate. May return nullptr. virtual NetworkingConfigDelegate* GetNetworkingConfigDelegate() const;
diff --git a/ash/system/web_notification/web_notification_tray_unittest.cc b/ash/system/web_notification/web_notification_tray_unittest.cc index 5f487d8c..5a5d7ca 100644 --- a/ash/system/web_notification/web_notification_tray_unittest.cc +++ b/ash/system/web_notification/web_notification_tray_unittest.cc
@@ -19,7 +19,6 @@ #include "ash/system/web_notification/ash_popup_alignment_delegate.h" #include "ash/test/ash_test_base.h" #include "ash/test/status_area_widget_test_helper.h" -#include "ash/test/test_system_tray_delegate.h" #include "ash/wm/window_state.h" #include "base/memory/ptr_util.h" #include "base/strings/stringprintf.h"
diff --git a/ash/test/BUILD.gn b/ash/test/BUILD.gn index 41785fea3..d7e3f43 100644 --- a/ash/test/BUILD.gn +++ b/ash/test/BUILD.gn
@@ -113,8 +113,6 @@ "test_session_state_animator.h", "test_shell_delegate.cc", "test_shell_delegate.h", - "test_system_tray_delegate.cc", - "test_system_tray_delegate.h", "test_system_tray_item.cc", "test_system_tray_item.h", "test_wallpaper_delegate.cc",
diff --git a/ash/test/ash_test_base.cc b/ash/test/ash_test_base.cc index ef6c1f1..5c556b9 100644 --- a/ash/test/ash_test_base.cc +++ b/ash/test/ash_test_base.cc
@@ -25,7 +25,6 @@ #include "ash/test/ash_test_helper.h" #include "ash/test/test_session_controller_client.h" #include "ash/test/test_shell_delegate.h" -#include "ash/test/test_system_tray_delegate.h" #include "ash/wm/window_positioner.h" #include "services/ui/public/cpp/property_type_converters.h" #include "services/ui/public/interfaces/window_manager.mojom.h" @@ -413,11 +412,6 @@ return ash_test_helper_->test_session_controller_client(); } -TestSystemTrayDelegate* AshTestBase::GetSystemTrayDelegate() { - return static_cast<TestSystemTrayDelegate*>( - Shell::Get()->system_tray_delegate()); -} - void AshTestBase::SetSessionStarted(bool session_started) { if (session_started) GetSessionControllerClient()->CreatePredefinedUserSessions(1);
diff --git a/ash/test/ash_test_base.h b/ash/test/ash_test_base.h index e078e46..c6f0f42 100644 --- a/ash/test/ash_test_base.h +++ b/ash/test/ash_test_base.h
@@ -58,7 +58,6 @@ class AshTestHelper; class TestScreenshotDelegate; class TestSessionControllerClient; -class TestSystemTrayDelegate; class AshTestBase : public testing::Test { public: @@ -179,8 +178,6 @@ TestSessionControllerClient* GetSessionControllerClient(); - TestSystemTrayDelegate* GetSystemTrayDelegate(); - // Utility methods to emulate user logged in or not, session started or not // and user able to lock screen or not cases. void SetSessionStarted(bool session_started);
diff --git a/ash/test/ash_test_helper.cc b/ash/test/ash_test_helper.cc index f506bfcc..b5b6f5d 100644 --- a/ash/test/ash_test_helper.cc +++ b/ash/test/ash_test_helper.cc
@@ -24,7 +24,6 @@ #include "ash/test/display_configuration_controller_test_api.h" #include "ash/test/test_screenshot_delegate.h" #include "ash/test/test_shell_delegate.h" -#include "ash/test/test_system_tray_delegate.h" #include "base/memory/ptr_util.h" #include "base/run_loop.h" #include "base/strings/string_split.h"
diff --git a/ash/test/test_shell_delegate.cc b/ash/test/test_shell_delegate.cc index 846c6e5..e010d9f 100644 --- a/ash/test/test_shell_delegate.cc +++ b/ash/test/test_shell_delegate.cc
@@ -13,10 +13,10 @@ #include "ash/shelf/shelf.h" #include "ash/shell.h" #include "ash/shell_observer.h" +#include "ash/system/tray/system_tray_delegate.h" #include "ash/system/tray/system_tray_notifier.h" #include "ash/test/test_accessibility_delegate.h" #include "ash/test/test_keyboard_ui.h" -#include "ash/test/test_system_tray_delegate.h" #include "ash/test/test_wallpaper_delegate.h" #include "ash/wm/window_state.h" #include "ash/wm/window_util.h" @@ -102,7 +102,11 @@ void TestShellDelegate::ShelfShutdown() {} SystemTrayDelegate* TestShellDelegate::CreateSystemTrayDelegate() { - return new TestSystemTrayDelegate; + return new SystemTrayDelegate; +} + +ImeController* TestShellDelegate::GetImeController() { + return &stub_ime_controller_; } std::unique_ptr<WallpaperDelegate>
diff --git a/ash/test/test_shell_delegate.h b/ash/test/test_shell_delegate.h index a5a0467..84e1131 100644 --- a/ash/test/test_shell_delegate.h +++ b/ash/test/test_shell_delegate.h
@@ -8,6 +8,7 @@ #include <memory> #include <string> +#include "ash/ime/ime_controller.h" #include "ash/shell_delegate.h" #include "base/macros.h" @@ -50,6 +51,7 @@ void ShelfShutdown() override; void OpenUrlFromArc(const GURL& url) override; SystemTrayDelegate* CreateSystemTrayDelegate() override; + ImeController* GetImeController() override; std::unique_ptr<WallpaperDelegate> CreateWallpaperDelegate() override; AccessibilityDelegate* CreateAccessibilityDelegate() override; std::unique_ptr<PaletteDelegate> CreatePaletteDelegate() override; @@ -80,6 +82,7 @@ bool touchscreen_enabled_in_local_pref_ = true; bool media_sessions_suspended_ = false; std::unique_ptr<ShelfInitializer> shelf_initializer_; + ImeController stub_ime_controller_; PrefService* active_user_pref_service_ = nullptr; // Not owned. DISALLOW_COPY_AND_ASSIGN(TestShellDelegate);
diff --git a/ash/test/test_system_tray_delegate.cc b/ash/test/test_system_tray_delegate.cc deleted file mode 100644 index f14d374e9f..0000000 --- a/ash/test/test_system_tray_delegate.cc +++ /dev/null
@@ -1,31 +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/test/test_system_tray_delegate.h" - -namespace ash { -namespace test { - -TestSystemTrayDelegate::TestSystemTrayDelegate() = default; - -TestSystemTrayDelegate::~TestSystemTrayDelegate() = default; - -void TestSystemTrayDelegate::SetCurrentIME(const IMEInfo& info) { - current_ime_ = info; -} - -void TestSystemTrayDelegate::SetAvailableIMEList(const IMEInfoList& list) { - ime_list_ = list; -} - -void TestSystemTrayDelegate::GetCurrentIME(IMEInfo* info) { - *info = current_ime_; -} - -void TestSystemTrayDelegate::GetAvailableIMEList(IMEInfoList* list) { - *list = ime_list_; -} - -} // namespace test -} // namespace ash
diff --git a/ash/test/test_system_tray_delegate.h b/ash/test/test_system_tray_delegate.h deleted file mode 100644 index 38548c0..0000000 --- a/ash/test/test_system_tray_delegate.h +++ /dev/null
@@ -1,40 +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. - -#ifndef ASH_TEST_TEST_SYSTEM_TRAY_DELEGATE_H_ -#define ASH_TEST_TEST_SYSTEM_TRAY_DELEGATE_H_ - -#include "ash/system/tray/ime_info.h" -#include "ash/system/tray/system_tray_delegate.h" -#include "base/macros.h" - -namespace ash { -namespace test { - -class TestSystemTrayDelegate : public SystemTrayDelegate { - public: - TestSystemTrayDelegate(); - ~TestSystemTrayDelegate() override; - - // Sets the IME info. - void SetCurrentIME(const IMEInfo& info); - - // Sets the list of available IMEs. - void SetAvailableIMEList(const IMEInfoList& list); - - // SystemTrayDelegate: - void GetCurrentIME(IMEInfo* info) override; - void GetAvailableIMEList(IMEInfoList* list) override; - - private: - IMEInfo current_ime_; - IMEInfoList ime_list_; - - DISALLOW_COPY_AND_ASSIGN(TestSystemTrayDelegate); -}; - -} // namespace test -} // namespace ash - -#endif // ASH_TEST_TEST_SYSTEM_TRAY_DELEGATE_H_
diff --git a/ash/wm/maximize_mode/maximize_mode_controller_unittest.cc b/ash/wm/maximize_mode/maximize_mode_controller_unittest.cc index cf6bb66..4b813e4f 100644 --- a/ash/wm/maximize_mode/maximize_mode_controller_unittest.cc +++ b/ash/wm/maximize_mode/maximize_mode_controller_unittest.cc
@@ -13,7 +13,6 @@ #include "ash/shell.h" #include "ash/system/tray/system_tray_delegate.h" #include "ash/test/ash_test_base.h" -#include "ash/test/test_system_tray_delegate.h" #include "ash/wm/overview/window_selector_controller.h" #include "base/command_line.h" #include "base/run_loop.h"
diff --git a/base/android/jni_generator/jni_generator.py b/base/android/jni_generator/jni_generator.py index 99d8b424..d4c3523 100755 --- a/base/android/jni_generator/jni_generator.py +++ b/base/android/jni_generator/jni_generator.py
@@ -420,7 +420,7 @@ needed by non-browser processes must explicitly be annotated with @MainDex to force JNI registration. """ - re_maindex = re.compile(r'@MainDex[\s\S]*class\s+\w+\s*{') + re_maindex = re.compile(r'@MainDex[\s\S]*class({|[\s\S]*{)') found = re.search(re_maindex, contents) return 'true' if found else 'false'
diff --git a/base/android/jni_generator/jni_generator_tests.py b/base/android/jni_generator/jni_generator_tests.py index c0c82388..feac90a 100755 --- a/base/android/jni_generator/jni_generator_tests.py +++ b/base/android/jni_generator/jni_generator_tests.py
@@ -18,7 +18,11 @@ import sys import unittest import jni_generator -from jni_generator import CalledByNative, JniParams, NativeMethod, Param +from jni_generator import CalledByNative +from jni_generator import IsMainDexJavaClass +from jni_generator import JniParams +from jni_generator import NativeMethod +from jni_generator import Param SCRIPT_NAME = 'base/android/jni_generator/jni_generator.py' @@ -977,6 +981,45 @@ test_data, 'org/chromium/foo/Bar', options) self.assertGoldenTextEquals(jni_from_java.GetContent()) + def testMainDexAnnotation(self): + mainDexEntries = [ + '@MainDex public class Test {', + '@MainDex public class Test{', + """@MainDex + public class Test { + """, + """@MainDex public class Test + { + """, + '@MainDex /* This class is a test */ public class Test {', + '@MainDex public class Test implements java.io.Serializable {', + '@MainDex public class Test implements java.io.Serializable, Bidule {', + '@MainDex public class Test extends BaseTest {', + """@MainDex + public class Test extends BaseTest implements Bidule { + """, + """@MainDex + public class Test extends BaseTest implements Bidule, Machin, Chose { + """, + """@MainDex + public class Test implements Testable<java.io.Serializable> { + """, + '@MainDex public class Test implements Testable<java.io.Serializable> {', + '@MainDex public class Test extends Testable<java.io.Serializable> {', + ] + for entry in mainDexEntries: + self.assertEquals("true", IsMainDexJavaClass(entry)) + + def testNoMainDexAnnotation(self): + noMainDexEntries = [ + 'public class Test {', + '@NotMainDex public class Test {', + 'public class Test implements java.io.Serializable {', + 'public class Test extends BaseTest {' + ] + for entry in noMainDexEntries: + self.assertEquals("false", IsMainDexJavaClass(entry)) + def testNativeExportsOnlyOption(self): test_data = """ package org.chromium.example.jni_generator;
diff --git a/chrome/BUILD.gn b/chrome/BUILD.gn index 6cba336..cb1b62ee 100644 --- a/chrome/BUILD.gn +++ b/chrome/BUILD.gn
@@ -1526,15 +1526,17 @@ if (!is_android) { public_deps += [ "//chrome/browser/resources:component_extension_resources", - "//chrome/browser/resources:options_resources", "//chrome/browser/resources:settings_resources", ] } if (is_chromeos) { - public_deps += [ "//chrome/browser/resources/chromeos/chromevox" ] - public_deps += [ "//chrome/browser/resources/chromeos/select_to_speak" ] - public_deps += [ "//chrome/browser/resources/chromeos/switch_access" ] + public_deps += [ + "//chrome/browser/resources:options_resources", + "//chrome/browser/resources/chromeos/chromevox", + "//chrome/browser/resources/chromeos/select_to_speak", + "//chrome/browser/resources/chromeos/switch_access", + ] } if (enable_extensions) {
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn index 22dc801e6..429b2d5 100644 --- a/chrome/android/BUILD.gn +++ b/chrome/android/BUILD.gn
@@ -556,8 +556,11 @@ "javatests/src/org/chromium/chrome/browser/vr_shell/mock/MockVrCoreVersionCheckerImpl.java", "javatests/src/org/chromium/chrome/browser/vr_shell/mock/MockVrDaydreamApi.java", "javatests/src/org/chromium/chrome/browser/vr_shell/nfc_apk/SimNfcActivity.java", + "javatests/src/org/chromium/chrome/browser/vr_shell/util/CardboardUtils.java", "javatests/src/org/chromium/chrome/browser/vr_shell/util/NfcSimUtils.java", - "javatests/src/org/chromium/chrome/browser/vr_shell/util/VrUtils.java", + "javatests/src/org/chromium/chrome/browser/vr_shell/util/VrInfoBarUtils.java", + "javatests/src/org/chromium/chrome/browser/vr_shell/util/VrShellDelegateUtils.java", + "javatests/src/org/chromium/chrome/browser/vr_shell/util/VrTransitionUtils.java", "javatests/src/org/chromium/chrome/browser/vr_shell/VrFeedbackInfoBarTest.java", "javatests/src/org/chromium/chrome/browser/vr_shell/VrShellTest.java", "javatests/src/org/chromium/chrome/browser/vr_shell/VrShellNavigationTest.java",
diff --git a/chrome/android/java/res/layout/bottom_toolbar_phone.xml b/chrome/android/java/res/layout/bottom_toolbar_phone.xml index 9dc4891..fded2a5 100644 --- a/chrome/android/java/res/layout/bottom_toolbar_phone.xml +++ b/chrome/android/java/res/layout/bottom_toolbar_phone.xml
@@ -10,7 +10,9 @@ xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/toolbar" android:layout_width="match_parent" - android:layout_height="match_parent" > + android:layout_height="match_parent" + android:focusable="true" + android:focusableInTouchMode="true" > <include layout="@layout/toolbar_phone_common"/>
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManager.java b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManager.java index 1b5e0a5..53e907b3 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManager.java
@@ -431,9 +431,9 @@ if (isTap && mPolicy.shouldPreviousTapResolve()) { // Cache the native translate data, so JNI calls won't be made when time-critical. mTranslateController.cacheNativeTranslateData(); - } else { + } else if (!TextUtils.isEmpty(selection)) { boolean shouldPrefetch = mPolicy.shouldPrefetchSearchResult(); - mSearchRequest = createContextualSearchRequest(selection, null, null, shouldPrefetch); + mSearchRequest = new ContextualSearchRequest(selection, null, null, shouldPrefetch); mTranslateController.forceAutoDetectTranslateUnlessDisabled(mSearchRequest); mDidStartLoadingResolvedSearchRequest = false; mSearchPanel.setSearchTerm(selection); @@ -447,6 +447,10 @@ RecordUserAction.record(isSingleWord ? "ContextualSearch.ManualRefineSingleWord" : "ContextualSearch.ManualRefineMultiWord"); } + } else { + // The selection is no longer valid, so we can't build a request. Don't show the UX. + hideContextualSearch(StateChangeReason.UNKNOWN); + return; } mWereSearchResultsSeen = false; @@ -503,18 +507,6 @@ } } - /** - * A method that can override the creation of a standard search request. This should only be - * used for testing. - * @param term The search term to create the request with. - * @param altTerm An alternate search term. - * @param isLowPriorityEnabled Whether the request can be made at low priority. - */ - protected ContextualSearchRequest createContextualSearchRequest( - String term, String altTerm, String mid, boolean isLowPriorityEnabled) { - return new ContextualSearchRequest(term, altTerm, mid, isLowPriorityEnabled); - } - /** Accessor for the {@code InfoBarContainer} currently attached to the {@code Tab}. */ private InfoBarContainer getInfoBarContainer() { Tab tab = mActivity.getActivityTab(); @@ -710,7 +702,7 @@ // appear in the user's history until the user views it). See crbug.com/406446. boolean shouldPreload = !doPreventPreload && mPolicy.shouldPrefetchSearchResult(); mSearchRequest = - createContextualSearchRequest(searchTerm, alternateTerm, mid, shouldPreload); + new ContextualSearchRequest(searchTerm, alternateTerm, mid, shouldPreload); // Trigger translation, if enabled. mTranslateController.forceTranslateIfNeeded(mSearchRequest, contextLanguage); mDidStartLoadingResolvedSearchRequest = false; @@ -948,8 +940,9 @@ mWereSearchResultsSeen = true; // If there's no current request, then either a search term resolution // is in progress or we should do a verbatim search now. - if (mSearchRequest == null && mPolicy.shouldCreateVerbatimRequest()) { - mSearchRequest = createContextualSearchRequest( + if (mSearchRequest == null && mPolicy.shouldCreateVerbatimRequest() + && !TextUtils.isEmpty(mSelectionController.getSelectedText())) { + mSearchRequest = new ContextualSearchRequest( mSelectionController.getSelectedText(), null, null, false); mDidStartLoadingResolvedSearchRequest = false; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/infobar/InfoBarContainerLayout.java b/chrome/android/java/src/org/chromium/chrome/browser/infobar/InfoBarContainerLayout.java index babe13a61c..fd259f0 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/infobar/InfoBarContainerLayout.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/infobar/InfoBarContainerLayout.java
@@ -218,8 +218,8 @@ Animator.AnimatorListener listener = new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { - mAnimation = null; InfoBarAnimation.this.onAnimationEnd(); + mAnimation = null; for (InfoBarAnimationListener listener : mAnimationListeners) { listener.notifyAnimationFinished(getAnimationType()); } @@ -448,13 +448,6 @@ public void onAnimationStart(Animator animation) { setHierarchyClipsChildren(false); } - - @Override - public void onAnimationEnd(Animator animation) { - mAppearingWrapper.setRestrictHeightForAnimation(false); - mAppearingWrapper.removeView(mAppearingWrapper.getItem().getView()); - setHierarchyClipsChildren(true); - } }); set.playSequentially(animators); @@ -464,6 +457,13 @@ } @Override + public void onAnimationEnd() { + mAppearingWrapper.setRestrictHeightForAnimation(false); + mAppearingWrapper.removeView(mAppearingWrapper.getItem().getView()); + setHierarchyClipsChildren(true); + } + + @Override int getAnimationType() { return InfoBarAnimationListener.ANIMATION_TYPE_SHOW; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/BottomToolbarPhone.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/BottomToolbarPhone.java index 8570bc39..b81afc13 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/BottomToolbarPhone.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/BottomToolbarPhone.java
@@ -34,6 +34,7 @@ import org.chromium.chrome.browser.widget.bottomsheet.BottomSheetMetrics; import org.chromium.chrome.browser.widget.bottomsheet.BottomSheetObserver; import org.chromium.chrome.browser.widget.bottomsheet.EmptyBottomSheetObserver; +import org.chromium.ui.UiUtils; import org.chromium.ui.base.LocalizationUtils; import org.chromium.ui.interpolators.BakedBezierInterpolator; @@ -306,7 +307,8 @@ if (mProgressBar == null) return; ViewGroup coordinator = (ViewGroup) getRootView().findViewById(R.id.coordinator); - coordinator.addView(mProgressBar); + UiUtils.insertBefore(coordinator, mProgressBar, mBottomSheet); + mProgressBar.setProgressBarContainer(coordinator); } @@ -439,8 +441,6 @@ if (!mUseToolbarHandle) { initExpandButton(); } else { - setFocusable(true); - setFocusableInTouchMode(true); setContentDescription( getResources().getString(R.string.bottom_sheet_accessibility_toolbar)); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/selection/SelectableListLayout.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/selection/SelectableListLayout.java index 14c4621..ab76880 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/widget/selection/SelectableListLayout.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/selection/SelectableListLayout.java
@@ -279,6 +279,7 @@ mAdapter.unregisterAdapterDataObserver(mAdapterObserver); mToolbar.getSelectionDelegate().removeObserver(this); mToolbar.destroy(); + mRecyclerView.setAdapter(null); } /**
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchTapEventTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchTapEventTest.java index 6f910e6..0b23f5bd 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchTapEventTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchTapEventTest.java
@@ -5,7 +5,6 @@ package org.chromium.chrome.browser.contextualsearch; import android.content.Context; -import android.net.Uri; import android.support.test.filters.SmallTest; import android.widget.LinearLayout; @@ -35,8 +34,6 @@ import org.chromium.ui.resources.dynamics.DynamicResourceLoader; import org.chromium.ui.touch_selection.SelectionEventType; -import javax.annotation.Nullable; - /** * Mock touch events with Contextual Search to test behavior of its panel and manager. */ @@ -55,21 +52,6 @@ private OverlayPanelManagerWrapper mPanelManager; private SelectionClient mContextualSearchClient; - /** - * A ContextualSearchRequest that foregoes URI template lookup. - */ - private static class MockContextualSearchRequest extends ContextualSearchRequest { - public MockContextualSearchRequest(String term, String altTerm, boolean prefetch) { - super(term, altTerm, "", prefetch); - } - - @Override - protected Uri getUriTemplate( - String query, @Nullable String alternateTerm, String mid, boolean shouldPrefetch) { - return Uri.parse(""); - } - } - // -------------------------------------------------------------------------------------------- /** @@ -119,12 +101,6 @@ } @Override - protected ContextualSearchRequest createContextualSearchRequest( - String query, String altTerm, String mid, boolean shouldPrefetch) { - return new MockContextualSearchRequest(query, altTerm, shouldPrefetch); - } - - @Override protected void nativeGatherSurroundingText(long nativeContextualSearchManager, ContextualSearchContext contextualSearchContext, WebContents baseWebContents) {} @@ -349,4 +325,31 @@ Assert.assertEquals(mPanelManager.getRequestPanelShowCount(), 1); Assert.assertEquals(mPanelManager.getPanelHideCount(), 0); } + + /** + * Tests that a Tap gesture processing is robust even when the selection somehow gets cleared + * during that process. This tests a failure-case found in crbug.com/728644. + */ + @Test + @SmallTest + @Feature({"ContextualSearch"}) + @Restriction(Restriction.RESTRICTION_TYPE_NON_LOW_END_DEVICE) + public void testTapProcessIsRobustWhenSelectionGetsCleared() throws InterruptedException { + Assert.assertEquals(mPanelManager.getRequestPanelShowCount(), 0); + + // Fake a Tap event. + mockTapText("text"); + // Generate the surrounding-text-available callback. + generateTextSurroundingSelectionAvailable(); + + // Now clear the selection! + mContextualSearchManager.getSelectionController().clearSelection(); + + // Continue processing the Tap by acknowledging the SelectWordAroundCaret has selected the + // word. However we just simulated a condition that clears the selection above, so we're + // testing for robustness in completion of the processing even when there's no selection. + generateSelectWordAroundCaretAck(); + Assert.assertEquals(mPanelManager.getRequestPanelShowCount(), 0); + Assert.assertEquals(mPanelManager.getPanelHideCount(), 0); + } }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/VrFeedbackInfoBarTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/VrFeedbackInfoBarTest.java index e09ab77..33862a4 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/VrFeedbackInfoBarTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/VrFeedbackInfoBarTest.java
@@ -5,8 +5,8 @@ package org.chromium.chrome.browser.vr_shell; import static org.chromium.chrome.browser.vr_shell.VrTestRule.PAGE_LOAD_TIMEOUT_S; -import static org.chromium.chrome.browser.vr_shell.util.VrUtils.POLL_TIMEOUT_LONG_MS; -import static org.chromium.chrome.browser.vr_shell.util.VrUtils.POLL_TIMEOUT_SHORT_MS; +import static org.chromium.chrome.browser.vr_shell.VrTestRule.POLL_TIMEOUT_LONG_MS; +import static org.chromium.chrome.browser.vr_shell.VrTestRule.POLL_TIMEOUT_SHORT_MS; import static org.chromium.chrome.test.util.ChromeRestriction.RESTRICTION_TYPE_VIEWER_DAYDREAM; import android.support.test.filters.MediumTest; @@ -17,18 +17,16 @@ import org.junit.Test; import org.junit.runner.RunWith; -import org.chromium.base.ThreadUtils; import org.chromium.base.test.util.CommandLineFlags; import org.chromium.base.test.util.Restriction; import org.chromium.chrome.browser.ChromeSwitches; -import org.chromium.chrome.browser.infobar.InfoBar; -import org.chromium.chrome.browser.vr_shell.util.VrUtils; +import org.chromium.chrome.browser.vr_shell.util.VrInfoBarUtils; +import org.chromium.chrome.browser.vr_shell.util.VrShellDelegateUtils; +import org.chromium.chrome.browser.vr_shell.util.VrTransitionUtils; import org.chromium.chrome.test.ChromeActivityTestRule; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; import org.chromium.chrome.test.util.ChromeTabUtils; -import org.chromium.chrome.test.util.InfoBarUtil; -import java.util.List; import java.util.concurrent.TimeoutException; /** @@ -54,43 +52,16 @@ Assert.assertFalse(VrFeedbackStatus.getFeedbackOptOut()); } - private void clickInfoBarButton(final boolean primary) { - final List<InfoBar> infoBars = mVrTestRule.getInfoBars(); - ThreadUtils.runOnUiThreadBlocking(new Runnable() { - @Override - public void run() { - if (primary) { - InfoBarUtil.clickPrimaryButton(infoBars.get(0)); - } else { - InfoBarUtil.clickSecondaryButton(infoBars.get(0)); - } - } - }); - InfoBarUtil.waitUntilNoInfoBarsExist(mVrTestRule.getInfoBars()); - } - - private void clickInfobarCloseButton() { - final List<InfoBar> infoBars = mVrTestRule.getInfoBars(); - ThreadUtils.runOnUiThreadBlocking(new Runnable() { - @Override - public void run() { - InfoBarUtil.clickCloseButton(infoBars.get(0)); - } - }); - InfoBarUtil.waitUntilNoInfoBarsExist(mVrTestRule.getInfoBars()); - } - private void assertState(boolean isInVr, boolean isInfobarVisible) { Assert.assertEquals("Browser is in VR", isInVr, VrShellDelegate.isInVr()); - VrUtils.expectInfoBarPresent( - mVrTestRule.getActivity().getWindow().getDecorView(), isInfobarVisible); + VrInfoBarUtils.expectInfoBarPresent(mVrTestRule, isInfobarVisible); } private void enterThenExitVr() { - VrUtils.forceEnterVr(); - VrUtils.waitForVrSupported(POLL_TIMEOUT_LONG_MS); + VrTransitionUtils.forceEnterVr(); + VrTransitionUtils.waitForVrEntry(POLL_TIMEOUT_LONG_MS); assertState(true /* isInVr */, false /* isInfobarVisible */); - VrUtils.forceExitVr(VrUtils.getVrShellDelegateInstance()); + VrTransitionUtils.forceExitVr(); } /** @@ -101,12 +72,12 @@ public void testFeedbackFrequency() throws InterruptedException, TimeoutException { mVrTestRule.loadUrlAndAwaitInitialization(TEST_PAGE_2D_URL, PAGE_LOAD_TIMEOUT_S); // Set frequency of infobar to every 2nd time. - VrUtils.getVrShellDelegateInstance().setFeedbackFrequencyForTesting(2); + VrShellDelegateUtils.getDelegateInstance().setFeedbackFrequencyForTesting(2); // Verify that the Feedback infobar is visible when exiting VR. enterThenExitVr(); assertState(false /* isInVr */, true /* isInfobarVisible */); - clickInfobarCloseButton(); + VrInfoBarUtils.clickInfobarCloseButton(mVrTestRule); // Feedback infobar shouldn't show up this time. enterThenExitVr(); @@ -115,7 +86,7 @@ // Feedback infobar should show up again. enterThenExitVr(); assertState(false /* isInVr */, true /* isInfobarVisible */); - clickInfobarCloseButton(); + VrInfoBarUtils.clickInfobarCloseButton(mVrTestRule); } /** @@ -127,14 +98,14 @@ mVrTestRule.loadUrlAndAwaitInitialization(TEST_PAGE_2D_URL, PAGE_LOAD_TIMEOUT_S); // Show infobar every time. - VrUtils.getVrShellDelegateInstance().setFeedbackFrequencyForTesting(1); + VrShellDelegateUtils.getDelegateInstance().setFeedbackFrequencyForTesting(1); // The infobar should show the first time. enterThenExitVr(); assertState(false /* isInVr */, true /* isInfobarVisible */); // Opt-out of seeing the infobar. - clickInfoBarButton(false /* primary */); + VrInfoBarUtils.clickInfoBarButton(VrInfoBarUtils.Button.SECONDARY, mVrTestRule); Assert.assertTrue(VrFeedbackStatus.getFeedbackOptOut()); // The infobar should not show because the user opted out. @@ -152,13 +123,13 @@ mVrTestRule.loadUrlAndAwaitInitialization(TEST_PAGE_WEBVR_URL, PAGE_LOAD_TIMEOUT_S); Assert.assertTrue("VRDisplay found", mVrTestRule.vrDisplayFound(mVrTestRule.getFirstTabWebContents())); - mVrTestRule.enterPresentationAndWait( + VrTransitionUtils.enterPresentationAndWait( mVrTestRule.getFirstTabCvc(), mVrTestRule.getFirstTabWebContents()); assertState(true /* isInVr */, false /* isInfobarVisible */); Assert.assertTrue(VrShellDelegate.getVrShellForTesting().getWebVrModeEnabled()); // Exiting VR should not prompt for feedback since the no VR browsing was performed. - VrUtils.forceExitVr(VrUtils.getVrShellDelegateInstance()); + VrTransitionUtils.forceExitVr(); assertState(false /* isInVr */, false /* isInfobarVisible */); } @@ -172,7 +143,7 @@ mVrTestRule.loadUrlAndAwaitInitialization(TEST_PAGE_WEBVR_URL, PAGE_LOAD_TIMEOUT_S); Assert.assertTrue("VRDisplay found", mVrTestRule.vrDisplayFound(mVrTestRule.getFirstTabWebContents())); - mVrTestRule.enterPresentationAndWait( + VrTransitionUtils.enterPresentationAndWait( mVrTestRule.getFirstTabCvc(), mVrTestRule.getFirstTabWebContents()); assertState(true /* isInVr */, false /* isInfobarVisible */); Assert.assertTrue(VrShellDelegate.getVrShellForTesting().getWebVrModeEnabled()); @@ -189,7 +160,7 @@ }, POLL_TIMEOUT_LONG_MS); // Exiting VR should prompt for feedback since 2D browsing was performed after. - VrUtils.forceExitVr(VrUtils.getVrShellDelegateInstance()); + VrTransitionUtils.forceExitVr(); assertState(false /* isInVr */, true /* isInfobarVisible */); } }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/VrShellNavigationTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/VrShellNavigationTest.java index 2d2b76c..60b686f 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/VrShellNavigationTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/VrShellNavigationTest.java
@@ -5,8 +5,8 @@ package org.chromium.chrome.browser.vr_shell; import static org.chromium.chrome.browser.vr_shell.VrTestRule.PAGE_LOAD_TIMEOUT_S; -import static org.chromium.chrome.browser.vr_shell.util.VrUtils.POLL_TIMEOUT_LONG_MS; -import static org.chromium.chrome.browser.vr_shell.util.VrUtils.POLL_TIMEOUT_SHORT_MS; +import static org.chromium.chrome.browser.vr_shell.VrTestRule.POLL_TIMEOUT_LONG_MS; +import static org.chromium.chrome.browser.vr_shell.VrTestRule.POLL_TIMEOUT_SHORT_MS; import static org.chromium.chrome.test.util.ChromeRestriction.RESTRICTION_TYPE_VIEWER_DAYDREAM; import android.support.test.filters.MediumTest; @@ -20,7 +20,8 @@ import org.chromium.base.test.util.CommandLineFlags; import org.chromium.base.test.util.Restriction; import org.chromium.chrome.browser.ChromeSwitches; -import org.chromium.chrome.browser.vr_shell.util.VrUtils; +import org.chromium.chrome.browser.vr_shell.util.VrInfoBarUtils; +import org.chromium.chrome.browser.vr_shell.util.VrTransitionUtils; import org.chromium.chrome.test.ChromeActivityTestCaseBase; import org.chromium.chrome.test.ChromeActivityTestRule; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; @@ -55,8 +56,8 @@ @Before public void setUp() throws Exception { - VrUtils.forceEnterVr(); - VrUtils.waitForVrSupported(POLL_TIMEOUT_LONG_MS); + VrTransitionUtils.forceEnterVr(); + VrTransitionUtils.waitForVrEntry(POLL_TIMEOUT_LONG_MS); } private String getUrl(Page page) { @@ -96,7 +97,7 @@ private void enterPresentationOrFail(ContentViewCore cvc) throws InterruptedException, TimeoutException { - mVrTestRule.enterPresentation(cvc); + VrTransitionUtils.enterPresentation(cvc); mVrTestRule.pollJavaScriptBoolean("vrDisplay.isPresenting", POLL_TIMEOUT_SHORT_MS, mVrTestRule.getFirstTabWebContents()); Assert.assertTrue(VrShellDelegate.getVrShellForTesting().getWebVrModeEnabled()); @@ -112,7 +113,7 @@ Assert.assertEquals("Browser is in fullscreen", fullscreenMode == FullscreenMode.FULLSCREENED, DOMUtils.isFullscreen(wc)); // Feedback infobar should never show up during navigations. - VrUtils.expectInfoBarPresent(mVrTestRule.getActivity().getWindow().getDecorView(), false); + VrInfoBarUtils.expectInfoBarPresent(mVrTestRule, false); } /**
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/VrShellTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/VrShellTest.java index 3033484..6e8f6ec 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/VrShellTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/VrShellTest.java
@@ -5,8 +5,8 @@ package org.chromium.chrome.browser.vr_shell; import static org.chromium.chrome.browser.vr_shell.VrTestRule.PAGE_LOAD_TIMEOUT_S; -import static org.chromium.chrome.browser.vr_shell.util.VrUtils.POLL_CHECK_INTERVAL_LONG_MS; -import static org.chromium.chrome.browser.vr_shell.util.VrUtils.POLL_TIMEOUT_LONG_MS; +import static org.chromium.chrome.browser.vr_shell.VrTestRule.POLL_CHECK_INTERVAL_LONG_MS; +import static org.chromium.chrome.browser.vr_shell.VrTestRule.POLL_TIMEOUT_LONG_MS; import static org.chromium.chrome.test.util.ChromeRestriction.RESTRICTION_TYPE_DEVICE_DAYDREAM; import static org.chromium.chrome.test.util.ChromeRestriction.RESTRICTION_TYPE_DEVICE_NON_DAYDREAM; import static org.chromium.chrome.test.util.ChromeRestriction.RESTRICTION_TYPE_VIEWER_DAYDREAM; @@ -31,7 +31,9 @@ import org.chromium.chrome.browser.compositor.CompositorViewHolder; import org.chromium.chrome.browser.tabmodel.TabModelSelector; import org.chromium.chrome.browser.vr_shell.mock.MockVrDaydreamApi; -import org.chromium.chrome.browser.vr_shell.util.VrUtils; +import org.chromium.chrome.browser.vr_shell.util.NfcSimUtils; +import org.chromium.chrome.browser.vr_shell.util.VrShellDelegateUtils; +import org.chromium.chrome.browser.vr_shell.util.VrTransitionUtils; import org.chromium.chrome.test.ChromeActivityTestRule; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; import org.chromium.chrome.test.ChromeTabbedActivityTestRule; @@ -61,7 +63,7 @@ @Before public void setUp() throws Exception { mActivityTestRule.startMainActivityOnBlankPage(); - mDelegate = VrUtils.getVrShellDelegateInstance(); + mDelegate = VrShellDelegateUtils.getDelegateInstance(); } private void enterExitVrMode(boolean supported) { @@ -69,28 +71,28 @@ if (!supported) { mDelegate.overrideDaydreamApiForTesting(mockApi); } - VrUtils.forceEnterVr(); + VrTransitionUtils.forceEnterVr(); if (supported) { - VrUtils.waitForVrSupported(POLL_TIMEOUT_LONG_MS); + VrTransitionUtils.waitForVrEntry(POLL_TIMEOUT_LONG_MS); Assert.assertTrue(VrShellDelegate.isInVr()); } else { Assert.assertFalse(mockApi.getLaunchInVrCalled()); Assert.assertFalse(VrShellDelegate.isInVr()); } - VrUtils.forceExitVr(mDelegate); + VrTransitionUtils.forceExitVr(); Assert.assertFalse(VrShellDelegate.isInVr()); } private void enterVrModeNfc(boolean supported) { InstrumentationRegistry.getInstrumentation().waitForIdleSync(); - VrUtils.simNfcScan(mActivityTestRule.getActivity()); + NfcSimUtils.simNfcScan(mActivityTestRule.getActivity()); if (supported) { - VrUtils.waitForVrSupported(POLL_TIMEOUT_LONG_MS); + VrTransitionUtils.waitForVrEntry(POLL_TIMEOUT_LONG_MS); Assert.assertTrue(VrShellDelegate.isInVr()); } else { Assert.assertFalse(VrShellDelegate.isInVr()); } - VrUtils.forceExitVr(mDelegate); + VrTransitionUtils.forceExitVr(); // TODO(bsheedy): Figure out why NFC tests cause the next test to fail // to enter VR unless we sleep for some amount of time after exiting VR // in the NFC test @@ -150,8 +152,8 @@ public void testControllerScrolling() throws InterruptedException { // Load page in VR and make sure the controller is pointed at the content quad mActivityTestRule.loadUrl("chrome://credits", PAGE_LOAD_TIMEOUT_S); - VrUtils.forceEnterVr(); - VrUtils.waitForVrSupported(POLL_TIMEOUT_LONG_MS); + VrTransitionUtils.forceEnterVr(); + VrTransitionUtils.waitForVrEntry(POLL_TIMEOUT_LONG_MS); EmulatedVrController controller = new EmulatedVrController(mActivityTestRule.getActivity()); final ContentViewCore cvc = mActivityTestRule.getActivity().getActivityTab().getActiveContentViewCore();
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/VrTestRule.java b/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/VrTestRule.java index c9f47d5..2e8948d 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/VrTestRule.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/VrTestRule.java
@@ -4,28 +4,16 @@ package org.chromium.chrome.browser.vr_shell; -import static org.chromium.chrome.browser.vr_shell.util.VrUtils.POLL_CHECK_INTERVAL_LONG_MS; -import static org.chromium.chrome.browser.vr_shell.util.VrUtils.POLL_CHECK_INTERVAL_SHORT_MS; -import static org.chromium.chrome.browser.vr_shell.util.VrUtils.POLL_TIMEOUT_LONG_MS; -import static org.chromium.chrome.browser.vr_shell.util.VrUtils.POLL_TIMEOUT_SHORT_MS; - -import android.app.Activity; -import android.support.test.InstrumentationRegistry; - import org.junit.Assert; import org.junit.runner.Description; import org.junit.runners.model.Statement; import org.chromium.base.Log; import org.chromium.base.test.util.UrlUtils; -import org.chromium.chrome.browser.ChromeTabbedActivity; -import org.chromium.chrome.browser.vr_shell.util.VrUtils; import org.chromium.chrome.test.ChromeTabbedActivityTestRule; import org.chromium.content.browser.ContentViewCore; -import org.chromium.content.browser.test.util.ClickUtils; import org.chromium.content.browser.test.util.Criteria; import org.chromium.content.browser.test.util.CriteriaHelper; -import org.chromium.content.browser.test.util.DOMUtils; import org.chromium.content.browser.test.util.JavaScriptUtils; import org.chromium.content_public.browser.WebContents; @@ -54,9 +42,14 @@ * which can then grab the results and pass/fail the instrumentation test. */ public class VrTestRule extends ChromeTabbedActivityTestRule { + public static final int PAGE_LOAD_TIMEOUT_S = 10; + public static final int POLL_CHECK_INTERVAL_SHORT_MS = 50; + public static final int POLL_CHECK_INTERVAL_LONG_MS = 100; + public static final int POLL_TIMEOUT_SHORT_MS = 1000; + public static final int POLL_TIMEOUT_LONG_MS = 10000; + private static final String TAG = "VrTestRule"; static final String TEST_DIR = "chrome/test/data/android/webvr_instrumentation"; - static final int PAGE_LOAD_TIMEOUT_S = 10; private WebContents mFirstTabWebContents; private ContentViewCore mFirstTabCvc; @@ -113,66 +106,11 @@ * @param webContents The WebContents to run the JavaScript through. * @return Whether a VRDisplay was found. */ - public boolean vrDisplayFound(WebContents webContents) { + public static boolean vrDisplayFound(WebContents webContents) { return !runJavaScriptOrFail("vrDisplay", POLL_TIMEOUT_SHORT_MS, webContents).equals("null"); } /** - * Use to simulate a cardboard click by sending a touch event to the device. - * @param activity The activity to send the cardboard click to. - */ - public void sendCardboardClick(Activity activity) { - ClickUtils.mouseSingleClickView(InstrumentationRegistry.getInstrumentation(), - activity.getWindow().getDecorView().getRootView()); - } - - /** - * Sends a cardboard click then waits for the JavaScript step to finish. - * @param activity The activity to send the cardboard click to. - * @param webContents The WebContents for the tab the JavaScript step is in. - */ - public void sendCardboardClickAndWait(Activity activity, WebContents webContents) { - sendCardboardClick(activity); - waitOnJavaScriptStep(webContents); - } - - /** - * Sends a click event directly to the WebGL canvas, triggering its onclick - * that by default calls WebVR's requestPresent. Will have a similar result to - * sendCardboardClick if not already presenting, but less prone to errors, e.g. - * if there's dialog in the center of the screen blocking the canvas. - * @param cvc The ContentViewCore for the tab the canvas is in. - */ - public void enterPresentation(ContentViewCore cvc) { - try { - DOMUtils.clickNode(cvc, "webgl-canvas"); - } catch (InterruptedException | TimeoutException e) { - Assert.fail("Failed to click canvas to enter presentation: " + e.toString()); - } - } - - /** - * Sends a click event directly to the WebGL canvas then waits for the - * JavaScript step to finish. - * @param cvc The ContentViewCore for the tab the canvas is in. - * @param webContents The WebContents for the tab the JavaScript step is in. - */ - public void enterPresentationAndWait(ContentViewCore cvc, WebContents webContents) { - enterPresentation(cvc); - waitOnJavaScriptStep(webContents); - } - - /** - * Simulate an NFC scan and wait for the JavaScript code in the given - * WebContents to signal that it is done with the step. - * @param webContents The WebContents for the JavaScript that will be polled. - */ - public void simNfcScanAndWait(ChromeTabbedActivity activity, WebContents webContents) { - VrUtils.simNfcScan(activity); - waitOnJavaScriptStep(webContents); - } - - /** * Helper function to run the given JavaScript, return the return value, * and fail if a timeout/interrupt occurs so we don't have to catch or * declare exceptions all the time. @@ -181,7 +119,7 @@ * @param webContents The WebContents object to run the JavaScript in. * @return The return value of the JavaScript. */ - public String runJavaScriptOrFail(String js, int timeout, WebContents webContents) { + public static String runJavaScriptOrFail(String js, int timeout, WebContents webContents) { try { return JavaScriptUtils.executeJavaScriptAndWaitForResult( webContents, js, timeout, TimeUnit.MILLISECONDS); @@ -196,7 +134,7 @@ * @param webContents The WebContents for the tab to check results in. * @return "Passed" if test passed, String with failure reason otherwise. */ - public String checkResults(WebContents webContents) { + public static String checkResults(WebContents webContents) { if (runJavaScriptOrFail("testPassed", POLL_TIMEOUT_SHORT_MS, webContents).equals("true")) { return "Passed"; } @@ -208,7 +146,7 @@ * setting the failure reason as the description if it didn't. * @param webContents The WebContents for the tab to check test results in. */ - public void endTest(WebContents webContents) { + public static void endTest(WebContents webContents) { Assert.assertEquals("Passed", checkResults(webContents)); } @@ -220,7 +158,7 @@ * @param webContents The WebContents to run the JavaScript through. * @return True if the boolean evaluated to true, false if timed out. */ - public boolean pollJavaScriptBoolean( + public static boolean pollJavaScriptBoolean( final String boolName, int timeoutMs, final WebContents webContents) { try { CriteriaHelper.pollInstrumentationThread(Criteria.equals(true, new Callable<Boolean>() { @@ -248,7 +186,7 @@ * instead of timing out. * @param webContents The WebContents for the tab the JavaScript step is in. */ - public void waitOnJavaScriptStep(WebContents webContents) { + public static void waitOnJavaScriptStep(WebContents webContents) { Assert.assertTrue("Polling JavaScript boolean javascriptDone timed out", pollJavaScriptBoolean("javascriptDone", POLL_TIMEOUT_LONG_MS, webContents)); // Reset the synchronization boolean @@ -260,7 +198,7 @@ * @param stepFunction The JavaScript step function to call. * @param webContents The WebContents for the tab the JavaScript is in. */ - public void executeStepAndWait(String stepFunction, WebContents webContents) { + public static void executeStepAndWait(String stepFunction, WebContents webContents) { // Run the step and block JavaScriptUtils.executeJavaScript(webContents, stepFunction); waitOnJavaScriptStep(webContents);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/WebVrTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/WebVrTest.java index 6cb8ad0..f4a8d39 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/WebVrTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/WebVrTest.java
@@ -5,7 +5,7 @@ package org.chromium.chrome.browser.vr_shell; import static org.chromium.chrome.browser.vr_shell.VrTestRule.PAGE_LOAD_TIMEOUT_S; -import static org.chromium.chrome.browser.vr_shell.util.VrUtils.POLL_TIMEOUT_SHORT_MS; +import static org.chromium.chrome.browser.vr_shell.VrTestRule.POLL_TIMEOUT_SHORT_MS; import static org.chromium.chrome.test.util.ChromeRestriction.RESTRICTION_TYPE_VIEWER_DAYDREAM; import static org.chromium.chrome.test.util.ChromeRestriction.RESTRICTION_TYPE_VIEWER_NON_DAYDREAM; @@ -30,7 +30,11 @@ import org.chromium.chrome.R; import org.chromium.chrome.browser.ChromeSwitches; import org.chromium.chrome.browser.vr_shell.mock.MockVrCoreVersionCheckerImpl; -import org.chromium.chrome.browser.vr_shell.util.VrUtils; +import org.chromium.chrome.browser.vr_shell.util.CardboardUtils; +import org.chromium.chrome.browser.vr_shell.util.NfcSimUtils; +import org.chromium.chrome.browser.vr_shell.util.VrInfoBarUtils; +import org.chromium.chrome.browser.vr_shell.util.VrShellDelegateUtils; +import org.chromium.chrome.browser.vr_shell.util.VrTransitionUtils; import org.chromium.chrome.test.ChromeActivityTestRule; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; @@ -61,7 +65,7 @@ public void testRequestPresentEntersVr() throws InterruptedException { mVrTestRule.loadUrlAndAwaitInitialization( VrTestRule.getHtmlTestFile("test_requestPresent_enters_vr"), PAGE_LOAD_TIMEOUT_S); - mVrTestRule.enterPresentationAndWait( + VrTransitionUtils.enterPresentationAndWait( mVrTestRule.getFirstTabCvc(), mVrTestRule.getFirstTabWebContents()); Assert.assertTrue("VrShellDelegate is in VR", VrShellDelegate.isInVr()); mVrTestRule.endTest(mVrTestRule.getFirstTabWebContents()); @@ -78,8 +82,8 @@ mVrTestRule.loadUrlAndAwaitInitialization( VrTestRule.getHtmlTestFile("test_nfc_fires_vrdisplayactivate"), PAGE_LOAD_TIMEOUT_S); - mVrTestRule.simNfcScanAndWait( - mVrTestRule.getActivity(), mVrTestRule.getFirstTabWebContents()); + NfcSimUtils.simNfcScan(mVrTestRule.getActivity()); + mVrTestRule.waitOnJavaScriptStep(mVrTestRule.getFirstTabWebContents()); mVrTestRule.endTest(mVrTestRule.getFirstTabWebContents()); } @@ -95,7 +99,7 @@ PAGE_LOAD_TIMEOUT_S); mVrTestRule.executeStepAndWait( "stepVerifyNoInitialTaps()", mVrTestRule.getFirstTabWebContents()); - mVrTestRule.enterPresentationAndWait( + VrTransitionUtils.enterPresentationAndWait( mVrTestRule.getFirstTabCvc(), mVrTestRule.getFirstTabWebContents()); // Wait on VrShellImpl to say that its parent consumed the touch event // Set to 2 because there's an ACTION_DOWN followed by ACTION_UP @@ -108,7 +112,7 @@ touchRegisteredLatch.countDown(); } }); - mVrTestRule.sendCardboardClick(mVrTestRule.getActivity()); + CardboardUtils.sendCardboardClick(mVrTestRule.getActivity()); Assert.assertTrue("VrShellImpl dispatched touches", touchRegisteredLatch.await(POLL_TIMEOUT_SHORT_MS, TimeUnit.MILLISECONDS)); mVrTestRule.executeStepAndWait( @@ -130,7 +134,7 @@ mVrTestRule.executeStepAndWait( "stepVerifyNoInitialTaps()", mVrTestRule.getFirstTabWebContents()); // Wait to enter VR - mVrTestRule.enterPresentationAndWait( + VrTransitionUtils.enterPresentationAndWait( mVrTestRule.getFirstTabCvc(), mVrTestRule.getFirstTabWebContents()); // Send a controller click and wait for JavaScript to receive it controller.pressReleaseTouchpadButton(); @@ -153,10 +157,10 @@ mVrTestRule.executeStepAndWait( "stepVerifyNoInitialTaps()", mVrTestRule.getFirstTabWebContents()); // Wait to enter VR - mVrTestRule.enterPresentationAndWait( + VrTransitionUtils.enterPresentationAndWait( mVrTestRule.getFirstTabCvc(), mVrTestRule.getFirstTabWebContents()); // Tap and wait for JavaScript to receive it - mVrTestRule.sendCardboardClickAndWait( + CardboardUtils.sendCardboardClickAndWait( mVrTestRule.getActivity(), mVrTestRule.getFirstTabWebContents()); mVrTestRule.endTest(mVrTestRule.getFirstTabWebContents()); } @@ -191,7 +195,7 @@ public void run() { MockVrCoreVersionCheckerImpl mockChecker = new MockVrCoreVersionCheckerImpl(); mockChecker.setMockReturnValue(new VrCoreInfo(null, checkerReturnCompatibility)); - VrShellDelegate.getInstanceForTesting().overrideVrCoreVersionCheckerForTesting( + VrShellDelegateUtils.getDelegateInstance().overrideVrCoreVersionCheckerForTesting( mockChecker); Assert.assertEquals( checkerReturnCompatibility, mockChecker.getLastReturnValue().compatibility); @@ -199,7 +203,7 @@ }); View decorView = mVrTestRule.getActivity().getWindow().getDecorView(); if (checkerReturnCompatibility == VrCoreCompatibility.VR_READY) { - VrUtils.expectInfoBarPresent(decorView, false); + VrInfoBarUtils.expectInfoBarPresent(mVrTestRule, false); } else if (checkerReturnCompatibility == VrCoreCompatibility.VR_OUT_OF_DATE || checkerReturnCompatibility == VrCoreCompatibility.VR_NOT_AVAILABLE) { // Out of date and missing cases are the same, but with different text @@ -215,16 +219,13 @@ expectedButton = mVrTestRule.getActivity().getString( R.string.vr_services_check_infobar_install_button); } - VrUtils.expectInfoBarPresent(decorView, true); - TextView tempView = - (TextView) mVrTestRule.getActivity().getWindow().getDecorView().findViewById( - R.id.infobar_message); + VrInfoBarUtils.expectInfoBarPresent(mVrTestRule, true); + TextView tempView = (TextView) decorView.findViewById(R.id.infobar_message); Assert.assertEquals(expectedMessage, tempView.getText().toString()); - tempView = (TextView) mVrTestRule.getActivity().getWindow().getDecorView().findViewById( - R.id.button_primary); + tempView = (TextView) decorView.findViewById(R.id.button_primary); Assert.assertEquals(expectedButton, tempView.getText().toString()); } else if (checkerReturnCompatibility == VrCoreCompatibility.VR_NOT_SUPPORTED) { - VrUtils.expectInfoBarPresent(decorView, false); + VrInfoBarUtils.expectInfoBarPresent(mVrTestRule, false); } else { Assert.fail("Invalid VrCoreVersionChecker compatibility: " + String.valueOf(checkerReturnCompatibility)); @@ -292,7 +293,7 @@ public void testPresentationLocksFocus() throws InterruptedException { mVrTestRule.loadUrlAndAwaitInitialization( VrTestRule.getHtmlTestFile("test_presentation_locks_focus"), PAGE_LOAD_TIMEOUT_S); - mVrTestRule.enterPresentationAndWait( + VrTransitionUtils.enterPresentationAndWait( mVrTestRule.getFirstTabCvc(), mVrTestRule.getFirstTabWebContents()); mVrTestRule.endTest(mVrTestRule.getFirstTabWebContents()); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/util/CardboardUtils.java b/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/util/CardboardUtils.java new file mode 100644 index 0000000..9ecfe53 --- /dev/null +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/util/CardboardUtils.java
@@ -0,0 +1,39 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.vr_shell.util; + +import android.app.Activity; +import android.support.test.InstrumentationRegistry; + +import org.chromium.chrome.browser.vr_shell.VrTestRule; +import org.chromium.content.browser.test.util.ClickUtils; +import org.chromium.content_public.browser.WebContents; + +/** + * Class containing utility functions for sending Cardboard clicks, aka + * screen taps. + */ +public class CardboardUtils { + /** + * Use to simulate a cardboard click by sending a touch event to the device. + * @param activity The activity to send the cardboard click to. + */ + public static void sendCardboardClick(Activity activity) { + ClickUtils.mouseSingleClickView(InstrumentationRegistry.getInstrumentation(), + activity.getWindow().getDecorView().getRootView()); + } + + /** + * Sends a cardboard click then waits for the JavaScript step to finish. + * + * Only meant to be used alongside the test framework from VrTestRule. + * @param activity The activity to send the cardboard click to. + * @param webContents The WebContents for the tab the JavaScript step is in. + */ + public static void sendCardboardClickAndWait(Activity activity, WebContents webContents) { + sendCardboardClick(activity); + VrTestRule.waitOnJavaScriptStep(webContents); + } +}
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/util/NfcSimUtils.java b/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/util/NfcSimUtils.java index baf20eb..8f55e1e 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/util/NfcSimUtils.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/util/NfcSimUtils.java
@@ -4,7 +4,9 @@ package org.chromium.chrome.browser.vr_shell.util; +import android.content.ActivityNotFoundException; import android.content.ComponentName; +import android.content.Context; import android.content.Intent; import android.nfc.NdefMessage; import android.nfc.NdefRecord; @@ -14,10 +16,7 @@ import java.nio.ByteOrder; /** - * Utility class to simulate a Daydream View NFC tag being scanned. In its own - * class so that both instrumentation tests and the standalone APK for use with - * Telemetry can share code without the APK including instrumentation-test-only - * code. + * Utility class to simulate a Daydream View NFC tag being scanned. */ public class NfcSimUtils { private static final String DETECTION_ACTIVITY = ".nfc.ViewerDetectionActivity"; @@ -51,6 +50,19 @@ return nfcIntent; } + /** + * Simulates the NFC tag of the Daydream headset being scanned. + * @param context The Context that the activity will be started from. + */ + public static void simNfcScan(Context context) { + Intent nfcIntent = NfcSimUtils.makeNfcIntent(); + try { + context.startActivity(nfcIntent); + } catch (ActivityNotFoundException e) { + // On unsupported devices, won't find VrCore -> Do nothing + } + } + private static byte[] intToByteArray(int i) { final ByteBuffer bb = ByteBuffer.allocate(Integer.SIZE / Byte.SIZE); bb.order(BYTE_ORDER);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/util/VrInfoBarUtils.java b/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/util/VrInfoBarUtils.java new file mode 100644 index 0000000..29a021a --- /dev/null +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/util/VrInfoBarUtils.java
@@ -0,0 +1,89 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.vr_shell.util; + +import static org.chromium.chrome.browser.vr_shell.VrTestRule.POLL_CHECK_INTERVAL_SHORT_MS; +import static org.chromium.chrome.browser.vr_shell.VrTestRule.POLL_TIMEOUT_SHORT_MS; + +import org.chromium.base.ThreadUtils; +import org.chromium.chrome.browser.infobar.InfoBar; +import org.chromium.chrome.browser.vr_shell.VrTestRule; +import org.chromium.chrome.test.util.InfoBarUtil; +import org.chromium.content.browser.test.util.Criteria; +import org.chromium.content.browser.test.util.CriteriaHelper; + +import java.util.List; +import java.util.concurrent.Callable; + +/** + * Class containing utility functions for interacting with InfoBars at + * a high level. + */ +public class VrInfoBarUtils { + public enum Button { PRIMARY, SECONDARY }; + + /** + * Determines whether InfoBars are present in the current activity. + * @return True if there are any InfoBars present, false otherwise + */ + public static boolean isInfoBarPresent(VrTestRule rule) { + List<InfoBar> infoBars = rule.getInfoBars(); + return infoBars != null && !infoBars.isEmpty(); + } + + /** + * Clicks on either the primary or secondary button of the first InfoBar + * in the activity. + * @param button Which button to click + * @param rule The VrTestRule to get the current activity from + */ + public static void clickInfoBarButton(final Button button, VrTestRule rule) { + if (!isInfoBarPresent(rule)) return; + final List<InfoBar> infoBars = rule.getInfoBars(); + ThreadUtils.runOnUiThreadBlocking(new Runnable() { + @Override + public void run() { + switch (button) { + case PRIMARY: + InfoBarUtil.clickPrimaryButton(infoBars.get(0)); + break; + default: + InfoBarUtil.clickSecondaryButton(infoBars.get(0)); + } + } + }); + InfoBarUtil.waitUntilNoInfoBarsExist(rule.getInfoBars()); + } + + /** + * Clicks on the close button of the first InfoBar in the activity. + * @param rule The VrTestRule to get the current activity from + */ + public static void clickInfobarCloseButton(VrTestRule rule) { + if (!isInfoBarPresent(rule)) return; + final List<InfoBar> infoBars = rule.getInfoBars(); + ThreadUtils.runOnUiThreadBlocking(new Runnable() { + @Override + public void run() { + InfoBarUtil.clickCloseButton(infoBars.get(0)); + } + }); + InfoBarUtil.waitUntilNoInfoBarsExist(rule.getInfoBars()); + } + + /** + * Determines is there is any InfoBar present in the given View hierarchy. + * @param parentView The View to start the search in + * @param present Whether an InfoBar should be present. + */ + public static void expectInfoBarPresent(final VrTestRule rule, boolean present) { + CriteriaHelper.pollUiThread(Criteria.equals(present, new Callable<Boolean>() { + @Override + public Boolean call() { + return isInfoBarPresent(rule); + } + }), POLL_TIMEOUT_SHORT_MS, POLL_CHECK_INTERVAL_SHORT_MS); + } +}
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/util/VrShellDelegateUtils.java b/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/util/VrShellDelegateUtils.java new file mode 100644 index 0000000..09ec927e --- /dev/null +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/util/VrShellDelegateUtils.java
@@ -0,0 +1,32 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.vr_shell.util; + +import org.chromium.base.ThreadUtils; +import org.chromium.chrome.browser.vr_shell.VrShellDelegate; + +import java.util.concurrent.atomic.AtomicReference; + +/** + * Class containing utility functions for interacting with VrShellDelegate + * during tests. + */ +public class VrShellDelegateUtils { + /** + * Retrieves the current VrShellDelegate instance from the UI thread. + * This is necessary in case acquiring the instance causes the delegate + * to be constructed, which must happen on the UI thread. + */ + public static VrShellDelegate getDelegateInstance() { + final AtomicReference<VrShellDelegate> delegate = new AtomicReference<VrShellDelegate>(); + ThreadUtils.runOnUiThreadBlocking(new Runnable() { + @Override + public void run() { + delegate.set(VrShellDelegate.getInstanceForTesting()); + } + }); + return delegate.get(); + } +}
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/util/VrTransitionUtils.java b/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/util/VrTransitionUtils.java new file mode 100644 index 0000000..47ec4006 --- /dev/null +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/util/VrTransitionUtils.java
@@ -0,0 +1,102 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.vr_shell.util; + +import static org.chromium.chrome.browser.vr_shell.VrTestRule.POLL_CHECK_INTERVAL_SHORT_MS; + +import org.junit.Assert; + +import org.chromium.base.ThreadUtils; +import org.chromium.chrome.browser.vr_shell.VrShellDelegate; +import org.chromium.chrome.browser.vr_shell.VrTestRule; +import org.chromium.content.browser.ContentViewCore; +import org.chromium.content.browser.test.util.Criteria; +import org.chromium.content.browser.test.util.CriteriaHelper; +import org.chromium.content.browser.test.util.DOMUtils; +import org.chromium.content_public.browser.WebContents; + +import java.util.concurrent.Callable; +import java.util.concurrent.TimeoutException; + +/** + * Class containing utility functions for transitioning between different + * states in VR, such as fullscreen, WebVR presentation, and the VR browser. + * + * All the transitions in this class are performed directly through Chrome, + * as opposed to NFC tag simulation which involves receiving an intent from + * an outside application (VR Services). + */ +public class VrTransitionUtils { + /** + * Forces the browser into VR mode via a VrShellDelegate call. + */ + public static void forceEnterVr() { + ThreadUtils.runOnUiThreadBlocking(new Runnable() { + @Override + public void run() { + VrShellDelegate.enterVrIfNecessary(); + } + }); + } + + /** + * Forces the browser out of VR mode via a VrShellDelegate call. + */ + public static void forceExitVr() { + ThreadUtils.runOnUiThreadBlocking(new Runnable() { + @Override + public void run() { + VrShellDelegateUtils.getDelegateInstance().shutdownVr(true /* disableVrMode */, + false /* canReenter */, true /* stayingInChrome */); + } + }); + } + + /** + * Waits until the given VrShellDelegate's isInVR() returns true. Should + * only be used when VR support is expected. + * @param timeout How long to wait before giving up, in milliseconds + */ + public static void waitForVrEntry(final int timeout) { + // If VR Shell is supported, mInVr should eventually go to true + // Relatively long timeout because sometimes GVR takes a while to enter VR + CriteriaHelper.pollUiThread(Criteria.equals(true, new Callable<Boolean>() { + @Override + public Boolean call() { + return VrShellDelegate.isInVr(); + } + }), timeout, POLL_CHECK_INTERVAL_SHORT_MS); + } + + /** + * Sends a click event directly to the WebGL canvas, triggering its onclick + * that by default calls WebVR's requestPresent. Will have a similar result to + * CardboardUtils.sendCardboardClick if not already presenting, but less prone + * to errors, e.g. if there's dialog in the center of the screen blocking the canvas. + * + * Only meant to be used alongside the test framework from VrTestRule. + * @param cvc The ContentViewCore for the tab the canvas is in. + */ + public static void enterPresentation(ContentViewCore cvc) { + try { + DOMUtils.clickNode(cvc, "webgl-canvas"); + } catch (InterruptedException | TimeoutException e) { + Assert.fail("Failed to click canvas to enter presentation: " + e.toString()); + } + } + + /** + * Sends a click event directly to the WebGL canvas then waits for the + * JavaScript step to finish. + * + * Only meant to be used alongside the test framework from VrTestRule. + * @param cvc The ContentViewCore for the tab the canvas is in. + * @param webContents The WebContents for the tab the JavaScript step is in. + */ + public static void enterPresentationAndWait(ContentViewCore cvc, WebContents webContents) { + enterPresentation(cvc); + VrTestRule.waitOnJavaScriptStep(webContents); + } +}
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/util/VrUtils.java b/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/util/VrUtils.java deleted file mode 100644 index 5aa5159..0000000 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/util/VrUtils.java +++ /dev/null
@@ -1,138 +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. - -package org.chromium.chrome.browser.vr_shell.util; - -import android.content.ActivityNotFoundException; -import android.content.Context; -import android.content.Intent; -import android.view.View; -import android.view.ViewGroup; - -import org.chromium.base.ThreadUtils; -import org.chromium.chrome.browser.infobar.InfoBarLayout; -import org.chromium.chrome.browser.vr_shell.VrShellDelegate; -import org.chromium.content.browser.test.util.Criteria; -import org.chromium.content.browser.test.util.CriteriaHelper; - -import java.util.concurrent.Callable; -import java.util.concurrent.atomic.AtomicReference; - -/** - * Class containing static functions and constants that are useful for VR - * instrumentation testing. - */ -public class VrUtils { - public static final int POLL_CHECK_INTERVAL_SHORT_MS = 50; - public static final int POLL_CHECK_INTERVAL_LONG_MS = 100; - public static final int POLL_TIMEOUT_SHORT_MS = 1000; - public static final int POLL_TIMEOUT_LONG_MS = 10000; - - /** - * Gets the VrShellDelegate instance on the UI thread, as otherwise the Choreographer obtained - * in VrShellDelegate's constructor is for the instrumentation thread instead of the UI thread. - * @return The browser's current VrShellDelegate instance - */ - public static VrShellDelegate getVrShellDelegateInstance() { - final AtomicReference<VrShellDelegate> delegate = new AtomicReference<VrShellDelegate>(); - ThreadUtils.runOnUiThreadBlocking(new Runnable() { - @Override - public void run() { - delegate.set(VrShellDelegate.getInstanceForTesting()); - } - }); - return delegate.get(); - } - - /** - * Forces the browser into VR mode via a VrShellDelegate call. - */ - public static void forceEnterVr() { - ThreadUtils.runOnUiThreadBlocking(new Runnable() { - @Override - public void run() { - VrShellDelegate.enterVrIfNecessary(); - } - }); - } - - /** - * Forces the browser out of VR mode via a VrShellDelegate call. - * @param vrDelegate The VRShellDelegate associated with this activity. - */ - public static void forceExitVr(final VrShellDelegate vrDelegate) { - ThreadUtils.runOnUiThreadBlocking(new Runnable() { - @Override - public void run() { - vrDelegate.shutdownVr(true /* disableVrMode */, false /* canReenter */, - true /* stayingInChrome */); - } - }); - } - - /** - * Simulates the NFC tag of the Daydream headset being scanned. - * @param context The Context that the activity will be started from. - */ - public static void simNfcScan(Context context) { - Intent nfcIntent = NfcSimUtils.makeNfcIntent(); - try { - context.startActivity(nfcIntent); - } catch (ActivityNotFoundException e) { - // On unsupported devices, won't find VrCore -> Do nothing - } - } - - /** - * Waits until the given VrShellDelegate's isInVR() returns true. Should - * only be used when VR Shell support is expected. - * @param timeout How long to wait before giving up, in milliseconds - */ - public static void waitForVrSupported(final int timeout) { - // If VR Shell is supported, mInVr should eventually go to true - // Relatively long timeout because sometimes GVR takes a while to enter VR - CriteriaHelper.pollUiThread(Criteria.equals(true, new Callable<Boolean>() { - @Override - public Boolean call() { - return VrShellDelegate.isInVr(); - } - }), timeout, POLL_CHECK_INTERVAL_SHORT_MS); - } - - /** - * Determines is there is any InfoBar present in the given View hierarchy. - * @param parentView The View to start the search in - * @param present Whether an InfoBar should be present. - */ - public static void expectInfoBarPresent(final View parentView, boolean present) { - CriteriaHelper.pollUiThread(Criteria.equals(present, new Callable<Boolean>() { - @Override - public Boolean call() { - return isInfoBarPresentInternal(parentView); - } - }), POLL_TIMEOUT_SHORT_MS, POLL_CHECK_INTERVAL_SHORT_MS); - } - - /** - * Determines is there is any InfoBar present in the given View hierarchy. - * @param parentView The View to start the search in - * @return Whether the InfoBar is present - */ - private static boolean isInfoBarPresentInternal(View parentView) { - // TODO(ymalik): This will return true if any infobar is present. Is it - // possible to determine the type of infobar present (e.g. Feedback)? - // InfoBarContainer will be present regardless of whether an InfoBar - // is actually there, but InfoBarLayout is only present if one is - // currently showing. - if (parentView instanceof InfoBarLayout) { - return true; - } else if (parentView instanceof ViewGroup) { - ViewGroup group = (ViewGroup) parentView; - for (int i = 0; i < group.getChildCount(); i++) { - if (isInfoBarPresentInternal(group.getChildAt(i))) return true; - } - } - return false; - } -}
diff --git a/chrome/app/chrome_manifest.json b/chrome/app/chrome_manifest.json index a3d96761..6c0181a5 100644 --- a/chrome/app/chrome_manifest.json +++ b/chrome/app/chrome_manifest.json
@@ -4,6 +4,11 @@ "interface_provider_specs": { "service_manager:connector": { "provides": { + // This is only used in classic ash. In mus InputDeviceController comes + // from mus. + "input_device_controller": [ + "ui::mojom::InputDeviceController" + ], "mash:launchable": [ "mash::mojom::Launchable" ]
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index aa464ff..ee3fae0 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -682,6 +682,8 @@ "net/chrome_extensions_network_delegate.h", "net/chrome_http_user_agent_settings.cc", "net/chrome_http_user_agent_settings.h", + "net/chrome_mojo_proxy_resolver_factory.cc", + "net/chrome_mojo_proxy_resolver_factory.h", "net/chrome_net_log_helper.cc", "net/chrome_net_log_helper.h", "net/chrome_network_delegate.cc", @@ -1659,6 +1661,7 @@ "//mojo/public/cpp/bindings", "//mojo/public/js", "//net:extras", + "//net:net_browser_services", "//ppapi/features", "//printing/features", "//rlz/features", @@ -1715,6 +1718,7 @@ # platforms use OOP Mojo resolution. if (is_android) { deps += [ + "//net:net_utility_services", "//net:net_with_v8", "//v8", ] @@ -2481,6 +2485,13 @@ "//components/metrics/leak_detector:interfaces", "//components/metrics/leak_detector:leak_detector", ] + if (use_ozone) { + deps += [ + "//services/ui/public/cpp/input_devices", + "//services/ui/public/cpp/input_devices:input_device_controller", + "//ui/ozone", + ] + } } else { # Non-ChromeOS. sources += [ "policy/cloud/user_cloud_policy_manager_factory.cc", @@ -3495,8 +3506,6 @@ "metrics/tab_usage_recorder.h", "net/firefox_proxy_settings.cc", "net/firefox_proxy_settings.h", - "net/utility_process_mojo_proxy_resolver_factory.cc", - "net/utility_process_mojo_proxy_resolver_factory.h", "notifications/application_notifier_source.cc", "notifications/application_notifier_source.h", "notifications/arc_application_notifier_source_chromeos.cc", @@ -3710,7 +3719,6 @@ "//components/cryptauth/proto", "//components/feedback", "//components/web_modal", - "//net:net_browser_services", ] }
diff --git a/chrome/browser/android/offline_pages/prefetch/prefetch_background_task.cc b/chrome/browser/android/offline_pages/prefetch/prefetch_background_task.cc index 231be79f..43b46cc9 100644 --- a/chrome/browser/android/offline_pages/prefetch/prefetch_background_task.cc +++ b/chrome/browser/android/offline_pages/prefetch/prefetch_background_task.cc
@@ -53,7 +53,7 @@ prefetch_service->GetPrefetchDispatcher()->BeginBackgroundTask( base::MakeUnique<PrefetchBackgroundTask>(env, jcaller, prefetch_service, profile)); - return false; // true; + return true; } } // namespace prefetch
diff --git a/chrome/browser/browser_process_platform_part_chromeos.cc b/chrome/browser/browser_process_platform_part_chromeos.cc index 08f4c21..af96a8b 100644 --- a/chrome/browser/browser_process_platform_part_chromeos.cc +++ b/chrome/browser/browser_process_platform_part_chromeos.cc
@@ -9,6 +9,8 @@ #include "base/time/default_tick_clock.h" #include "base/time/tick_clock.h" #include "chrome/browser/browser_process.h" +#include "chrome/browser/chromeos/ash_config.h" +#include "chrome/browser/chromeos/chrome_service_name.h" #include "chrome/browser/chromeos/login/session/chrome_session_manager.h" #include "chrome/browser/chromeos/login/users/chrome_user_manager_impl.h" #include "chrome/browser/chromeos/net/delay_network_call.h" @@ -29,6 +31,14 @@ #include "components/session_manager/core/session_manager.h" #include "components/user_manager/user_manager.h" +#if defined(USE_OZONE) +#include "ash/public/interfaces/constants.mojom.h" +#include "content/public/common/service_manager_connection.h" +#include "services/service_manager/runner/common/client_util.h" +#include "services/ui/public/cpp/input_devices/input_device_controller_client.h" +#include "services/ui/public/interfaces/constants.mojom.h" +#endif + BrowserProcessPlatformPart::BrowserProcessPlatformPart() : created_profile_helper_(false) {} @@ -166,6 +176,23 @@ return compatible_cros_components_.count(name) > 0; } +#if defined(USE_OZONE) +ui::InputDeviceControllerClient* +BrowserProcessPlatformPart::GetInputDeviceControllerClient() { + if (!input_device_controller_client_) { + const std::string service_name = + chromeos::GetAshConfig() == ash::Config::CLASSIC + ? chromeos::kChromeServiceName + : ui::mojom::kServiceName; + input_device_controller_client_ = + base::MakeUnique<ui::InputDeviceControllerClient>( + content::ServiceManagerConnection::GetForProcess()->GetConnector(), + service_name); + } + return input_device_controller_client_.get(); +} +#endif + void BrowserProcessPlatformPart::CreateProfileHelper() { DCHECK(!created_profile_helper_ && !profile_helper_); created_profile_helper_ = true;
diff --git a/chrome/browser/browser_process_platform_part_chromeos.h b/chrome/browser/browser_process_platform_part_chromeos.h index 11348eff..2aa21c1 100644 --- a/chrome/browser/browser_process_platform_part_chromeos.h +++ b/chrome/browser/browser_process_platform_part_chromeos.h
@@ -36,6 +36,10 @@ class BrowserPolicyConnectorChromeOS; } +namespace ui { +class InputDeviceControllerClient; +} + class ScopedKeepAlive; class BrowserProcessPlatformPart : public BrowserProcessPlatformPartBase { @@ -103,6 +107,10 @@ bool IsCompatibleCrOSComponent(const std::string& name); +#if defined(USE_OZONE) + ui::InputDeviceControllerClient* GetInputDeviceControllerClient(); +#endif + private: void CreateProfileHelper(); @@ -131,6 +139,11 @@ base::flat_set<std::string> compatible_cros_components_; +#if defined(USE_OZONE) + std::unique_ptr<ui::InputDeviceControllerClient> + input_device_controller_client_; +#endif + SEQUENCE_CHECKER(sequence_checker_); DISALLOW_COPY_AND_ASSIGN(BrowserProcessPlatformPart);
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index 6435b992..a607f6a0 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc
@@ -234,6 +234,7 @@ #include "chrome/browser/chromeos/arc/intent_helper/arc_navigation_throttle.h" #include "chrome/browser/chromeos/attestation/platform_verification_impl.h" #include "chrome/browser/chromeos/chrome_browser_main_chromeos.h" +#include "chrome/browser/chromeos/chrome_service_name.h" #include "chrome/browser/chromeos/drive/fileapi/file_system_backend_delegate.h" #include "chrome/browser/chromeos/file_manager/app_id.h" #include "chrome/browser/chromeos/file_system_provider/fileapi/backend_delegate.h" @@ -244,11 +245,13 @@ #include "chrome/browser/chromeos/login/startup_utils.h" #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" #include "chrome/browser/chromeos/system/input_device_settings.h" +#include "chrome/browser/metrics/leak_detector/leak_detector_remote_controller.h" #include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/ui/ash/ash_util.h" #include "chrome/browser/ui/browser_commands.h" #include "chrome/browser/ui/browser_dialogs.h" #include "chrome/browser/ui/browser_finder.h" +#include "chrome/browser/ui/views/ash/chrome_browser_main_extra_parts_ash.h" #include "chromeos/chromeos_constants.h" #include "chromeos/chromeos_switches.h" #include "components/user_manager/user_manager.h" @@ -258,16 +261,30 @@ #include "chrome/browser/chrome_browser_main_linux.h" #elif defined(OS_ANDROID) #include "chrome/browser/android/app_hooks.h" +#include "chrome/browser/android/chrome_context_util.h" +#include "chrome/browser/android/devtools_manager_delegate_android.h" +#include "chrome/browser/android/ntp/new_tab_page_url_handler.h" +#include "chrome/browser/android/service_tab_launcher.h" +#include "chrome/browser/android/tab_android.h" +#include "chrome/browser/android/webapps/single_tab_mode_tab_helper.h" #include "chrome/browser/chrome_browser_main_android.h" #include "chrome/common/descriptors_android.h" #include "components/crash/content/browser/crash_dump_manager_android.h" #include "components/navigation_interception/intercept_navigation_delegate.h" +#include "components/payments/mojom/payment_request.mojom.h" +#include "content/public/browser/android/java_interfaces.h" #include "ui/base/resource/resource_bundle_android.h" +#include "ui/base/ui_base_paths.h" #elif defined(OS_POSIX) #include "chrome/browser/chrome_browser_main_posix.h" #endif +#if defined(OS_CHROMEOS) && defined(USE_OZONE) +#include "services/ui/public/cpp/input_devices/input_device_controller.h" +#endif + #if !defined(OS_ANDROID) +#include "chrome/browser/devtools/chrome_devtools_manager_delegate.h" #include "chrome/browser/payments/payment_request_factory.h" #endif @@ -281,20 +298,6 @@ #include "components/crash/content/browser/crash_handler_host_linux.h" #endif -#if defined(OS_ANDROID) -#include "chrome/browser/android/chrome_context_util.h" -#include "chrome/browser/android/devtools_manager_delegate_android.h" -#include "chrome/browser/android/ntp/new_tab_page_url_handler.h" -#include "chrome/browser/android/service_tab_launcher.h" -#include "chrome/browser/android/tab_android.h" -#include "chrome/browser/android/webapps/single_tab_mode_tab_helper.h" -#include "components/payments/mojom/payment_request.mojom.h" -#include "content/public/browser/android/java_interfaces.h" -#include "ui/base/ui_base_paths.h" -#else -#include "chrome/browser/devtools/chrome_devtools_manager_delegate.h" -#endif - #if defined(TOOLKIT_VIEWS) #include "chrome/browser/ui/views/chrome_browser_main_extra_parts_views.h" #endif @@ -310,10 +313,6 @@ #include "ui/views/mus/mus_client.h" #endif -#if defined(USE_ASH) -#include "chrome/browser/ui/views/ash/chrome_browser_main_extra_parts_ash.h" -#endif - #if defined(USE_X11) #include "chrome/browser/chrome_browser_main_extra_parts_x11.h" #endif @@ -401,10 +400,6 @@ #include "media/mojo/services/media_service_factory.h" // nogncheck #endif -#if defined(OS_CHROMEOS) -#include "chrome/browser/metrics/leak_detector/leak_detector_remote_controller.h" -#endif - #if BUILDFLAG(ENABLE_SUPERVISED_USERS) #include "chrome/browser/supervised_user/supervised_user_navigation_throttle.h" #endif @@ -506,10 +501,6 @@ #if defined(OS_CHROMEOS) -// The name of the packaged service used to expose miscellaneous application -// control features such as the mash Launchable interface. -const char kChromeServiceName[] = "chrome"; - // Packaged service implementation used to expose miscellaneous application // control features. This is a singleton service which runs on the main thread // and never stops. @@ -517,6 +508,9 @@ public mash::mojom::Launchable { public: ChromeServiceChromeOS() { +#if defined(USE_OZONE) + input_device_controller_.AddInterface(&interfaces_); +#endif interfaces_.AddInterface<mash::mojom::Launchable>( base::Bind(&ChromeServiceChromeOS::Create, base::Unretained(this))); } @@ -575,6 +569,9 @@ service_manager::BinderRegistry interfaces_; mojo::BindingSet<mash::mojom::Launchable> bindings_; +#if defined(USE_OZONE) + ui::InputDeviceController input_device_controller_; +#endif DISALLOW_COPY_AND_ASSIGN(ChromeServiceChromeOS); }; @@ -3154,7 +3151,7 @@ content::ServiceInfo info; info.factory = base::Bind(&ChromeServiceChromeOS::CreateService); info.task_runner = base::ThreadTaskRunnerHandle::Get(); - services->insert(std::make_pair(kChromeServiceName, info)); + services->insert(std::make_pair(chromeos::kChromeServiceName, info)); } if (features::PrefServiceEnabled()) {
diff --git a/chrome/browser/chrome_content_browser_manifest_overlay.json b/chrome/browser/chrome_content_browser_manifest_overlay.json index cd6f9bbb..df431cad0 100644 --- a/chrome/browser/chrome_content_browser_manifest_overlay.json +++ b/chrome/browser/chrome_content_browser_manifest_overlay.json
@@ -27,13 +27,20 @@ "requires": { "accessibility_autoclick": [ "ash:autoclick" ], "ash": [ "ash", "display" ], + // Only used in classic ash case. + "chrome": [ "input_device_controller" ], "device": [ "device:fingerprint" ], "identity": [ "identity_manager" ], "nacl_broker": [ "browser" ], "nacl_loader": [ "browser" ], "preferences_forwarder": [ "pref_client" ], "preferences": [ "pref_client", "pref_control" ], - "ui": [ "display_controller", "ime_registrar", "window_manager" ] + "ui": [ + "display_controller", + "ime_registrar", + "input_device_controller", + "window_manager" + ] } }, "navigation:frame": {
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn index 363edaaa2..4b8b2e5 100644 --- a/chrome/browser/chromeos/BUILD.gn +++ b/chrome/browser/chromeos/BUILD.gn
@@ -390,6 +390,8 @@ "certificate_provider/thread_safe_certificate_map.h", "chrome_browser_main_chromeos.cc", "chrome_browser_main_chromeos.h", + "chrome_service_name.cc", + "chrome_service_name.h", "customization/customization_document.cc", "customization/customization_document.h", "customization/customization_wallpaper_downloader.cc",
diff --git a/chrome/browser/chromeos/arc/arc_play_store_enabled_preference_handler.cc b/chrome/browser/chromeos/arc/arc_play_store_enabled_preference_handler.cc index e7de3ac..4496078 100644 --- a/chrome/browser/chromeos/arc/arc_play_store_enabled_preference_handler.cc +++ b/chrome/browser/chromeos/arc/arc_play_store_enabled_preference_handler.cc
@@ -134,7 +134,8 @@ if (!base::CommandLine::ForCurrentProcess()->HasSwitch( chromeos::switches::kEnableArcOOBEOptIn) && profile_->IsNewProfile() && - !profile_->GetPrefs()->HasPrefPath(prefs::kArcEnabled)) { + !profile_->GetPrefs()->HasPrefPath(prefs::kArcEnabled) && + arc::IsPlayStoreAvailable()) { ArcAuthNotification::Show(profile_); } }
diff --git a/chrome/browser/chromeos/arc/arc_session_manager.cc b/chrome/browser/chromeos/arc/arc_session_manager.cc index e623a1d..f930bcc 100644 --- a/chrome/browser/chromeos/arc/arc_session_manager.cc +++ b/chrome/browser/chromeos/arc/arc_session_manager.cc
@@ -307,7 +307,8 @@ // the whole OptIn flow should happen as seamless as possible for the // user. const bool suppress_play_store_app = - IsArcOptInVerificationDisabled() || IsArcKioskMode() || + !IsPlayStoreAvailable() || IsArcOptInVerificationDisabled() || + IsArcKioskMode() || (IsArcPlayStoreEnabledPreferenceManagedForProfile(profile_) && AreArcAllOptInPreferencesManagedForProfile(profile_)); if (!suppress_play_store_app) {
diff --git a/chrome/browser/chromeos/arc/arc_session_manager_unittest.cc b/chrome/browser/chromeos/arc/arc_session_manager_unittest.cc index b251fd0..b3e21db 100644 --- a/chrome/browser/chromeos/arc/arc_session_manager_unittest.cc +++ b/chrome/browser/chromeos/arc/arc_session_manager_unittest.cc
@@ -469,7 +469,7 @@ ArcSessionManagerArcAlwaysStartTest() = default; void SetUp() override { - SetArcAlwaysStartForTesting(); + SetArcAlwaysStartForTesting(true); ArcSessionManagerTest::SetUp(); }
diff --git a/chrome/browser/chromeos/chrome_service_name.cc b/chrome/browser/chromeos/chrome_service_name.cc new file mode 100644 index 0000000..faed9da --- /dev/null +++ b/chrome/browser/chromeos/chrome_service_name.cc
@@ -0,0 +1,11 @@ +// 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 "chrome/browser/chromeos/chrome_service_name.h" + +namespace chromeos { + +const char kChromeServiceName[] = "chrome"; + +} // namespace chromeos
diff --git a/chrome/browser/chromeos/chrome_service_name.h b/chrome/browser/chromeos/chrome_service_name.h new file mode 100644 index 0000000..248becbe --- /dev/null +++ b/chrome/browser/chromeos/chrome_service_name.h
@@ -0,0 +1,16 @@ +// 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 CHROME_BROWSER_CHROMEOS_CHROME_SERVICE_NAME_H_ +#define CHROME_BROWSER_CHROMEOS_CHROME_SERVICE_NAME_H_ + +namespace chromeos { + +// This is the service name used for services exposed by Chrome. Interfaces +// exported (and potentially used inside Chrome) are registered under this name. +extern const char kChromeServiceName[]; + +} // namespace chromeos + +#endif // CHROME_BROWSER_CHROMEOS_CHROME_SERVICE_NAME_H_
diff --git a/chrome/browser/chromeos/input_method/input_method_manager_impl.cc b/chrome/browser/chromeos/input_method/input_method_manager_impl.cc index 059746f..703e114 100644 --- a/chrome/browser/chromeos/input_method/input_method_manager_impl.cc +++ b/chrome/browser/chromeos/input_method/input_method_manager_impl.cc
@@ -12,7 +12,9 @@ #include <sstream> #include <utility> +#include "ash/ime/ime_controller.h" #include "ash/shell.h" +#include "ash/system/tray/ime_info.h" #include "base/bind.h" #include "base/feature_list.h" #include "base/hash.h" @@ -21,6 +23,7 @@ #include "base/metrics/sparse_histogram.h" #include "base/strings/string_split.h" #include "base/strings/string_util.h" +#include "base/strings/utf_string_conversions.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/chromeos/ash_config.h" #include "chrome/browser/chromeos/input_method/candidate_window_controller.h" @@ -52,6 +55,19 @@ namespace { +InputMethodManagerImpl* g_instance = nullptr; + +ash::IMEInfo GetAshImeInfo(const InputMethodDescriptor& ime, + const InputMethodUtil& util) { + ash::IMEInfo info; + info.id = ime.id(); + info.name = util.GetInputMethodLongName(ime); + info.medium_name = util.GetInputMethodMediumName(ime); + info.short_name = util.GetInputMethodShortName(ime); + info.third_party = extension_ime_util::IsExtensionIME(ime.id()); + return info; +} + bool Contains(const std::vector<std::string>& container, const std::string& value) { return std::find(container.begin(), container.end(), value) != @@ -939,14 +955,25 @@ component_extension_ime_manager_->GetAllIMEAsInputMethodDescriptor(); util_.ResetInputMethods(descriptors); chromeos::UserAddingScreen::Get()->AddObserver(this); + + DCHECK(!g_instance); + g_instance = this; } InputMethodManagerImpl::~InputMethodManagerImpl() { + DCHECK_EQ(g_instance, this); + g_instance = nullptr; + if (candidate_window_controller_.get()) candidate_window_controller_->RemoveObserver(this); chromeos::UserAddingScreen::Get()->RemoveObserver(this); } +// static +InputMethodManagerImpl* InputMethodManagerImpl::Get() { + return g_instance; +} + void InputMethodManagerImpl::RecordInputMethodUsage( const std::string& input_method_id) { UMA_HISTOGRAM_ENUMERATION("InputMethod.Category", @@ -1335,5 +1362,55 @@ return base::FeatureList::IsEnabled(features::kEHVInputOnImeMenu); } +ash::IMEInfo InputMethodManagerImpl::GetCurrentIme() const { + if (!state_) + return ash::IMEInfo(); + + InputMethodDescriptor ime = state_->GetCurrentInputMethod(); + ash::IMEInfo info = GetAshImeInfo(ime, util_); + info.selected = true; + return info; +} + +std::vector<ash::IMEPropertyInfo> +InputMethodManagerImpl::GetCurrentImeProperties() const { + std::vector<ash::IMEPropertyInfo> properties; + ui::ime::InputMethodMenuItemList menu_list = + ui::ime::InputMethodMenuManager::GetInstance() + ->GetCurrentInputMethodMenuItemList(); + for (size_t i = 0; i < menu_list.size(); ++i) { + ash::IMEPropertyInfo property; + property.key = menu_list[i].key; + property.name = base::UTF8ToUTF16(menu_list[i].label); + property.selected = menu_list[i].is_selection_item_checked; + properties.push_back(property); + } + return properties; +} + +std::vector<ash::IMEInfo> InputMethodManagerImpl::GetAvailableImes() const { + if (!state_) + return std::vector<ash::IMEInfo>(); + + std::vector<ash::IMEInfo> imes; + std::string current_ime_id = state_->GetCurrentInputMethod().id(); + std::unique_ptr<InputMethodDescriptors> descriptors = + state_->GetActiveInputMethods(); + for (const InputMethodDescriptor& descriptor : *descriptors) { + ash::IMEInfo info = GetAshImeInfo(descriptor, util_); + info.selected = descriptor.id() == current_ime_id; + imes.push_back(info); + } + return imes; +} + +bool InputMethodManagerImpl::IsImeManaged() const { + if (!state_) + return false; + + // Having a non-empty "allowed" list indicates that IMEs are managed. + return !state_->GetAllowedInputMethods().empty(); +} + } // namespace input_method } // namespace chromeos
diff --git a/chrome/browser/chromeos/input_method/input_method_manager_impl.h b/chrome/browser/chromeos/input_method/input_method_manager_impl.h index dfd8fdc4..a3ba164 100644 --- a/chrome/browser/chromeos/input_method/input_method_manager_impl.h +++ b/chrome/browser/chromeos/input_method/input_method_manager_impl.h
@@ -12,6 +12,7 @@ #include <string> #include <vector> +#include "ash/ime/ime_controller.h" #include "base/macros.h" #include "base/observer_list.h" #include "base/threading/thread_checker.h" @@ -35,7 +36,9 @@ class ImeKeyboard; // The implementation of InputMethodManager. +// TODO(jamescook): Replace ash::ImeController with mojo interface. class InputMethodManagerImpl : public InputMethodManager, + public ash::ImeController, public CandidateWindowController::Observer, public UserAddingScreen::Observer { public: @@ -164,6 +167,8 @@ bool enable_extension_loading); ~InputMethodManagerImpl() override; + static InputMethodManagerImpl* Get(); + // Receives notification of an InputMethodManager::UISessionState transition. void SetUISessionState(UISessionState new_ui_session); @@ -191,6 +196,12 @@ void OverrideKeyboardUrlRef(const std::string& keyset) override; bool IsEmojiHandwritingVoiceOnImeMenuEnabled() override; + // ash::ImeController: + ash::IMEInfo GetCurrentIme() const override; + std::vector<ash::IMEPropertyInfo> GetCurrentImeProperties() const override; + std::vector<ash::IMEInfo> GetAvailableImes() const override; + bool IsImeManaged() const override; + // chromeos::UserAddingScreen: void OnUserAddingStarted() override; void OnUserAddingFinished() override;
diff --git a/chrome/browser/chromeos/note_taking_helper_unittest.cc b/chrome/browser/chromeos/note_taking_helper_unittest.cc index 50434e7..a13c584c 100644 --- a/chrome/browser/chromeos/note_taking_helper_unittest.cc +++ b/chrome/browser/chromeos/note_taking_helper_unittest.cc
@@ -139,7 +139,7 @@ void SetUp() override { if (GetParam()) - arc::SetArcAlwaysStartForTesting(); + arc::SetArcAlwaysStartForTesting(true); // This is needed to avoid log spam due to ArcSessionManager's // RemoveArcData() calls failing.
diff --git a/chrome/browser/chromeos/system/fake_input_device_settings.cc b/chrome/browser/chromeos/system/fake_input_device_settings.cc index 6638773..e8cd17b6 100644 --- a/chrome/browser/chromeos/system/fake_input_device_settings.cc +++ b/chrome/browser/chromeos/system/fake_input_device_settings.cc
@@ -4,6 +4,10 @@ #include "chrome/browser/chromeos/system/fake_input_device_settings.h" +#include <utility> + +#include "base/callback.h" + namespace chromeos { namespace system { @@ -12,9 +16,8 @@ FakeInputDeviceSettings::~FakeInputDeviceSettings() {} // Overriden from InputDeviceSettings. -void FakeInputDeviceSettings::TouchpadExists( - const DeviceExistsCallback& callback) { - callback.Run(touchpad_exists_); +void FakeInputDeviceSettings::TouchpadExists(DeviceExistsCallback callback) { + std::move(callback).Run(touchpad_exists_); } void FakeInputDeviceSettings::UpdateTouchpadSettings( @@ -52,9 +55,8 @@ UpdateTouchpadSettings(settings); } -void FakeInputDeviceSettings::MouseExists( - const DeviceExistsCallback& callback) { - callback.Run(mouse_exists_); +void FakeInputDeviceSettings::MouseExists(DeviceExistsCallback callback) { + std::move(callback).Run(mouse_exists_); } void FakeInputDeviceSettings::UpdateMouseSettings(
diff --git a/chrome/browser/chromeos/system/fake_input_device_settings.h b/chrome/browser/chromeos/system/fake_input_device_settings.h index 3da56e8..1f0568d 100644 --- a/chrome/browser/chromeos/system/fake_input_device_settings.h +++ b/chrome/browser/chromeos/system/fake_input_device_settings.h
@@ -20,13 +20,13 @@ ~FakeInputDeviceSettings() override; // Overridden from InputDeviceSettings. - void TouchpadExists(const DeviceExistsCallback& callback) override; + void TouchpadExists(DeviceExistsCallback callback) override; void UpdateTouchpadSettings(const TouchpadSettings& settings) override; void SetTouchpadSensitivity(int value) override; void SetTapToClick(bool enabled) override; void SetThreeFingerClick(bool enabled) override; void SetTapDragging(bool enabled) override; - void MouseExists(const DeviceExistsCallback& callback) override; + void MouseExists(DeviceExistsCallback callback) override; void UpdateMouseSettings(const MouseSettings& settings) override; void SetMouseSensitivity(int value) override; void SetPrimaryButtonRight(bool right) override;
diff --git a/chrome/browser/chromeos/system/input_device_settings.h b/chrome/browser/chromeos/system/input_device_settings.h index 430d738..9f0b63b 100644 --- a/chrome/browser/chromeos/system/input_device_settings.h +++ b/chrome/browser/chromeos/system/input_device_settings.h
@@ -5,7 +5,7 @@ #ifndef CHROME_BROWSER_CHROMEOS_SYSTEM_INPUT_DEVICE_SETTINGS_H_ #define CHROME_BROWSER_CHROMEOS_SYSTEM_INPUT_DEVICE_SETTINGS_H_ -#include "base/callback.h" +#include "base/callback_forward.h" #include "base/optional.h" #include "chromeos/chromeos_export.h" @@ -104,7 +104,7 @@ // Interface for configuring input device settings. class CHROMEOS_EXPORT InputDeviceSettings { public: - typedef base::Callback<void(bool)> DeviceExistsCallback; + using DeviceExistsCallback = base::OnceCallback<void(bool)>; // Interface for faking touchpad and mouse. Accessed through // GetFakeInterface(), implemented only in FakeInputDeviceSettings. @@ -152,7 +152,7 @@ // Calls |callback|, possibly asynchronously, after determining if a touchpad // is connected. - virtual void TouchpadExists(const DeviceExistsCallback& callback) = 0; + virtual void TouchpadExists(DeviceExistsCallback callback) = 0; // Updates several touchpad settings at a time. Updates only settings that // are set in |settings| object. It is more efficient to use this method to @@ -177,7 +177,7 @@ // Calls |callback|, possibly asynchronously, after determining if a mouse is // connected. - virtual void MouseExists(const DeviceExistsCallback& callback) = 0; + virtual void MouseExists(DeviceExistsCallback callback) = 0; // Updates several mouse settings at a time. Updates only settings that // are set in |settings| object. It is more efficient to use this method to
diff --git a/chrome/browser/chromeos/system/input_device_settings_impl_ozone.cc b/chrome/browser/chromeos/system/input_device_settings_impl_ozone.cc index 412b742..98a97cbd 100644 --- a/chrome/browser/chromeos/system/input_device_settings_impl_ozone.cc +++ b/chrome/browser/chromeos/system/input_device_settings_impl_ozone.cc
@@ -5,25 +5,21 @@ #include "chrome/browser/chromeos/system/input_device_settings.h" #include "base/macros.h" +#include "chrome/browser/browser_process.h" +#include "chrome/browser/browser_process_platform_part_chromeos.h" #include "chrome/browser/chromeos/system/fake_input_device_settings.h" #include "chromeos/system/devicemode.h" #include "content/public/browser/browser_thread.h" -#include "services/service_manager/runner/common/client_util.h" -#include "ui/ozone/public/input_controller.h" -#include "ui/ozone/public/ozone_platform.h" +#include "services/ui/public/cpp/input_devices/input_device_controller_client.h" namespace chromeos { namespace system { - namespace { InputDeviceSettings* g_instance = nullptr; -std::unique_ptr<ui::InputController> CreateStubInputControllerIfNecessary() { - return service_manager::ServiceManagerIsRemote() - ? ui::CreateStubInputController() - : nullptr; -} +// Callback from SetInternalTouchpadEnabled(). +void OnSetInternalTouchpadEnabled(bool result) {} // InputDeviceSettings for Linux without X11 (a.k.a. Ozone). class InputDeviceSettingsImplOzone : public InputDeviceSettings { @@ -35,14 +31,14 @@ private: // Overridden from InputDeviceSettings. - void TouchpadExists(const DeviceExistsCallback& callback) override; + void TouchpadExists(DeviceExistsCallback callback) override; void UpdateTouchpadSettings(const TouchpadSettings& settings) override; void SetTouchpadSensitivity(int value) override; void SetTapToClick(bool enabled) override; void SetThreeFingerClick(bool enabled) override; void SetTapDragging(bool enabled) override; void SetNaturalScroll(bool enabled) override; - void MouseExists(const DeviceExistsCallback& callback) override; + void MouseExists(DeviceExistsCallback callback) override; void UpdateMouseSettings(const MouseSettings& settings) override; void SetMouseSensitivity(int value) override; void SetPrimaryButtonRight(bool right) override; @@ -52,13 +48,8 @@ void SetInternalTouchpadEnabled(bool enabled) override; void SetTouchscreensEnabled(bool enabled) override; - // TODO(sad): A stub input controller is used when running inside mus. - // http://crbug.com/601981 - std::unique_ptr<ui::InputController> stub_controller_; - - // Cached InputController pointer. It should be fixed throughout the browser - // session. - ui::InputController* input_controller_; + // Cached InputDeviceControllerClient. It is owned by BrowserProcess. + ui::InputDeviceControllerClient* input_device_controller_client_; // Respective device setting objects. TouchpadSettings current_touchpad_settings_; @@ -68,19 +59,16 @@ }; InputDeviceSettingsImplOzone::InputDeviceSettingsImplOzone() - : stub_controller_(CreateStubInputControllerIfNecessary()), - input_controller_( - stub_controller_ - ? stub_controller_.get() - : ui::OzonePlatform::GetInstance()->GetInputController()) { + : input_device_controller_client_(g_browser_process->platform_part() + ->GetInputDeviceControllerClient()) { // Make sure the input controller does exist. - DCHECK(input_controller_); + DCHECK(input_device_controller_client_); } void InputDeviceSettingsImplOzone::TouchpadExists( - const DeviceExistsCallback& callback) { + DeviceExistsCallback callback) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - callback.Run(input_controller_->HasTouchpad()); + input_device_controller_client_->GetHasTouchpad(std::move(callback)); } void InputDeviceSettingsImplOzone::UpdateTouchpadSettings( @@ -92,34 +80,33 @@ void InputDeviceSettingsImplOzone::SetTouchpadSensitivity(int value) { DCHECK(value >= kMinPointerSensitivity && value <= kMaxPointerSensitivity); current_touchpad_settings_.SetSensitivity(value); - input_controller_->SetTouchpadSensitivity(value); + input_device_controller_client_->SetTouchpadSensitivity(value); } void InputDeviceSettingsImplOzone::SetNaturalScroll(bool enabled) { current_touchpad_settings_.SetNaturalScroll(enabled); - input_controller_->SetNaturalScroll(enabled); + input_device_controller_client_->SetNaturalScroll(enabled); } void InputDeviceSettingsImplOzone::SetTapToClick(bool enabled) { current_touchpad_settings_.SetTapToClick(enabled); - input_controller_->SetTapToClick(enabled); + input_device_controller_client_->SetTapToClick(enabled); } void InputDeviceSettingsImplOzone::SetThreeFingerClick(bool enabled) { // For Alex/ZGB. current_touchpad_settings_.SetThreeFingerClick(enabled); - input_controller_->SetThreeFingerClick(enabled); + input_device_controller_client_->SetThreeFingerClick(enabled); } void InputDeviceSettingsImplOzone::SetTapDragging(bool enabled) { current_touchpad_settings_.SetTapDragging(enabled); - input_controller_->SetTapDragging(enabled); + input_device_controller_client_->SetTapDragging(enabled); } -void InputDeviceSettingsImplOzone::MouseExists( - const DeviceExistsCallback& callback) { +void InputDeviceSettingsImplOzone::MouseExists(DeviceExistsCallback callback) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - callback.Run(input_controller_->HasMouse()); + input_device_controller_client_->GetHasMouse(std::move(callback)); } void InputDeviceSettingsImplOzone::UpdateMouseSettings( @@ -131,12 +118,12 @@ void InputDeviceSettingsImplOzone::SetMouseSensitivity(int value) { DCHECK(value >= kMinPointerSensitivity && value <= kMaxPointerSensitivity); current_mouse_settings_.SetSensitivity(value); - input_controller_->SetMouseSensitivity(value); + input_device_controller_client_->SetMouseSensitivity(value); } void InputDeviceSettingsImplOzone::SetPrimaryButtonRight(bool right) { current_mouse_settings_.SetPrimaryButtonRight(right); - input_controller_->SetPrimaryButtonRight(right); + input_device_controller_client_->SetPrimaryButtonRight(right); } void InputDeviceSettingsImplOzone::ReapplyTouchpadSettings() { @@ -153,11 +140,12 @@ } void InputDeviceSettingsImplOzone::SetInternalTouchpadEnabled(bool enabled) { - input_controller_->SetInternalTouchpadEnabled(enabled); + input_device_controller_client_->SetInternalTouchpadEnabled( + enabled, base::BindOnce(&OnSetInternalTouchpadEnabled)); } void InputDeviceSettingsImplOzone::SetTouchscreensEnabled(bool enabled) { - input_controller_->SetTouchscreensEnabled(enabled); + input_device_controller_client_->SetTouchscreensEnabled(enabled); } } // namespace
diff --git a/chrome/browser/chromeos/system/input_device_settings_impl_x11.cc b/chrome/browser/chromeos/system/input_device_settings_impl_x11.cc index 99e1a394..59a83f8 100644 --- a/chrome/browser/chromeos/system/input_device_settings_impl_x11.cc +++ b/chrome/browser/chromeos/system/input_device_settings_impl_x11.cc
@@ -8,6 +8,7 @@ #include <vector> #include "base/bind.h" +#include "base/callback.h" #include "base/command_line.h" #include "base/files/file_path.h" #include "base/files/file_util.h" @@ -122,16 +123,15 @@ DVLOG(1) << "DeviceExistsBlockingPool:" << device_type << "=" << exists->data; } -void RunCallbackUIThread( - scoped_refptr<RefCountedBool> exists, - const InputDeviceSettings::DeviceExistsCallback& callback) { +void RunCallbackUIThread(scoped_refptr<RefCountedBool> exists, + InputDeviceSettings::DeviceExistsCallback callback) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); DVLOG(1) << "RunCallbackUIThread " << exists->data; - callback.Run(exists->data); + std::move(callback).Run(exists->data); } void DeviceExists(const char* script, - const InputDeviceSettings::DeviceExistsCallback& callback) { + InputDeviceSettings::DeviceExistsCallback callback) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); // One or both of the control scripts can apparently hang during shutdown @@ -144,7 +144,7 @@ base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN); runner->PostTaskAndReply( FROM_HERE, base::Bind(&DeviceExistsBlockingPool, script, exists), - base::Bind(&RunCallbackUIThread, exists, callback)); + base::BindOnce(&RunCallbackUIThread, exists, std::move(callback))); } // InputDeviceSettings for Linux with X11. @@ -157,14 +157,14 @@ private: // Overridden from InputDeviceSettings. - void TouchpadExists(const DeviceExistsCallback& callback) override; + void TouchpadExists(DeviceExistsCallback callback) override; void UpdateTouchpadSettings(const TouchpadSettings& settings) override; void SetTouchpadSensitivity(int value) override; void SetTapToClick(bool enabled) override; void SetThreeFingerClick(bool enabled) override; void SetTapDragging(bool enabled) override; void SetNaturalScroll(bool enabled) override; - void MouseExists(const DeviceExistsCallback& callback) override; + void MouseExists(DeviceExistsCallback callback) override; void UpdateMouseSettings(const MouseSettings& settings) override; void SetMouseSensitivity(int value) override; void SetPrimaryButtonRight(bool right) override; @@ -190,9 +190,8 @@ InputDeviceSettingsImplX11::InputDeviceSettingsImplX11() { } -void InputDeviceSettingsImplX11::TouchpadExists( - const DeviceExistsCallback& callback) { - DeviceExists(kDeviceTypeTouchpad, callback); +void InputDeviceSettingsImplX11::TouchpadExists(DeviceExistsCallback callback) { + DeviceExists(kDeviceTypeTouchpad, std::move(callback)); } void InputDeviceSettingsImplX11::UpdateTouchpadSettings( @@ -235,10 +234,9 @@ UpdateTouchpadSettings(settings); } -void InputDeviceSettingsImplX11::MouseExists( - const DeviceExistsCallback& callback) { +void InputDeviceSettingsImplX11::MouseExists(DeviceExistsCallback callback) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - DeviceExists(kDeviceTypeMouse, callback); + DeviceExists(kDeviceTypeMouse, std::move(callback)); } void InputDeviceSettingsImplX11::UpdateMouseSettings(
diff --git a/chrome/browser/devtools/devtools_file_helper.cc b/chrome/browser/devtools/devtools_file_helper.cc index 28599b7b..463cedea 100644 --- a/chrome/browser/devtools/devtools_file_helper.cc +++ b/chrome/browser/devtools/devtools_file_helper.cc
@@ -212,12 +212,6 @@ delegate_(delegate), weak_factory_(this) { pref_change_registrar_.Init(profile_->GetPrefs()); - pref_change_registrar_.Add(prefs::kDevToolsFileSystemPaths, - base::Bind(&DevToolsFileHelper::FileSystemPathsSettingChanged, - base::Unretained(this))); - file_watcher_.reset(new DevToolsFileWatcher( - base::Bind(&DevToolsFileHelper::FilePathsChanged, - weak_factory_.GetWeakPtr()))); } DevToolsFileHelper::~DevToolsFileHelper() { @@ -392,6 +386,14 @@ DevToolsFileHelper::GetFileSystems() { file_system_paths_ = GetAddedFileSystemPaths(profile_); std::vector<FileSystem> file_systems; + if (!file_watcher_) { + file_watcher_.reset(new DevToolsFileWatcher(base::Bind( + &DevToolsFileHelper::FilePathsChanged, weak_factory_.GetWeakPtr()))); + pref_change_registrar_.Add( + prefs::kDevToolsFileSystemPaths, + base::Bind(&DevToolsFileHelper::FileSystemPathsSettingChanged, + base::Unretained(this))); + } for (auto file_system_path : file_system_paths_) { base::FilePath path = base::FilePath::FromUTF8Unsafe(file_system_path); std::string file_system_id = RegisterFileSystem(web_contents_, path); @@ -428,6 +430,7 @@ void DevToolsFileHelper::FileSystemPathsSettingChanged() { std::set<std::string> remaining; remaining.swap(file_system_paths_); + DCHECK(file_watcher_.get()); for (auto file_system_path : GetAddedFileSystemPaths(profile_)) { if (remaining.find(file_system_path) == remaining.end()) {
diff --git a/chrome/browser/devtools/devtools_ui_bindings.cc b/chrome/browser/devtools/devtools_ui_bindings.cc index cbdff1523..55158c2 100644 --- a/chrome/browser/devtools/devtools_ui_bindings.cc +++ b/chrome/browser/devtools/devtools_ui_bindings.cc
@@ -1354,6 +1354,8 @@ void DevToolsUIBindings::Reload() { reloading_ = true; + if (agent_host_) + agent_host_->DetachClient(this); web_contents_->GetController().Reload(content::ReloadType::NORMAL, false); } @@ -1397,10 +1399,8 @@ if (!reloading_) return; reloading_ = false; - if (agent_host_.get()) { - agent_host_->DetachClient(this); + if (agent_host_.get()) agent_host_->AttachClient(this); - } } void DevToolsUIBindings::DocumentOnLoadCompletedInMainFrame() {
diff --git a/chrome/browser/extensions/api/font_settings/font_settings_api.cc b/chrome/browser/extensions/api/font_settings/font_settings_api.cc index 31f9f9d..3f56296 100644 --- a/chrome/browser/extensions/api/font_settings/font_settings_api.cc +++ b/chrome/browser/extensions/api/font_settings/font_settings_api.cc
@@ -27,7 +27,7 @@ #include "chrome/browser/extensions/api/preference/preference_helpers.h" #include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/profiles/profile.h" -#include "chrome/browser/ui/webui/options/font_settings_utils.h" +#include "chrome/browser/ui/webui/settings_utils.h" #include "chrome/common/extensions/api/font_settings.h" #include "chrome/common/pref_names.h" #include "chrome/common/pref_names_util.h" @@ -41,7 +41,6 @@ namespace extensions { namespace fonts = api::font_settings; -using options::FontSettingsUtilities; namespace { @@ -161,7 +160,7 @@ NOTREACHED(); return; } - font_name = FontSettingsUtilities::MaybeGetLocalizedFontName(font_name); + font_name = settings_utils::MaybeGetLocalizedFontName(font_name); base::ListValue args; std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); @@ -247,7 +246,7 @@ std::string font_name; EXTENSION_FUNCTION_VALIDATE( pref && pref->GetValue()->GetAsString(&font_name)); - font_name = FontSettingsUtilities::MaybeGetLocalizedFontName(font_name); + font_name = settings_utils::MaybeGetLocalizedFontName(font_name); // We don't support incognito-specific font prefs, so don't consider them when // getting level of control.
diff --git a/chrome/browser/net/chrome_mojo_proxy_resolver_factory.cc b/chrome/browser/net/chrome_mojo_proxy_resolver_factory.cc new file mode 100644 index 0000000..3ed6244 --- /dev/null +++ b/chrome/browser/net/chrome_mojo_proxy_resolver_factory.cc
@@ -0,0 +1,133 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/net/chrome_mojo_proxy_resolver_factory.h" + +#include <utility> + +#include "base/logging.h" +#include "base/memory/ptr_util.h" +#include "base/memory/singleton.h" +#include "base/single_thread_task_runner.h" +#include "base/threading/thread_task_runner_handle.h" +#include "content/public/browser/browser_thread.h" + +#if !defined(OS_ANDROID) +#include "chrome/grit/generated_resources.h" +#include "content/public/browser/utility_process_host.h" +#include "content/public/browser/utility_process_host_client.h" +#include "services/service_manager/public/cpp/interface_provider.h" +#include "ui/base/l10n/l10n_util.h" +#else // defined(OS_ANDROID) +#include "mojo/public/cpp/bindings/strong_binding.h" +#include "net/proxy/mojo_proxy_resolver_factory_impl.h" +#endif // !defined(OS_ANDROID) + +namespace { +const int kUtilityProcessIdleTimeoutSeconds = 5; +} + +// static +ChromeMojoProxyResolverFactory* ChromeMojoProxyResolverFactory::GetInstance() { + DCHECK_CURRENTLY_ON(content::BrowserThread::IO); + return base::Singleton< + ChromeMojoProxyResolverFactory, + base::LeakySingletonTraits<ChromeMojoProxyResolverFactory>>::get(); +} + +ChromeMojoProxyResolverFactory::ChromeMojoProxyResolverFactory() { + DCHECK_CURRENTLY_ON(content::BrowserThread::IO); +} + +ChromeMojoProxyResolverFactory::~ChromeMojoProxyResolverFactory() { + DCHECK(thread_checker_.CalledOnValidThread()); +} + +std::unique_ptr<base::ScopedClosureRunner> +ChromeMojoProxyResolverFactory::CreateResolver( + const std::string& pac_script, + mojo::InterfaceRequest<net::interfaces::ProxyResolver> req, + net::interfaces::ProxyResolverFactoryRequestClientPtr client) { + DCHECK(thread_checker_.CalledOnValidThread()); + if (!resolver_factory_) + CreateFactory(); + + if (!resolver_factory_) { + // If factory creation failed, close |req|'s message pipe, which should + // cause a connection error. + req = nullptr; + return nullptr; + } + idle_timer_.Stop(); + num_proxy_resolvers_++; + resolver_factory_->CreateResolver(pac_script, std::move(req), + std::move(client)); + return base::MakeUnique<base::ScopedClosureRunner>( + base::Bind(&ChromeMojoProxyResolverFactory::OnResolverDestroyed, + base::Unretained(this))); +} + +void ChromeMojoProxyResolverFactory::CreateFactory() { + DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK(!resolver_factory_); + +#if defined(OS_ANDROID) + mojo::MakeStrongBinding(base::MakeUnique<net::MojoProxyResolverFactoryImpl>(), + mojo::MakeRequest(&resolver_factory_)); +#else // !defined(OS_ANDROID) + DCHECK(!weak_utility_process_host_); + + DVLOG(1) << "Attempting to create utility process for proxy resolver"; + content::UtilityProcessHost* utility_process_host = + content::UtilityProcessHost::Create( + scoped_refptr<content::UtilityProcessHostClient>(), + base::ThreadTaskRunnerHandle::Get()); + utility_process_host->SetName( + l10n_util::GetStringUTF16(IDS_UTILITY_PROCESS_PROXY_RESOLVER_NAME)); + bool process_started = utility_process_host->Start(); + if (process_started) { + BindInterface(utility_process_host, &resolver_factory_); + weak_utility_process_host_ = utility_process_host->AsWeakPtr(); + } else { + LOG(ERROR) << "Unable to connect to utility process"; + return; + } +#endif // defined(OS_ANDROID) + + resolver_factory_.set_connection_error_handler(base::Bind( + &ChromeMojoProxyResolverFactory::DestroyFactory, base::Unretained(this))); +} + +void ChromeMojoProxyResolverFactory::DestroyFactory() { + resolver_factory_.reset(); +#if !defined(OS_ANDROID) + delete weak_utility_process_host_.get(); + weak_utility_process_host_.reset(); +#endif +} + +void ChromeMojoProxyResolverFactory::OnResolverDestroyed() { + DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_GT(num_proxy_resolvers_, 0u); + if (--num_proxy_resolvers_ == 0) { + // When all proxy resolvers have been destroyed, the proxy resolver factory + // is no longer needed. However, new proxy resolvers may be created + // shortly after being destroyed (e.g. due to a network change). + // + // On desktop, where a utility process is used, if the utility process is + // shut down immediately, this would cause unnecessary process churn, so + // wait for an idle timeout before shutting down the proxy resolver utility + // process. + idle_timer_.Start( + FROM_HERE, + base::TimeDelta::FromSeconds(kUtilityProcessIdleTimeoutSeconds), this, + &ChromeMojoProxyResolverFactory::OnIdleTimeout); + } +} + +void ChromeMojoProxyResolverFactory::OnIdleTimeout() { + DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_EQ(num_proxy_resolvers_, 0u); + DestroyFactory(); +}
diff --git a/chrome/browser/net/chrome_mojo_proxy_resolver_factory.h b/chrome/browser/net/chrome_mojo_proxy_resolver_factory.h new file mode 100644 index 0000000..610b146 --- /dev/null +++ b/chrome/browser/net/chrome_mojo_proxy_resolver_factory.h
@@ -0,0 +1,76 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_NET_CHROME_MOJO_PROXY_RESOLVER_FACTORY_H_ +#define CHROME_BROWSER_NET_CHROME_MOJO_PROXY_RESOLVER_FACTORY_H_ + +#include <stddef.h> + +#include "base/macros.h" +#include "base/memory/weak_ptr.h" +#include "base/threading/thread_checker.h" +#include "base/timer/timer.h" +#include "net/proxy/mojo_proxy_resolver_factory.h" + +#if !defined(OS_ANDROID) +namespace content { +class UtilityProcessHost; +} +#endif + +namespace base { +template <typename Type> +struct DefaultSingletonTraits; +} // namespace base + +// A factory used to create connections to Mojo proxy resolver services. On +// Android, the proxy resolvers will run in the browser process, and on other +// platforms, they'll all be run in the same utility process. Utility process +// crashes are detected and the utility process is automatically restarted. +class ChromeMojoProxyResolverFactory : public net::MojoProxyResolverFactory { + public: + static ChromeMojoProxyResolverFactory* GetInstance(); + + // Overridden from net::MojoProxyResolverFactory: + std::unique_ptr<base::ScopedClosureRunner> CreateResolver( + const std::string& pac_script, + mojo::InterfaceRequest<net::interfaces::ProxyResolver> req, + net::interfaces::ProxyResolverFactoryRequestClientPtr client) override; + + private: + friend struct base::DefaultSingletonTraits<ChromeMojoProxyResolverFactory>; + ChromeMojoProxyResolverFactory(); + ~ChromeMojoProxyResolverFactory() override; + + // Creates the proxy resolver factory. On desktop, creates a new utility + // process before creating it out of process. On Android, creates it on the + // current thread. + void CreateFactory(); + + // Destroys |resolver_factory_|. + void DestroyFactory(); + + // Invoked each time a proxy resolver is destroyed. + void OnResolverDestroyed(); + + // Invoked once an idle timeout has elapsed after all proxy resolvers are + // destroyed. + void OnIdleTimeout(); + + net::interfaces::ProxyResolverFactoryPtr resolver_factory_; + +#if !defined(OS_ANDROID) + base::WeakPtr<content::UtilityProcessHost> weak_utility_process_host_; +#endif + + size_t num_proxy_resolvers_ = 0; + + base::OneShotTimer idle_timer_; + + base::ThreadChecker thread_checker_; + + DISALLOW_COPY_AND_ASSIGN(ChromeMojoProxyResolverFactory); +}; + +#endif // CHROME_BROWSER_NET_CHROME_MOJO_PROXY_RESOLVER_FACTORY_H_
diff --git a/chrome/browser/net/proxy_service_factory.cc b/chrome/browser/net/proxy_service_factory.cc index c08f382..dcb7c5c 100644 --- a/chrome/browser/net/proxy_service_factory.cc +++ b/chrome/browser/net/proxy_service_factory.cc
@@ -15,16 +15,16 @@ #include "build/build_config.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/io_thread.h" +#include "chrome/browser/net/chrome_mojo_proxy_resolver_factory.h" #include "chrome/common/chrome_switches.h" #include "components/proxy_config/pref_proxy_config_tracker_impl.h" #include "content/public/browser/browser_thread.h" #include "content/public/common/content_switches.h" #include "net/proxy/dhcp_proxy_script_fetcher_factory.h" #include "net/proxy/proxy_config_service.h" -#include "net/proxy/proxy_resolver_v8.h" #include "net/proxy/proxy_script_fetcher_impl.h" #include "net/proxy/proxy_service.h" -#include "net/proxy/proxy_service_v8.h" +#include "net/proxy/proxy_service_mojo.h" #include "net/url_request/url_request_context.h" #if defined(OS_CHROMEOS) @@ -32,11 +32,6 @@ #include "chromeos/network/proxy/proxy_config_service_impl.h" #endif // defined(OS_CHROMEOS) -#if !defined(OS_ANDROID) -#include "chrome/browser/net/utility_process_mojo_proxy_resolver_factory.h" -#include "net/proxy/proxy_service_mojo.h" -#endif - using content::BrowserThread; // static @@ -128,20 +123,12 @@ dhcp_proxy_script_fetcher = dhcp_factory.Create(context); #endif -#if !defined(OS_ANDROID) proxy_service = net::CreateProxyServiceUsingMojoFactory( - UtilityProcessMojoProxyResolverFactory::GetInstance(), + ChromeMojoProxyResolverFactory::GetInstance(), std::move(proxy_config_service), new net::ProxyScriptFetcherImpl(context), std::move(dhcp_proxy_script_fetcher), context->host_resolver(), net_log, network_delegate); -#else - proxy_service = net::CreateProxyServiceUsingV8ProxyResolver( - std::move(proxy_config_service), - new net::ProxyScriptFetcherImpl(context), - std::move(dhcp_proxy_script_fetcher), context->host_resolver(), net_log, - network_delegate); -#endif // !defined(OS_ANDROID) } else { proxy_service = net::ProxyService::CreateUsingSystemProxyResolver( std::move(proxy_config_service), net_log);
diff --git a/chrome/browser/net/utility_process_mojo_proxy_resolver_factory.cc b/chrome/browser/net/utility_process_mojo_proxy_resolver_factory.cc deleted file mode 100644 index 4a88a57..0000000 --- a/chrome/browser/net/utility_process_mojo_proxy_resolver_factory.cc +++ /dev/null
@@ -1,121 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/net/utility_process_mojo_proxy_resolver_factory.h" - -#include <utility> - -#include "base/logging.h" -#include "base/memory/ptr_util.h" -#include "base/memory/singleton.h" -#include "base/single_thread_task_runner.h" -#include "base/threading/thread_task_runner_handle.h" -#include "chrome/grit/generated_resources.h" -#include "content/public/browser/browser_thread.h" -#include "content/public/browser/utility_process_host.h" -#include "content/public/browser/utility_process_host_client.h" -#include "services/service_manager/public/cpp/interface_provider.h" -#include "ui/base/l10n/l10n_util.h" - -namespace { -const int kUtilityProcessIdleTimeoutSeconds = 5; -} - -// static -UtilityProcessMojoProxyResolverFactory* -UtilityProcessMojoProxyResolverFactory::GetInstance() { - DCHECK_CURRENTLY_ON(content::BrowserThread::IO); - return base::Singleton<UtilityProcessMojoProxyResolverFactory, - base::LeakySingletonTraits< - UtilityProcessMojoProxyResolverFactory>>::get(); -} - -UtilityProcessMojoProxyResolverFactory:: - UtilityProcessMojoProxyResolverFactory() { - DCHECK_CURRENTLY_ON(content::BrowserThread::IO); -} - -UtilityProcessMojoProxyResolverFactory:: - ~UtilityProcessMojoProxyResolverFactory() { - DCHECK(thread_checker_.CalledOnValidThread()); -} - -void UtilityProcessMojoProxyResolverFactory::CreateProcessAndConnect() { - DCHECK(thread_checker_.CalledOnValidThread()); - DCHECK(!resolver_factory_); - DCHECK(!weak_utility_process_host_); - DVLOG(1) << "Attempting to create utility process for proxy resolver"; - content::UtilityProcessHost* utility_process_host = - content::UtilityProcessHost::Create( - scoped_refptr<content::UtilityProcessHostClient>(), - base::ThreadTaskRunnerHandle::Get()); - utility_process_host->SetName(l10n_util::GetStringUTF16( - IDS_UTILITY_PROCESS_PROXY_RESOLVER_NAME)); - bool process_started = utility_process_host->Start(); - if (process_started) { - BindInterface(utility_process_host, &resolver_factory_); - resolver_factory_.set_connection_error_handler( - base::Bind(&UtilityProcessMojoProxyResolverFactory::OnConnectionError, - base::Unretained(this))); - weak_utility_process_host_ = utility_process_host->AsWeakPtr(); - } else { - LOG(ERROR) << "Unable to connect to utility process"; - } -} - -std::unique_ptr<base::ScopedClosureRunner> -UtilityProcessMojoProxyResolverFactory::CreateResolver( - const std::string& pac_script, - mojo::InterfaceRequest<net::interfaces::ProxyResolver> req, - net::interfaces::ProxyResolverFactoryRequestClientPtr client) { - DCHECK(thread_checker_.CalledOnValidThread()); - if (!resolver_factory_) - CreateProcessAndConnect(); - - if (!resolver_factory_) { - // If there's still no factory, then utility process creation failed so - // close |req|'s message pipe, which should cause a connection error. - req = nullptr; - return nullptr; - } - idle_timer_.Stop(); - num_proxy_resolvers_++; - resolver_factory_->CreateResolver(pac_script, std::move(req), - std::move(client)); - return base::MakeUnique<base::ScopedClosureRunner>( - base::Bind(&UtilityProcessMojoProxyResolverFactory::OnResolverDestroyed, - base::Unretained(this))); -} - -void UtilityProcessMojoProxyResolverFactory::OnConnectionError() { - DVLOG(1) << "Disconnection from utility process detected"; - resolver_factory_.reset(); - delete weak_utility_process_host_.get(); - weak_utility_process_host_.reset(); -} - -void UtilityProcessMojoProxyResolverFactory::OnResolverDestroyed() { - DCHECK(thread_checker_.CalledOnValidThread()); - DCHECK_GT(num_proxy_resolvers_, 0u); - if (--num_proxy_resolvers_ == 0) { - // When all proxy resolvers have been destroyed, the proxy resolver utility - // process is no longer needed. However, new proxy resolvers may be created - // shortly after being destroyed (e.g. due to a network change). If the - // utility process is shut down immediately, this would cause unnecessary - // process churn, so wait for an idle timeout before shutting down the - // proxy resolver utility process. - idle_timer_.Start( - FROM_HERE, - base::TimeDelta::FromSeconds(kUtilityProcessIdleTimeoutSeconds), this, - &UtilityProcessMojoProxyResolverFactory::OnIdleTimeout); - } -} - -void UtilityProcessMojoProxyResolverFactory::OnIdleTimeout() { - DCHECK(thread_checker_.CalledOnValidThread()); - DCHECK_EQ(num_proxy_resolvers_, 0u); - delete weak_utility_process_host_.get(); - weak_utility_process_host_.reset(); - resolver_factory_.reset(); -}
diff --git a/chrome/browser/net/utility_process_mojo_proxy_resolver_factory.h b/chrome/browser/net/utility_process_mojo_proxy_resolver_factory.h deleted file mode 100644 index b39362372..0000000 --- a/chrome/browser/net/utility_process_mojo_proxy_resolver_factory.h +++ /dev/null
@@ -1,71 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_NET_UTILITY_PROCESS_MOJO_PROXY_RESOLVER_FACTORY_H_ -#define CHROME_BROWSER_NET_UTILITY_PROCESS_MOJO_PROXY_RESOLVER_FACTORY_H_ - -#include <stddef.h> - -#include "base/macros.h" -#include "base/memory/weak_ptr.h" -#include "base/threading/thread_checker.h" -#include "base/timer/timer.h" -#include "net/proxy/mojo_proxy_resolver_factory.h" - -namespace content { -class UtilityProcessHost; -} -namespace base { -template <typename Type> -struct DefaultSingletonTraits; -} // namespace base - -// A factory used to create connections to Mojo proxy resolver services run in a -// utility process. All Mojo proxy resolver services will be run in the same -// utility process. Utility process crashes are detected and the utility -// process is automatically restarted. -class UtilityProcessMojoProxyResolverFactory - : public net::MojoProxyResolverFactory { - public: - static UtilityProcessMojoProxyResolverFactory* GetInstance(); - - // Overridden from net::MojoProxyResolverFactory: - std::unique_ptr<base::ScopedClosureRunner> CreateResolver( - const std::string& pac_script, - mojo::InterfaceRequest<net::interfaces::ProxyResolver> req, - net::interfaces::ProxyResolverFactoryRequestClientPtr client) override; - - private: - friend struct base::DefaultSingletonTraits< - UtilityProcessMojoProxyResolverFactory>; - UtilityProcessMojoProxyResolverFactory(); - ~UtilityProcessMojoProxyResolverFactory() override; - - // Error handler callback for |resolver_factory_|. - void OnConnectionError(); - - // Invoked each time a proxy resolver is destroyed. - void OnResolverDestroyed(); - - // Invoked once an idle timeout has elapsed after all proxy resolvers are - // destroyed. - void OnIdleTimeout(); - - // Creates a new utility process and connects to its Mojo proxy resolver - // factory. - void CreateProcessAndConnect(); - - net::interfaces::ProxyResolverFactoryPtr resolver_factory_; - - base::WeakPtr<content::UtilityProcessHost> weak_utility_process_host_; - size_t num_proxy_resolvers_ = 0; - - base::OneShotTimer idle_timer_; - - base::ThreadChecker thread_checker_; - - DISALLOW_COPY_AND_ASSIGN(UtilityProcessMojoProxyResolverFactory); -}; - -#endif // CHROME_BROWSER_NET_UTILITY_PROCESS_MOJO_PROXY_RESOLVER_FACTORY_H_
diff --git a/chrome/browser/policy/policy_prefs_browsertest.cc b/chrome/browser/policy/policy_prefs_browsertest.cc index d7f2b93..4235de509 100644 --- a/chrome/browser/policy/policy_prefs_browsertest.cc +++ b/chrome/browser/policy/policy_prefs_browsertest.cc
@@ -32,6 +32,7 @@ #include "chrome/browser/search_engines/template_url_service_factory.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" +#include "chrome/common/url_constants.h" #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/search_test_utils.h" #include "chrome/test/base/ui_test_utils.h" @@ -58,8 +59,6 @@ namespace { -const char kMainSettingsPage[] = "chrome://settings-frame"; - const char kCrosSettingsPrefix[] = "cros."; std::string GetPolicyName(const std::string& policy_name_decorated) { @@ -375,6 +374,8 @@ DISALLOW_COPY_AND_ASSIGN(PolicyTestCases); }; +#if defined(OS_CHROMEOS) + // Returns a pseudo-random integer distributed in [0, range). int GetRandomNumber(int range) { return rand() % range; @@ -480,6 +481,8 @@ } } +#endif // defined(OS_CHROMEOS) + } // namespace typedef InProcessBrowserTest PolicyPrefsTestCoverageTest; @@ -604,6 +607,8 @@ public testing::WithParamInterface<std::vector<std::string> > { }; +#if defined(OS_CHROMEOS) + // Verifies that controlled setting indicators correctly show whether a pref's // value is recommended or enforced by a corresponding policy. IN_PROC_BROWSER_TEST_P(PolicyPrefIndicatorTest, CheckPolicyIndicators) { @@ -611,7 +616,8 @@ PrefService* local_state = g_browser_process->local_state(); PrefService* user_prefs = browser()->profile()->GetPrefs(); - ui_test_utils::NavigateToURL(browser(), GURL(kMainSettingsPage)); + ui_test_utils::NavigateToURL(browser(), + GURL(chrome::kChromeUISettingsFrameURL)); for (std::vector<std::string>::const_iterator policy = GetParam().begin(); policy != GetParam().end(); @@ -763,8 +769,10 @@ prefs->ClearPref(pref_mapping->pref().c_str()); } - if (!pref_mapping->indicator_test_url().empty()) - ui_test_utils::NavigateToURL(browser(), GURL(kMainSettingsPage)); + if (!pref_mapping->indicator_test_url().empty()) { + ui_test_utils::NavigateToURL(browser(), + GURL(chrome::kChromeUISettingsFrameURL)); + } } } } @@ -774,4 +782,6 @@ PolicyPrefIndicatorTest, testing::ValuesIn(SplitPoliciesIntoChunks(10))); +#endif // defined(OS_CHROMEOS) + } // namespace policy
diff --git a/chrome/browser/resources/BUILD.gn b/chrome/browser/resources/BUILD.gn index 16864c45..479e357f 100644 --- a/chrome/browser/resources/BUILD.gn +++ b/chrome/browser/resources/BUILD.gn
@@ -106,16 +106,6 @@ output_dir = "$root_gen_dir/chrome" } - grit("options_resources") { - source = "options_resources.grd" - defines = chrome_grit_defines - outputs = [ - "grit/options_resources.h", - "options_resources.pak", - ] - output_dir = "$root_gen_dir/chrome" - } - grit("settings_resources") { if (use_vulcanize) { source = "settings/settings_resources_vulcanized.grd" @@ -141,6 +131,18 @@ } } +if (is_chromeos) { + grit("options_resources") { + source = "options_resources.grd" + defines = chrome_grit_defines + outputs = [ + "grit/options_resources.h", + "options_resources.pak", + ] + output_dir = "$root_gen_dir/chrome" + } +} + if (enable_extensions) { grit("sync_file_system_internals_resources") { source = "sync_file_system_internals_resources.grd"
diff --git a/chrome/browser/resources/chromeos/login/oobe_buttons.html b/chrome/browser/resources/chromeos/login/oobe_buttons.html index 03487202..1272d9f 100644 --- a/chrome/browser/resources/chromeos/login/oobe_buttons.html +++ b/chrome/browser/resources/chromeos/login/oobe_buttons.html
@@ -6,7 +6,6 @@ <link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html"> <link rel="import" href="chrome://resources/polymer/v1_0/iron-iconset-svg/iron-iconset-svg.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html"> -<link rel="import" href="chrome://resources/polymer/v1_0/paper-fab/paper-fab.html"> <iron-iconset-svg name="oobe-buttons" size="24"> <svg>
diff --git a/chrome/browser/resources/md_extensions/manager.html b/chrome/browser/resources/md_extensions/manager.html index 0ad334b..237ed717 100644 --- a/chrome/browser/resources/md_extensions/manager.html +++ b/chrome/browser/resources/md_extensions/manager.html
@@ -48,6 +48,22 @@ overflow-y: auto; } + /* Neon-animated pages set the position of the content to be absolute, + * which is necessary for animations, but breaks sub-page layout. Apply a + * static position to the selected page. See + * https://github.com/PolymerElements/neon-animation/issues/101 for + * conversations. + * Note: Another proposed solution was + * neon-animated-pages .iron-selected:not(.neon-animating) { + * position: relative; + * } + * but the below appears to work fine, and is in line with what settings + * does. + */ + neon-animated-pages ::content > .iron-selected { + position: static; + } + extensions-item { display: inline-block; }
diff --git a/chrome/browser/resources/settings/focus_row_behavior.js b/chrome/browser/resources/settings/focus_row_behavior.js index 286c4eb6..0946758d 100644 --- a/chrome/browser/resources/settings/focus_row_behavior.js +++ b/chrome/browser/resources/settings/focus_row_behavior.js
@@ -14,12 +14,15 @@ FocusRowDelegate.prototype = { /** + * This function gets called when the [focus-row-control] element receives + * the focus event. * @override * @param {!cr.ui.FocusRow} row * @param {!Event} e */ onFocus: function(row, e) { this.listItem_.lastFocused = e.path[0]; + this.listItem_.tabIndex = -1; }, /** @@ -137,7 +140,10 @@ } }, - /** @private */ + /** + * This function gets called when the row itself receives the focus event. + * @private + */ onFocus_: function() { if (this.mouseFocused_) { this.mouseFocused_ = false; // Consume and reset flag.
diff --git a/chrome/browser/resources/settings/settings_ui/settings_ui.js b/chrome/browser/resources/settings/settings_ui/settings_ui.js index 3b15d6d..de88756f 100644 --- a/chrome/browser/resources/settings/settings_ui/settings_ui.js +++ b/chrome/browser/resources/settings/settings_ui/settings_ui.js
@@ -156,8 +156,8 @@ }; } - this.showAndroidApps_ = loadTimeData.valueExists('androidAppsAllowed') && - loadTimeData.getBoolean('androidAppsAllowed'); + this.showAndroidApps_ = loadTimeData.valueExists('androidAppsVisible') && + loadTimeData.getBoolean('androidAppsVisible'); this.addEventListener('show-container', function() { this.$.container.style.visibility = 'visible';
diff --git a/chrome/browser/safe_browsing/chrome_password_protection_service.cc b/chrome/browser/safe_browsing/chrome_password_protection_service.cc index 63168e7a..86be5bd66 100644 --- a/chrome/browser/safe_browsing/chrome_password_protection_service.cc +++ b/chrome/browser/safe_browsing/chrome_password_protection_service.cc
@@ -55,8 +55,15 @@ if (content_settings()) { CleanUpExpiredVerdicts(); UMA_HISTOGRAM_COUNTS_1000( - "PasswordProtection.NumberOfCachedVerdictBeforeShutdown", - GetStoredVerdictCount()); + "PasswordProtection.NumberOfCachedVerdictBeforeShutdown." + "PasswordOnFocus", + GetStoredVerdictCount( + LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE)); + UMA_HISTOGRAM_COUNTS_1000( + "PasswordProtection.NumberOfCachedVerdictBeforeShutdown." + "ProtectedPasswordEntry", + GetStoredVerdictCount( + LoginReputationClientRequest::PASSWORD_REUSE_EVENT)); } }
diff --git a/chrome/browser/safe_browsing/chrome_password_protection_service_unittest.cc b/chrome/browser/safe_browsing/chrome_password_protection_service_unittest.cc index e7670c2..02b84c1 100644 --- a/chrome/browser/safe_browsing/chrome_password_protection_service_unittest.cc +++ b/chrome/browser/safe_browsing/chrome_password_protection_service_unittest.cc
@@ -75,6 +75,7 @@ } void CacheVerdict(const GURL& url, + LoginReputationClientRequest::TriggerType trigger_type, LoginReputationClientResponse* verdict, const base::Time& receive_time) override {}
diff --git a/chrome/browser/signin/signin_promo.cc b/chrome/browser/signin/signin_promo.cc index cfbc4eb..968fd3f 100644 --- a/chrome/browser/signin/signin_promo.cc +++ b/chrome/browser/signin/signin_promo.cc
@@ -21,7 +21,6 @@ #include "chrome/browser/signin/signin_error_controller_factory.h" #include "chrome/browser/signin/signin_manager_factory.h" #include "chrome/browser/signin/signin_promo_util.h" -#include "chrome/browser/ui/webui/options/core_options_handler.h" #include "chrome/browser/ui/webui/theme_source.h" #include "chrome/common/pref_names.h" #include "chrome/common/url_constants.h"
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index 27d85bf..2cd97f9 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -211,10 +211,8 @@ "webui/bluetooth_internals/bluetooth_internals_ui.h", "webui/chrome_web_ui_controller_factory.cc", "webui/chrome_web_ui_controller_factory.h", - "webui/chromeos/bluetooth_pairing_ui.cc", - "webui/chromeos/bluetooth_pairing_ui.h", - "webui/chromeos/certificate_manager_dialog_ui.cc", - "webui/chromeos/certificate_manager_dialog_ui.h", + + # TODO(dbeam): why are all these /chromeos/ files on all platforms? "webui/chromeos/choose_mobile_network_ui.cc", "webui/chromeos/choose_mobile_network_ui.h", "webui/chromeos/cryptohome_ui.cc", @@ -320,8 +318,6 @@ "webui/chromeos/network_ui.h", "webui/chromeos/power_ui.cc", "webui/chromeos/power_ui.h", - "webui/chromeos/proxy_settings_ui.cc", - "webui/chromeos/proxy_settings_ui.h", "webui/chromeos/set_time_ui.cc", "webui/chromeos/set_time_ui.h", "webui/chromeos/sim_unlock_ui.cc", @@ -977,103 +973,6 @@ "webui/ntp/ntp_resource_cache.h", "webui/ntp/ntp_resource_cache_factory.cc", "webui/ntp/ntp_resource_cache_factory.h", - "webui/options/autofill_options_handler.cc", - "webui/options/autofill_options_handler.h", - "webui/options/automatic_settings_reset_handler.cc", - "webui/options/automatic_settings_reset_handler.h", - "webui/options/browser_options_handler.cc", - "webui/options/browser_options_handler.h", - "webui/options/chromeos/accounts_options_handler.cc", - "webui/options/chromeos/accounts_options_handler.h", - "webui/options/chromeos/bluetooth_options_handler.cc", - "webui/options/chromeos/bluetooth_options_handler.h", - "webui/options/chromeos/change_picture_options_handler.cc", - "webui/options/chromeos/change_picture_options_handler.h", - "webui/options/chromeos/core_chromeos_options_handler.cc", - "webui/options/chromeos/core_chromeos_options_handler.h", - "webui/options/chromeos/cros_language_options_handler.cc", - "webui/options/chromeos/cros_language_options_handler.h", - "webui/options/chromeos/date_time_options_handler.cc", - "webui/options/chromeos/date_time_options_handler.h", - "webui/options/chromeos/display_options_handler.cc", - "webui/options/chromeos/display_options_handler.h", - "webui/options/chromeos/display_overscan_handler.cc", - "webui/options/chromeos/display_overscan_handler.h", - "webui/options/chromeos/internet_options_handler.cc", - "webui/options/chromeos/internet_options_handler.h", - "webui/options/chromeos/internet_options_handler_strings.cc", - "webui/options/chromeos/internet_options_handler_strings.h", - "webui/options/chromeos/keyboard_handler.cc", - "webui/options/chromeos/keyboard_handler.h", - "webui/options/chromeos/options_stylus_handler.cc", - "webui/options/chromeos/options_stylus_handler.h", - "webui/options/chromeos/pointer_handler.cc", - "webui/options/chromeos/pointer_handler.h", - "webui/options/chromeos/power_handler.cc", - "webui/options/chromeos/power_handler.h", - "webui/options/chromeos/proxy_handler.cc", - "webui/options/chromeos/proxy_handler.h", - "webui/options/chromeos/stats_options_handler.cc", - "webui/options/chromeos/stats_options_handler.h", - "webui/options/chromeos/storage_manager_handler.cc", - "webui/options/chromeos/storage_manager_handler.h", - "webui/options/chromeos/user_image_source.cc", - "webui/options/chromeos/user_image_source.h", - "webui/options/clear_browser_data_handler.cc", - "webui/options/clear_browser_data_handler.h", - "webui/options/content_settings_handler.cc", - "webui/options/content_settings_handler.h", - "webui/options/cookies_view_handler.cc", - "webui/options/cookies_view_handler.h", - "webui/options/core_options_handler.cc", - "webui/options/core_options_handler.h", - "webui/options/create_profile_handler.cc", - "webui/options/create_profile_handler.h", - "webui/options/easy_unlock_handler.cc", - "webui/options/easy_unlock_handler.h", - "webui/options/font_settings_handler.cc", - "webui/options/font_settings_handler.h", - "webui/options/font_settings_utils.cc", - "webui/options/font_settings_utils.h", - "webui/options/font_settings_utils_linux.cc", - "webui/options/font_settings_utils_mac.mm", - "webui/options/font_settings_utils_win.cc", - "webui/options/handler_options_handler.cc", - "webui/options/handler_options_handler.h", - "webui/options/help_overlay_handler.cc", - "webui/options/help_overlay_handler.h", - "webui/options/home_page_overlay_handler.cc", - "webui/options/home_page_overlay_handler.h", - "webui/options/import_data_handler.cc", - "webui/options/import_data_handler.h", - "webui/options/language_dictionary_overlay_handler.cc", - "webui/options/language_dictionary_overlay_handler.h", - "webui/options/language_options_handler.cc", - "webui/options/language_options_handler.h", - "webui/options/language_options_handler_common.cc", - "webui/options/language_options_handler_common.h", - "webui/options/manage_profile_handler.cc", - "webui/options/manage_profile_handler.h", - "webui/options/media_devices_selection_handler.cc", - "webui/options/media_devices_selection_handler.h", - "webui/options/options_ui.cc", - "webui/options/options_ui.h", - "webui/options/password_manager_handler.cc", - "webui/options/password_manager_handler.h", - "webui/options/reset_profile_settings_handler.cc", - "webui/options/reset_profile_settings_handler.h", - "webui/options/search_engine_manager_handler.cc", - "webui/options/search_engine_manager_handler.h", - "webui/options/startup_pages_handler.cc", - "webui/options/startup_pages_handler.h", - "webui/options/supervised_user_create_confirm_handler.cc", - "webui/options/supervised_user_create_confirm_handler.h", - "webui/options/supervised_user_import_handler.cc", - "webui/options/supervised_user_import_handler.h", - "webui/options/supervised_user_learn_more_handler.cc", - "webui/options/supervised_user_learn_more_handler.h", - "webui/options/sync_setup_handler.cc", - "webui/options/sync_setup_handler.h", "webui/plural_string_handler.cc", "webui/plural_string_handler.h", "webui/policy_indicator_localized_strings_provider.cc", @@ -1281,6 +1180,104 @@ "views/select_file_dialog_extension.h", "views/select_file_dialog_extension_factory.cc", "views/select_file_dialog_extension_factory.h", + "webui/chromeos/bluetooth_pairing_ui.cc", + "webui/chromeos/bluetooth_pairing_ui.h", + "webui/chromeos/certificate_manager_dialog_ui.cc", + "webui/chromeos/certificate_manager_dialog_ui.h", + "webui/chromeos/proxy_settings_ui.cc", + "webui/chromeos/proxy_settings_ui.h", + "webui/options/autofill_options_handler.cc", + "webui/options/autofill_options_handler.h", + "webui/options/automatic_settings_reset_handler.cc", + "webui/options/automatic_settings_reset_handler.h", + "webui/options/browser_options_handler.cc", + "webui/options/browser_options_handler.h", + "webui/options/chromeos/accounts_options_handler.cc", + "webui/options/chromeos/accounts_options_handler.h", + "webui/options/chromeos/bluetooth_options_handler.cc", + "webui/options/chromeos/bluetooth_options_handler.h", + "webui/options/chromeos/change_picture_options_handler.cc", + "webui/options/chromeos/change_picture_options_handler.h", + "webui/options/chromeos/core_chromeos_options_handler.cc", + "webui/options/chromeos/core_chromeos_options_handler.h", + "webui/options/chromeos/cros_language_options_handler.cc", + "webui/options/chromeos/cros_language_options_handler.h", + "webui/options/chromeos/date_time_options_handler.cc", + "webui/options/chromeos/date_time_options_handler.h", + "webui/options/chromeos/display_options_handler.cc", + "webui/options/chromeos/display_options_handler.h", + "webui/options/chromeos/display_overscan_handler.cc", + "webui/options/chromeos/display_overscan_handler.h", + "webui/options/chromeos/internet_options_handler.cc", + "webui/options/chromeos/internet_options_handler.h", + "webui/options/chromeos/internet_options_handler_strings.cc", + "webui/options/chromeos/internet_options_handler_strings.h", + "webui/options/chromeos/keyboard_handler.cc", + "webui/options/chromeos/keyboard_handler.h", + "webui/options/chromeos/options_stylus_handler.cc", + "webui/options/chromeos/options_stylus_handler.h", + "webui/options/chromeos/pointer_handler.cc", + "webui/options/chromeos/pointer_handler.h", + "webui/options/chromeos/power_handler.cc", + "webui/options/chromeos/power_handler.h", + "webui/options/chromeos/proxy_handler.cc", + "webui/options/chromeos/proxy_handler.h", + "webui/options/chromeos/stats_options_handler.cc", + "webui/options/chromeos/stats_options_handler.h", + "webui/options/chromeos/storage_manager_handler.cc", + "webui/options/chromeos/storage_manager_handler.h", + "webui/options/chromeos/user_image_source.cc", + "webui/options/chromeos/user_image_source.h", + "webui/options/clear_browser_data_handler.cc", + "webui/options/clear_browser_data_handler.h", + "webui/options/content_settings_handler.cc", + "webui/options/content_settings_handler.h", + "webui/options/cookies_view_handler.cc", + "webui/options/cookies_view_handler.h", + "webui/options/core_options_handler.cc", + "webui/options/core_options_handler.h", + "webui/options/create_profile_handler.cc", + "webui/options/create_profile_handler.h", + "webui/options/easy_unlock_handler.cc", + "webui/options/easy_unlock_handler.h", + "webui/options/font_settings_handler.cc", + "webui/options/font_settings_handler.h", + "webui/options/handler_options_handler.cc", + "webui/options/handler_options_handler.h", + "webui/options/help_overlay_handler.cc", + "webui/options/help_overlay_handler.h", + "webui/options/home_page_overlay_handler.cc", + "webui/options/home_page_overlay_handler.h", + "webui/options/import_data_handler.cc", + "webui/options/import_data_handler.h", + "webui/options/language_dictionary_overlay_handler.cc", + "webui/options/language_dictionary_overlay_handler.h", + "webui/options/language_options_handler.cc", + "webui/options/language_options_handler.h", + "webui/options/language_options_handler_common.cc", + "webui/options/language_options_handler_common.h", + "webui/options/manage_profile_handler.cc", + "webui/options/manage_profile_handler.h", + "webui/options/media_devices_selection_handler.cc", + "webui/options/media_devices_selection_handler.h", + "webui/options/options_ui.cc", + "webui/options/options_ui.h", + "webui/options/password_manager_handler.cc", + "webui/options/password_manager_handler.h", + "webui/options/reset_profile_settings_handler.cc", + "webui/options/reset_profile_settings_handler.h", + "webui/options/search_engine_manager_handler.cc", + "webui/options/search_engine_manager_handler.h", + "webui/options/startup_pages_handler.cc", + "webui/options/startup_pages_handler.h", + "webui/options/supervised_user_create_confirm_handler.cc", + "webui/options/supervised_user_create_confirm_handler.h", + "webui/options/supervised_user_import_handler.cc", + "webui/options/supervised_user_import_handler.h", + "webui/options/supervised_user_learn_more_handler.cc", + "webui/options/supervised_user_learn_more_handler.h", + "webui/options/sync_setup_handler.cc", + "webui/options/sync_setup_handler.h", ] deps += [ "//chrome/browser/chromeos", @@ -2180,11 +2177,15 @@ "crypto_module_delegate_nss.h", "crypto_module_password_dialog_nss.cc", "crypto_module_password_dialog_nss.h", - "webui/options/certificate_manager_handler.cc", - "webui/options/certificate_manager_handler.h", "webui/settings/certificates_handler.cc", "webui/settings/certificates_handler.h", ] + if (is_chromeos) { + sources += [ + "webui/options/certificate_manager_handler.cc", + "webui/options/certificate_manager_handler.h", + ] + } } if (is_mac || is_win) { sources += [
diff --git a/chrome/browser/ui/app_list/arc/arc_app_unittest.cc b/chrome/browser/ui/app_list/arc/arc_app_unittest.cc index bd91c22..8f2ec681 100644 --- a/chrome/browser/ui/app_list/arc/arc_app_unittest.cc +++ b/chrome/browser/ui/app_list/arc/arc_app_unittest.cc
@@ -136,6 +136,8 @@ ARC_PERSISTENT_PLAY_STORE_MANAGED_AND_ENABLED, // ARC is persistent and Play Store is managed and disabled. ARC_PERSISTENT_PLAY_STORE_MANAGED_AND_DISABLED, + // ARC is persistent but without Play Store UI support. + ARC_PERSISTENT_WITHOUT_PLAY_STORE, }; constexpr ArcState kManagedArcStates[] = { @@ -148,6 +150,7 @@ constexpr ArcState kUnmanagedArcStates[] = { ArcState::ARC_PLAY_STORE_UNMANAGED, ArcState::ARC_PERSISTENT_PLAY_STORE_UNMANAGED, + ArcState::ARC_PERSISTENT_WITHOUT_PLAY_STORE, }; } // namespace @@ -166,7 +169,10 @@ case ArcState::ARC_PERSISTENT_PLAY_STORE_UNMANAGED: case ArcState::ARC_PERSISTENT_PLAY_STORE_MANAGED_AND_ENABLED: case ArcState::ARC_PERSISTENT_PLAY_STORE_MANAGED_AND_DISABLED: - arc::SetArcAlwaysStartForTesting(); + arc::SetArcAlwaysStartForTesting(true); + break; + case ArcState::ARC_PERSISTENT_WITHOUT_PLAY_STORE: + arc::SetArcAlwaysStartForTesting(false); break; default: break; @@ -553,6 +559,7 @@ return true; case ArcState::ARC_PLAY_STORE_MANAGED_AND_DISABLED: case ArcState::ARC_PERSISTENT_PLAY_STORE_MANAGED_AND_DISABLED: + case ArcState::ARC_PERSISTENT_WITHOUT_PLAY_STORE: return false; default: NOTREACHED(); @@ -1121,7 +1128,6 @@ } TEST_P(ArcPlayStoreAppTest, PlayStore) { - // Make sure PlayStore is available. ASSERT_TRUE(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); ArcAppListPrefs* prefs = ArcAppListPrefs::Get(profile_.get()); @@ -1129,15 +1135,22 @@ std::unique_ptr<ArcAppListPrefs::AppInfo> app_info = prefs->GetApp( arc::kPlayStoreAppId); - ASSERT_TRUE(app_info); - EXPECT_FALSE(app_info->ready); + if (GetParam() != ArcState::ARC_PERSISTENT_WITHOUT_PLAY_STORE) { + // Make sure PlayStore is available. + ASSERT_TRUE(app_info); + EXPECT_FALSE(app_info->ready); + } else { + // By default Play Store is not available in case no Play Store mode. But + // explicitly adding it makes it appear as an ordinal app. + EXPECT_FALSE(app_info); + } arc::mojom::AppInfo app; std::vector<arc::mojom::AppInfo> apps; app.name = "Play Store"; app.package_name = arc::kPlayStorePackage; app.activity = arc::kPlayStoreActivity; - app.sticky = false; + app.sticky = GetParam() != ArcState::ARC_PERSISTENT_WITHOUT_PLAY_STORE; apps.push_back(app); app_instance()->RefreshAppList();
diff --git a/chrome/browser/ui/app_list/arc/arc_default_app_list.cc b/chrome/browser/ui/app_list/arc/arc_default_app_list.cc index 102d2a8..df79f640 100644 --- a/chrome/browser/ui/app_list/arc/arc_default_app_list.cc +++ b/chrome/browser/ui/app_list/arc/arc_default_app_list.cc
@@ -12,6 +12,7 @@ #include "chrome/browser/ui/app_list/arc/arc_app_list_prefs.h" #include "chrome/browser/ui/app_list/arc/arc_app_utils.h" #include "chrome/common/chrome_paths.h" +#include "components/arc/arc_util.h" #include "content/public/browser/browser_thread.h" #include "extensions/browser/extension_system.h" @@ -147,7 +148,7 @@ extensions::ExtensionSystem::Get(context_)->extension_service(); const extensions::Extension* arc_host = service ? service->GetInstalledExtension(arc::kPlayStoreAppId) : nullptr; - if (arc_host) { + if (arc_host && arc::IsPlayStoreAvailable()) { std::unique_ptr<ArcDefaultAppList::AppInfo> play_store_app( new ArcDefaultAppList::AppInfo(arc_host->name(), arc::kPlayStorePackage,
diff --git a/chrome/browser/ui/ash/chrome_shell_delegate.cc b/chrome/browser/ui/ash/chrome_shell_delegate.cc index 9aa1fd61..616f3cf 100644 --- a/chrome/browser/ui/ash/chrome_shell_delegate.cc +++ b/chrome/browser/ui/ash/chrome_shell_delegate.cc
@@ -32,6 +32,7 @@ #include "chrome/browser/chromeos/background/ash_wallpaper_delegate.h" #include "chrome/browser/chromeos/display/display_configuration_observer.h" #include "chrome/browser/chromeos/display/display_preferences.h" +#include "chrome/browser/chromeos/input_method/input_method_manager_impl.h" #include "chrome/browser/chromeos/policy/display_rotation_default_handler.h" #include "chrome/browser/chromeos/profiles/profile_helper.h" #include "chrome/browser/chromeos/system/input_device_settings.h" @@ -613,6 +614,10 @@ return chromeos::CreateSystemTrayDelegate(); } +ash::ImeController* ChromeShellDelegate::GetImeController() { + return chromeos::input_method::InputMethodManagerImpl::Get(); +} + std::unique_ptr<ash::WallpaperDelegate> ChromeShellDelegate::CreateWallpaperDelegate() { return base::WrapUnique(chromeos::CreateWallpaperDelegate());
diff --git a/chrome/browser/ui/ash/chrome_shell_delegate.h b/chrome/browser/ui/ash/chrome_shell_delegate.h index 1002ad8..34d5717 100644 --- a/chrome/browser/ui/ash/chrome_shell_delegate.h +++ b/chrome/browser/ui/ash/chrome_shell_delegate.h
@@ -45,6 +45,7 @@ void ShelfInit() override; void ShelfShutdown() override; ash::SystemTrayDelegate* CreateSystemTrayDelegate() override; + ash::ImeController* GetImeController() override; std::unique_ptr<ash::WallpaperDelegate> CreateWallpaperDelegate() override; ash::AccessibilityDelegate* CreateAccessibilityDelegate() override; std::unique_ptr<ash::PaletteDelegate> CreatePaletteDelegate() override;
diff --git a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_unittest.cc b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_unittest.cc index e4ae2d3..7d2a16f 100644 --- a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_unittest.cc +++ b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_unittest.cc
@@ -1079,7 +1079,7 @@ void SetUp() override { if (GetParam()) - arc::SetArcAlwaysStartForTesting(); + arc::SetArcAlwaysStartForTesting(true); ChromeLauncherControllerTest::SetUp(); } @@ -1334,7 +1334,7 @@ void SetUp() override { if (GetParam()) - arc::SetArcAlwaysStartForTesting(); + arc::SetArcAlwaysStartForTesting(true); MultiProfileMultiBrowserShelfLayoutChromeLauncherControllerTest::SetUp(); } @@ -3870,7 +3870,7 @@ protected: void SetUp() override { if (GetParam()) - arc::SetArcAlwaysStartForTesting(); + arc::SetArcAlwaysStartForTesting(true); ArcDefaultAppList::UseTestAppsDirectory(); ChromeLauncherControllerTest::SetUp(); }
diff --git a/chrome/browser/ui/ash/system_tray_delegate_chromeos.cc b/chrome/browser/ui/ash/system_tray_delegate_chromeos.cc index 67648c4c..7e207451 100644 --- a/chrome/browser/ui/ash/system_tray_delegate_chromeos.cc +++ b/chrome/browser/ui/ash/system_tray_delegate_chromeos.cc
@@ -17,7 +17,6 @@ #include "ash/shell.h" #include "ash/shell_delegate.h" #include "ash/system/date/clock_observer.h" -#include "ash/system/ime/ime_observer.h" #include "ash/system/power/power_status.h" #include "ash/system/session/logout_button_observer.h" #include "ash/system/tray/system_tray_notifier.h" @@ -56,29 +55,14 @@ #include "components/user_manager/user_type.h" #include "content/public/browser/notification_observer.h" #include "content/public/browser/notification_service.h" -#include "ui/base/ime/chromeos/extension_ime_util.h" -#include "ui/base/ime/chromeos/input_method_manager.h" -#include "ui/base/ime/chromeos/input_method_util.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/l10n/time_format.h" #include "ui/chromeos/events/pref_names.h" -#include "ui/chromeos/ime/input_method_menu_item.h" -#include "ui/chromeos/ime/input_method_menu_manager.h" namespace chromeos { namespace { -void ExtractIMEInfo(const input_method::InputMethodDescriptor& ime, - const input_method::InputMethodUtil& util, - ash::IMEInfo* info) { - info->id = ime.id(); - info->name = util.GetInputMethodLongName(ime); - info->medium_name = util.GetInputMethodMediumName(ime); - info->short_name = util.GetInputMethodShortName(ime); - info->third_party = extension_ime_util::IsExtensionIME(ime.id()); -} - void OnAcceptMultiprofilesIntro(bool no_show_again) { PrefService* prefs = ProfileManager::GetActiveUserProfile()->GetPrefs(); prefs->SetBoolean(prefs::kMultiProfileNeverShowIntro, no_show_again); @@ -181,54 +165,6 @@ } } -void SystemTrayDelegateChromeOS::GetCurrentIME(ash::IMEInfo* info) { - input_method::InputMethodManager* manager = - input_method::InputMethodManager::Get(); - input_method::InputMethodUtil* util = manager->GetInputMethodUtil(); - input_method::InputMethodDescriptor ime = - manager->GetActiveIMEState()->GetCurrentInputMethod(); - ExtractIMEInfo(ime, *util, info); - info->selected = true; -} - -void SystemTrayDelegateChromeOS::GetAvailableIMEList(ash::IMEInfoList* list) { - input_method::InputMethodManager* manager = - input_method::InputMethodManager::Get(); - input_method::InputMethodUtil* util = manager->GetInputMethodUtil(); - std::unique_ptr<input_method::InputMethodDescriptors> ime_descriptors( - manager->GetActiveIMEState()->GetActiveInputMethods()); - std::string current = - manager->GetActiveIMEState()->GetCurrentInputMethod().id(); - for (size_t i = 0; i < ime_descriptors->size(); i++) { - input_method::InputMethodDescriptor& ime = ime_descriptors->at(i); - ash::IMEInfo info; - ExtractIMEInfo(ime, *util, &info); - info.selected = ime.id() == current; - list->push_back(info); - } -} - -void SystemTrayDelegateChromeOS::GetCurrentIMEProperties( - ash::IMEPropertyInfoList* list) { - ui::ime::InputMethodMenuItemList menu_list = - ui::ime::InputMethodMenuManager::GetInstance()-> - GetCurrentInputMethodMenuItemList(); - for (size_t i = 0; i < menu_list.size(); ++i) { - ash::IMEPropertyInfo property; - property.key = menu_list[i].key; - property.name = base::UTF8ToUTF16(menu_list[i].label); - property.selected = menu_list[i].is_selection_item_checked; - list->push_back(property); - } -} - -base::string16 SystemTrayDelegateChromeOS::GetIMEManagedMessage() { - auto ime_state = input_method::InputMethodManager::Get()->GetActiveIMEState(); - return ime_state->GetAllowedInputMethods().empty() - ? base::string16() - : l10n_util::GetStringUTF16(IDS_OPTIONS_CONTROLLED_SETTING_POLICY); -} - ash::NetworkingConfigDelegate* SystemTrayDelegateChromeOS::GetNetworkingConfigDelegate() const { return networking_config_delegate_.get();
diff --git a/chrome/browser/ui/ash/system_tray_delegate_chromeos.h b/chrome/browser/ui/ash/system_tray_delegate_chromeos.h index a7d6a9b..2e267bd 100644 --- a/chrome/browser/ui/ash/system_tray_delegate_chromeos.h +++ b/chrome/browser/ui/ash/system_tray_delegate_chromeos.h
@@ -12,7 +12,6 @@ #include <vector> #include "ash/accessibility_types.h" -#include "ash/system/tray/ime_info.h" #include "ash/system/tray/system_tray_delegate.h" #include "base/macros.h" #include "base/observer_list.h" @@ -48,10 +47,6 @@ // Overridden from ash::SystemTrayDelegate: void Initialize() override; void ShowUserLogin() override; - void GetCurrentIME(ash::IMEInfo* info) override; - void GetAvailableIMEList(ash::IMEInfoList* list) override; - void GetCurrentIMEProperties(ash::IMEPropertyInfoList* list) override; - base::string16 GetIMEManagedMessage() override; ash::NetworkingConfigDelegate* GetNetworkingConfigDelegate() const override; void ActiveUserWasChanged() override; bool IsSearchKeyMappedToCapsLock() override;
diff --git a/chrome/browser/ui/chrome_pages.cc b/chrome/browser/ui/chrome_pages.cc index 115eb7cf..4b191db 100644 --- a/chrome/browser/ui/chrome_pages.cc +++ b/chrome/browser/ui/chrome_pages.cc
@@ -29,7 +29,6 @@ #include "chrome/browser/ui/singleton_tabs.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/browser/ui/webui/md_bookmarks/md_bookmarks_ui.h" -#include "chrome/browser/ui/webui/options/content_settings_handler.h" #include "chrome/browser/ui/webui/site_settings_helper.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/url_constants.h"
diff --git a/chrome/browser/ui/cocoa/omnibox/omnibox_popup_cell.mm b/chrome/browser/ui/cocoa/omnibox/omnibox_popup_cell.mm index d0f2a2e3..2aef7d8 100644 --- a/chrome/browser/ui/cocoa/omnibox/omnibox_popup_cell.mm +++ b/chrome/browser/ui/cocoa/omnibox/omnibox_popup_cell.mm
@@ -636,7 +636,8 @@ cellFrame, NSOffsetRect(cellFrame, origin.x, origin.y)); renderRect.size.width = std::min(NSWidth(renderRect), static_cast<CGFloat>(maxWidth)); - renderRect.size.height = std::min(NSWidth(renderRect), kDefaultTextHeight); + renderRect.size.height = + std::min(NSHeight(renderRect), [attributedString size].height); if (!NSIsEmptyRect(renderRect)) { [attributedString drawWithRect:FlipIfRTL(renderRect, cellFrame) options:NSStringDrawingUsesLineFragmentOrigin |
diff --git a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc b/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc index d0520cce..2d56788 100644 --- a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc +++ b/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc
@@ -43,7 +43,6 @@ #include "chrome/browser/ui/webui/net_internals/net_internals_ui.h" #include "chrome/browser/ui/webui/ntp_tiles_internals_ui.h" #include "chrome/browser/ui/webui/omnibox/omnibox_ui.h" -#include "chrome/browser/ui/webui/options/options_ui.h" #include "chrome/browser/ui/webui/password_manager_internals/password_manager_internals_ui.h" #include "chrome/browser/ui/webui/physical_web/physical_web_ui.h" #include "chrome/browser/ui/webui/policy_material_design_ui.h" @@ -147,6 +146,7 @@ #include "chrome/browser/ui/webui/chromeos/sim_unlock_ui.h" #include "chrome/browser/ui/webui/chromeos/slow_trace_ui.h" #include "chrome/browser/ui/webui/chromeos/slow_ui.h" +#include "chrome/browser/ui/webui/options/options_ui.h" #include "chrome/browser/ui/webui/voice_search_ui.h" #include "components/proximity_auth/webui/proximity_auth_ui.h" #include "components/proximity_auth/webui/url_constants.h" @@ -398,7 +398,7 @@ extensions::ExtensionSystem::Get(profile)->extension_service()) { return &NewWebUI<AppLauncherPageUI>; } -#endif // !defined(OS_CHROMEOS) +#endif // defined(OS_CHROMEOS) // Bookmarks are part of NTP on Android. if (url.host_piece() == chrome::kChromeUIBookmarksHost) { @@ -427,8 +427,6 @@ url.host_piece() == chrome::kChromeUIMdSettingsHost) { return &NewWebUI<settings::MdSettingsUI>; } - if (url.host_piece() == chrome::kChromeUISettingsFrameHost) - return &NewWebUI<options::OptionsUI>; // If the material design extensions page is enabled, it gets its own host. // Otherwise, it's handled by the uber settings page. if (url.host_piece() == chrome::kChromeUIExtensionsHost && @@ -483,6 +481,8 @@ return &NewWebUI<chromeos::ProxySettingsUI>; if (url.host_piece() == chrome::kChromeUISetTimeHost) return &NewWebUI<chromeos::SetTimeUI>; + if (url.host_piece() == chrome::kChromeUISettingsFrameHost) + return &NewWebUI<options::OptionsUI>; if (url.host_piece() == chrome::kChromeUISimUnlockHost) return &NewWebUI<chromeos::SimUnlockUI>; if (url.host_piece() == chrome::kChromeUISlowHost)
diff --git a/chrome/browser/ui/webui/options/font_settings_handler.cc b/chrome/browser/ui/webui/options/font_settings_handler.cc index f5a045c..7b1ca1f 100644 --- a/chrome/browser/ui/webui/options/font_settings_handler.cc +++ b/chrome/browser/ui/webui/options/font_settings_handler.cc
@@ -23,7 +23,7 @@ #include "chrome/browser/extensions/extension_tab_util.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser_finder.h" -#include "chrome/browser/ui/webui/options/font_settings_utils.h" +#include "chrome/browser/ui/webui/settings_utils.h" #include "chrome/common/pref_names.h" #include "chrome/grit/generated_resources.h" #include "components/prefs/pref_service.h" @@ -116,7 +116,9 @@ void FontSettingsHandler::RegisterMessages() { // Perform validation for saved fonts. PrefService* pref_service = Profile::FromWebUI(web_ui())->GetPrefs(); - FontSettingsUtilities::ValidateSavedFonts(pref_service); +#if defined(OS_MACOSX) + settings_utils::ValidateSavedFonts(pref_service); +#endif // Register for preferences that we need to observe manually. standard_font_.Init(prefs::kWebKitStandardFontFamily, @@ -192,14 +194,14 @@ } base::ListValue selected_values; - selected_values.AppendString(FontSettingsUtilities::MaybeGetLocalizedFontName( - standard_font_.GetValue())); selected_values.AppendString( - FontSettingsUtilities::MaybeGetLocalizedFontName(serif_font_.GetValue())); - selected_values.AppendString(FontSettingsUtilities::MaybeGetLocalizedFontName( - sans_serif_font_.GetValue())); + settings_utils::MaybeGetLocalizedFontName(standard_font_.GetValue())); selected_values.AppendString( - FontSettingsUtilities::MaybeGetLocalizedFontName(fixed_font_.GetValue())); + settings_utils::MaybeGetLocalizedFontName(serif_font_.GetValue())); + selected_values.AppendString( + settings_utils::MaybeGetLocalizedFontName(sans_serif_font_.GetValue())); + selected_values.AppendString( + settings_utils::MaybeGetLocalizedFontName(fixed_font_.GetValue())); web_ui()->CallJavascriptFunctionUnsafe( "FontSettings.setFontsData", *list.get(), selected_values); @@ -207,7 +209,7 @@ void FontSettingsHandler::SetUpStandardFontSample() { base::Value font_value( - FontSettingsUtilities::ResolveFontList(standard_font_.GetValue())); + settings_utils::ResolveFontList(standard_font_.GetValue())); base::Value size_value(default_font_size_.GetValue()); web_ui()->CallJavascriptFunctionUnsafe("FontSettings.setUpStandardFontSample", font_value, size_value); @@ -215,7 +217,7 @@ void FontSettingsHandler::SetUpSerifFontSample() { base::Value font_value( - FontSettingsUtilities::ResolveFontList(serif_font_.GetValue())); + settings_utils::ResolveFontList(serif_font_.GetValue())); base::Value size_value(default_font_size_.GetValue()); web_ui()->CallJavascriptFunctionUnsafe("FontSettings.setUpSerifFontSample", font_value, size_value); @@ -223,7 +225,7 @@ void FontSettingsHandler::SetUpSansSerifFontSample() { base::Value font_value( - FontSettingsUtilities::ResolveFontList(sans_serif_font_.GetValue())); + settings_utils::ResolveFontList(sans_serif_font_.GetValue())); base::Value size_value(default_font_size_.GetValue()); web_ui()->CallJavascriptFunctionUnsafe( "FontSettings.setUpSansSerifFontSample", font_value, size_value); @@ -231,7 +233,7 @@ void FontSettingsHandler::SetUpFixedFontSample() { base::Value font_value( - FontSettingsUtilities::ResolveFontList(fixed_font_.GetValue())); + settings_utils::ResolveFontList(fixed_font_.GetValue())); base::Value size_value(default_fixed_font_size_.GetValue()); web_ui()->CallJavascriptFunctionUnsafe("FontSettings.setUpFixedFontSample", font_value, size_value);
diff --git a/chrome/browser/ui/webui/options/font_settings_utils.cc b/chrome/browser/ui/webui/options/font_settings_utils.cc deleted file mode 100644 index 516b138..0000000 --- a/chrome/browser/ui/webui/options/font_settings_utils.cc +++ /dev/null
@@ -1,25 +0,0 @@ -// Copyright (c) 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 "chrome/browser/ui/webui/options/font_settings_utils.h" - -#include "ui/gfx/font_list.h" - -namespace options { - -std::string FontSettingsUtilities::ResolveFontList( - const std::string& font_name_or_list) { - if (!font_name_or_list.empty() && font_name_or_list[0] == ',') - return gfx::FontList::FirstAvailableOrFirst(font_name_or_list); - return font_name_or_list; -} - -#if !defined(OS_WIN) -std::string FontSettingsUtilities::MaybeGetLocalizedFontName( - const std::string& font_name_or_list) { - return ResolveFontList(font_name_or_list); -} -#endif - -} // namespace options
diff --git a/chrome/browser/ui/webui/options/font_settings_utils.h b/chrome/browser/ui/webui/options/font_settings_utils.h deleted file mode 100644 index 35801bb4..0000000 --- a/chrome/browser/ui/webui/options/font_settings_utils.h +++ /dev/null
@@ -1,41 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_UI_WEBUI_OPTIONS_FONT_SETTINGS_UTILS_H_ -#define CHROME_BROWSER_UI_WEBUI_OPTIONS_FONT_SETTINGS_UTILS_H_ - -#include <string> - -#include "base/macros.h" - -class PrefService; - -namespace options { - -// Chrome advanced options utility methods. -class FontSettingsUtilities { - public: - static void ValidateSavedFonts(PrefService* prefs); - - // When |font_name_or_list| starts with ",", it is a list of font names - // separated by "," and this function returns the first available font name. - // Otherwise returns |font_name_or_list| as is. - // Unlike gfx::FontList, this function picks one font, and character-level - // fallback is handled in CSS. - static std::string ResolveFontList(const std::string& font_name_or_list); - - // Returns the localized name of a font so that settings can find it within - // the list of system fonts. On Windows, the list of system fonts has names - // only for the system locale, but the pref value may be in the English name. - // For example, "MS Gothic" becomes "ï¼ï¼³ ゴシック" on localized Windows. - static std::string MaybeGetLocalizedFontName( - const std::string& font_name_or_list); - - private: - DISALLOW_IMPLICIT_CONSTRUCTORS(FontSettingsUtilities); -}; - -} // namespace options - -#endif // CHROME_BROWSER_UI_WEBUI_OPTIONS_FONT_SETTINGS_UTILS_H_
diff --git a/chrome/browser/ui/webui/options/font_settings_utils_linux.cc b/chrome/browser/ui/webui/options/font_settings_utils_linux.cc deleted file mode 100644 index 1576d03..0000000 --- a/chrome/browser/ui/webui/options/font_settings_utils_linux.cc +++ /dev/null
@@ -1,14 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ui/webui/options/font_settings_utils.h" - -namespace options { - -// static -void FontSettingsUtilities::ValidateSavedFonts(PrefService* prefs) { - // Nothing to do for X11. -} - -} // namespace options
diff --git a/chrome/browser/ui/webui/options/font_settings_utils_mac.mm b/chrome/browser/ui/webui/options/font_settings_utils_mac.mm deleted file mode 100644 index 85c220f..0000000 --- a/chrome/browser/ui/webui/options/font_settings_utils_mac.mm +++ /dev/null
@@ -1,42 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ui/webui/options/font_settings_utils.h" - -#import <Cocoa/Cocoa.h> - -#include "base/mac/scoped_nsautorelease_pool.h" -#include "base/strings/sys_string_conversions.h" -#include "base/values.h" -#include "chrome/common/pref_names.h" -#include "components/prefs/pref_service.h" - -namespace options { - -static void ValidateFontFamily(PrefService* prefs, - const char* family_pref_name) { - // The native font settings dialog saved fonts by the font name, rather - // than the family name. This worked for the old dialog since - // -[NSFont fontWithName:size] accepted a font or family name, but the - // behavior was technically wrong. Since we really need the family name for - // the dom-ui options window, we will fix the saved preference if necessary. - NSString *family_name = - base::SysUTF8ToNSString(prefs->GetString(family_pref_name)); - NSFont *font = [NSFont fontWithName:family_name - size:[NSFont systemFontSize]]; - if (font && - [[font familyName] caseInsensitiveCompare:family_name] != NSOrderedSame) { - std::string new_family_name = base::SysNSStringToUTF8([font familyName]); - prefs->SetString(family_pref_name, new_family_name); - } -} - -// static -void FontSettingsUtilities::ValidateSavedFonts(PrefService* prefs) { - ValidateFontFamily(prefs, prefs::kWebKitSerifFontFamily); - ValidateFontFamily(prefs, prefs::kWebKitSansSerifFontFamily); - ValidateFontFamily(prefs, prefs::kWebKitFixedFontFamily); -} - -} // namespace options
diff --git a/chrome/browser/ui/webui/options/font_settings_utils_win.cc b/chrome/browser/ui/webui/options/font_settings_utils_win.cc deleted file mode 100644 index aa3dd79..0000000 --- a/chrome/browser/ui/webui/options/font_settings_utils_win.cc +++ /dev/null
@@ -1,27 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ui/webui/options/font_settings_utils.h" - -#include "ui/gfx/font.h" -#include "ui/gfx/platform_font_win.h" - -namespace options { - -// static -void FontSettingsUtilities::ValidateSavedFonts(PrefService* prefs) { - // Nothing to do for Windows. -} - -std::string FontSettingsUtilities::MaybeGetLocalizedFontName( - const std::string& font_name_or_list) { - std::string font_name = ResolveFontList(font_name_or_list); - if (font_name.empty()) - return font_name; - gfx::Font font(font_name, 12); // dummy font size - return static_cast<gfx::PlatformFontWin*>(font.platform_font()) - ->GetLocalizedFontName(); -} - -} // namespace options
diff --git a/chrome/browser/ui/webui/settings/font_handler.cc b/chrome/browser/ui/webui/settings/font_handler.cc index 954f7f66..abd118e 100644 --- a/chrome/browser/ui/webui/settings/font_handler.cc +++ b/chrome/browser/ui/webui/settings/font_handler.cc
@@ -16,7 +16,6 @@ #include "chrome/browser/extensions/extension_tab_util.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser_finder.h" -#include "chrome/browser/ui/webui/options/font_settings_utils.h" #include "chrome/common/pref_names.h" #include "components/prefs/pref_service.h" #include "content/public/browser/font_list_async.h" @@ -25,6 +24,10 @@ #include "extensions/browser/extension_system.h" #include "extensions/common/extension_urls.h" +#if defined(OS_MACOSX) +#include "chrome/browser/ui/webui/settings_utils.h" +#endif + namespace { const char kAdvancedFontSettingsExtensionId[] = @@ -38,8 +41,10 @@ : extension_registry_observer_(this), profile_(Profile::FromWebUI(webui)), weak_ptr_factory_(this) { +#if defined(OS_MACOSX) // Perform validation for saved fonts. - options::FontSettingsUtilities::ValidateSavedFonts(profile_->GetPrefs()); + settings_utils::ValidateSavedFonts(profile_->GetPrefs()); +#endif } FontHandler::~FontHandler() {}
diff --git a/chrome/browser/ui/webui/settings/md_settings_ui.cc b/chrome/browser/ui/webui/settings/md_settings_ui.cc index 6d4d5df..83f48d8e 100644 --- a/chrome/browser/ui/webui/settings/md_settings_ui.cc +++ b/chrome/browser/ui/webui/settings/md_settings_ui.cc
@@ -204,9 +204,10 @@ chromeos::quick_unlock::IsPinEnabled(profile->GetPrefs())); html_source->AddBoolean("fingerprintUnlockEnabled", chromeos::quick_unlock::IsFingerprintEnabled()); - html_source->AddBoolean("androidAppsAllowed", + html_source->AddBoolean("androidAppsVisible", arc::IsArcAllowedForProfile(profile) && - !arc::IsArcOptInVerificationDisabled()); + !arc::IsArcOptInVerificationDisabled() && + arc::IsPlayStoreAvailable()); // TODO(mash): Support Chrome power settings in Mash. crbug.com/644348 bool enable_power_settings =
diff --git a/chrome/browser/ui/webui/settings_utils.cc b/chrome/browser/ui/webui/settings_utils.cc index 687fe4a..4347b44 100644 --- a/chrome/browser/ui/webui/settings_utils.cc +++ b/chrome/browser/ui/webui/settings_utils.cc
@@ -8,6 +8,7 @@ #include "chrome/grit/theme_resources.h" #include "components/url_formatter/url_fixer.h" #include "ui/base/resource/resource_bundle.h" +#include "ui/gfx/font_list.h" #include "url/gurl.h" namespace settings_utils { @@ -26,4 +27,16 @@ IDR_SETTINGS_FAVICON, scale_factor); } +std::string ResolveFontList(const std::string& font_name_or_list) { + if (!font_name_or_list.empty() && font_name_or_list[0] == ',') + return gfx::FontList::FirstAvailableOrFirst(font_name_or_list); + return font_name_or_list; +} + +#if !defined(OS_WIN) +std::string MaybeGetLocalizedFontName(const std::string& font_name_or_list) { + return ResolveFontList(font_name_or_list); +} +#endif + } // namespace settings_utils
diff --git a/chrome/browser/ui/webui/settings_utils.h b/chrome/browser/ui/webui/settings_utils.h index c32310e..d0f82b4 100644 --- a/chrome/browser/ui/webui/settings_utils.h +++ b/chrome/browser/ui/webui/settings_utils.h
@@ -11,6 +11,7 @@ #include "ui/base/resource/scale_factor.h" class GURL; +class PrefService; namespace base { class RefCountedMemory; @@ -20,6 +21,7 @@ class WebContents; } +// Chrome settings utility methods. namespace settings_utils { // Invoke UI for network proxy settings. @@ -35,6 +37,23 @@ base::RefCountedMemory* GetFaviconResourceBytes(ui::ScaleFactor scale_factor); +#if defined(OS_MACOSX) +void ValidateSavedFonts(PrefService* prefs); +#endif + +// When |font_name_or_list| starts with ",", it is a list of font names +// separated by "," and this function returns the first available font name. +// Otherwise returns |font_name_or_list| as is. +// Unlike gfx::FontList, this function picks one font, and character-level +// fallback is handled in CSS. +std::string ResolveFontList(const std::string& font_name_or_list); + +// Returns the localized name of a font so that settings can find it within +// the list of system fonts. On Windows, the list of system fonts has names +// only for the system locale, but the pref value may be in the English name. +// For example, "MS Gothic" becomes "ï¼ï¼³ ゴシック" on localized Windows. +std::string MaybeGetLocalizedFontName(const std::string& font_name_or_list); + } // namespace settings_utils #endif // CHROME_BROWSER_UI_WEBUI_SETTINGS_UTILS_H_
diff --git a/chrome/browser/ui/webui/settings_utils_mac.mm b/chrome/browser/ui/webui/settings_utils_mac.mm index 1f68f49..0611e97 100644 --- a/chrome/browser/ui/webui/settings_utils_mac.mm +++ b/chrome/browser/ui/webui/settings_utils_mac.mm
@@ -9,6 +9,28 @@ #include "base/logging.h" #include "base/mac/mac_logging.h" #include "base/mac/scoped_aedesc.h" +#include "base/mac/scoped_nsautorelease_pool.h" +#include "base/strings/sys_string_conversions.h" +#include "chrome/common/pref_names.h" +#include "components/prefs/pref_service.h" + +namespace { +void ValidateFontFamily(PrefService* prefs, const char* family_pref_name) { + // The native font settings dialog saved fonts by the font name, rather + // than the family name. This worked for the old dialog since + // -[NSFont fontWithName:size] accepted a font or family name, but the + // behavior was technically wrong. Since we really need the family name for + // the webui settings window, we will fix the saved preference if necessary. + NSString* family_name = + base::SysUTF8ToNSString(prefs->GetString(family_pref_name)); + NSFont* font = [NSFont fontWithName:family_name size:[NSFont systemFontSize]]; + if (font && + [[font familyName] caseInsensitiveCompare:family_name] != NSOrderedSame) { + std::string new_family_name = base::SysNSStringToUTF8([font familyName]); + prefs->SetString(family_pref_name, new_family_name); + } +} +} // namespace namespace settings_utils { @@ -41,4 +63,10 @@ launchIdentifier:nil]; } +void ValidateSavedFonts(PrefService* prefs) { + ValidateFontFamily(prefs, prefs::kWebKitSerifFontFamily); + ValidateFontFamily(prefs, prefs::kWebKitSansSerifFontFamily); + ValidateFontFamily(prefs, prefs::kWebKitFixedFontFamily); +} + } // namespace settings_utils
diff --git a/chrome/browser/ui/webui/settings_utils_win.cc b/chrome/browser/ui/webui/settings_utils_win.cc index 8380d43e..b9ed44f 100644 --- a/chrome/browser/ui/webui/settings_utils_win.cc +++ b/chrome/browser/ui/webui/settings_utils_win.cc
@@ -19,6 +19,8 @@ #include "chrome/browser/browser_process.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/web_contents.h" +#include "ui/gfx/font.h" +#include "ui/gfx/platform_font_win.h" #include "ui/shell_dialogs/base_shell_dialog_win.h" #include "ui/views/win/hwnd_util.h" @@ -112,4 +114,13 @@ base::Bind(&base::DeletePointer<ManageCertificatesDialog>, dialog)); } +std::string MaybeGetLocalizedFontName(const std::string& font_name_or_list) { + std::string font_name = ResolveFontList(font_name_or_list); + if (font_name.empty()) + return font_name; + gfx::Font font(font_name, 12); // dummy font size + return static_cast<gfx::PlatformFontWin*>(font.platform_font()) + ->GetLocalizedFontName(); +} + } // namespace settings_utils
diff --git a/chrome/browser/ui/webui/uber/uber_ui.cc b/chrome/browser/ui/webui/uber/uber_ui.cc index aa7a4f95..966231d 100644 --- a/chrome/browser/ui/webui/uber/uber_ui.cc +++ b/chrome/browser/ui/webui/uber/uber_ui.cc
@@ -11,7 +11,6 @@ #include "chrome/browser/ui/webui/chrome_web_ui_controller_factory.h" #include "chrome/browser/ui/webui/extensions/extensions_ui.h" #include "chrome/browser/ui/webui/log_web_ui_url.h" -#include "chrome/browser/ui/webui/options/options_ui.h" #include "chrome/common/chrome_features.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/extensions/chrome_manifest_url_handlers.h" @@ -30,6 +29,10 @@ #include "content/public/browser/web_ui_data_source.h" #include "content/public/common/browser_side_navigation_policy.h" +#if defined(OS_CHROMEOS) +#include "chrome/browser/ui/webui/options/options_ui.h" +#endif + using content::NavigationController; using content::NavigationEntry; using content::RenderFrameHost; @@ -127,8 +130,10 @@ chrome::kChromeUIExtensionsHost); RegisterSubpage(chrome::kChromeUIHelpFrameURL, chrome::kChromeUIHelpHost); +#if defined(OS_CHROMEOS) RegisterSubpage(chrome::kChromeUISettingsFrameURL, chrome::kChromeUISettingsHost); +#endif RegisterSubpage(chrome::kChromeUIUberFrameURL, chrome::kChromeUIUberHost); }
diff --git a/chrome/chrome_paks.gni b/chrome/chrome_paks.gni index 953d88d..235ee70 100644 --- a/chrome/chrome_paks.gni +++ b/chrome/chrome_paks.gni
@@ -137,14 +137,12 @@ # New paks should be added here by default. sources += [ "$root_gen_dir/chrome/component_extension_resources.pak", - "$root_gen_dir/chrome/options_resources.pak", "$root_gen_dir/chrome/settings_resources.pak", "$root_gen_dir/content/browser/devtools/devtools_resources.pak", "$root_gen_dir/headless/headless_lib_resources.pak", ] deps += [ "//chrome/browser/resources:component_extension_resources", - "//chrome/browser/resources:options_resources", "//chrome/browser/resources:settings_resources", "//content/browser/devtools:devtools_resources", "//headless:resources", @@ -152,10 +150,12 @@ } if (is_chromeos) { sources += [ + "$root_gen_dir/chrome/options_resources.pak", "$root_gen_dir/components/chrome_apps/chrome_apps_resources.pak", "$root_gen_dir/ui/file_manager/file_manager_resources.pak", ] deps += [ + "//chrome/browser/resources:options_resources", "//components/chrome_apps:resources", "//ui/file_manager:resources", ]
diff --git a/chrome/common/url_constants.h b/chrome/common/url_constants.h index a7e788c2..c6221cf 100644 --- a/chrome/common/url_constants.h +++ b/chrome/common/url_constants.h
@@ -50,6 +50,7 @@ extern const char kChromeUIFlagsURL[]; extern const char kChromeUIFlashURL[]; extern const char kChromeUIGCMInternalsURL[]; +// TODO(dbeam): remove help-frame. extern const char kChromeUIHelpFrameURL[]; extern const char kChromeUIHelpURL[]; extern const char kChromeUIHistoryURL[]; @@ -75,6 +76,7 @@ extern const char kChromeUIMdSettingsURL[]; extern const char kChromeUISettingsURL[]; extern const char kChromeUIContentSettingsURL[]; +// TODO(dbeam): remove settings-frame. extern const char kChromeUISettingsFrameURL[]; extern const char kChromeUISigninEmailConfirmationURL[]; extern const char kChromeUISigninErrorURL[]; @@ -188,6 +190,7 @@ extern const char kChromeUIFlagsHost[]; extern const char kChromeUIFlashHost[]; extern const char kChromeUIGCMInternalsHost[]; +// TODO(dbeam): remove help-frame. extern const char kChromeUIHelpFrameHost[]; extern const char kChromeUIHelpHost[]; extern const char kChromeUIHangHost[];
diff --git a/chrome/renderer/extensions/automation_internal_custom_bindings.cc b/chrome/renderer/extensions/automation_internal_custom_bindings.cc index 4121198..d7bb2f65 100644 --- a/chrome/renderer/extensions/automation_internal_custom_bindings.cc +++ b/chrome/renderer/extensions/automation_internal_custom_bindings.cc
@@ -88,61 +88,21 @@ return result; } -// Compute the bounding box of a node, fixing nodes with empty bounds by -// unioning the bounds of their children. -static gfx::RectF ComputeLocalNodeBounds(TreeCache* cache, ui::AXNode* node) { - gfx::RectF bounds = node->data().location; - if (bounds.width() > 0 && bounds.height() > 0) - return bounds; - - // Compute the bounds of each child. - for (size_t i = 0; i < node->children().size(); i++) { - ui::AXNode* child = node->children()[i]; - gfx::RectF child_bounds = ComputeLocalNodeBounds(cache, child); - - // Ignore children that don't have valid bounds themselves. - if (child_bounds.width() == 0 || child_bounds.height() == 0) - continue; - - // For the first valid child, just set the bounds to that child's bounds. - if (bounds.width() == 0 || bounds.height() == 0) { - bounds = child_bounds; - continue; - } - - // Union each additional child's bounds. - bounds.Union(child_bounds); - } - - return bounds; -} - // Adjust the bounding box of a node from local to global coordinates, // walking up the parent hierarchy to offset by frame offsets and // scroll offsets. -static gfx::Rect ComputeGlobalNodeBounds(TreeCache* cache, - ui::AXNode* node, - gfx::RectF local_bounds) { +static gfx::Rect ComputeGlobalNodeBounds( + TreeCache* cache, + ui::AXNode* node, + gfx::RectF local_bounds = gfx::RectF()) { gfx::RectF bounds = local_bounds; + while (node) { - if (node->data().transform) - node->data().transform->TransformRect(&bounds); + bounds = cache->tree.RelativeToTreeBounds(node, bounds); - // Walk up to this node's container. This may cross a tree - // boundary, in which case GetParent() modifies |cache|, so we - // save the old cache temporarily. TreeCache* previous_cache = cache; - ui::AXNode* container = - cache->tree.GetFromId(node->data().offset_container_id); - if (!container) { - if (node == cache->tree.root()) { - container = cache->owner->GetParent(node, &cache); - } else { - container = cache->tree.root(); - } - } - - if (!container || container == node) + ui::AXNode* parent = cache->owner->GetParent(cache->tree.root(), &cache); + if (parent == node) break; // All trees other than the desktop tree are scaled by the device @@ -155,17 +115,7 @@ bounds.Scale(1.0 / scale_factor); } - gfx::RectF container_bounds = container->data().location; - bounds.Offset(container_bounds.x(), container_bounds.y()); - - int scroll_x = 0; - int scroll_y = 0; - if (container->data().GetIntAttribute(ui::AX_ATTR_SCROLL_X, &scroll_x) && - container->data().GetIntAttribute(ui::AX_ATTR_SCROLL_Y, &scroll_y)) { - bounds.Offset(-scroll_x, -scroll_y); - } - - node = container; + node = parent; } return gfx::ToEnclosingRect(bounds); @@ -569,9 +519,7 @@ RouteNodeIDFunction( "GetLocation", [](v8::Isolate* isolate, v8::ReturnValue<v8::Value> result, TreeCache* cache, ui::AXNode* node) { - gfx::RectF local_bounds = ComputeLocalNodeBounds(cache, node); - gfx::Rect global_bounds = - ComputeGlobalNodeBounds(cache, node, local_bounds); + gfx::Rect global_bounds = ComputeGlobalNodeBounds(cache, node); result.Set(RectToV8Object(isolate, global_bounds)); }); RouteNodeIDFunction( @@ -607,14 +555,14 @@ "GetBoundsForRange", [](v8::Isolate* isolate, v8::ReturnValue<v8::Value> result, TreeCache* cache, ui::AXNode* node, int start, int end) { - gfx::RectF local_bounds = ComputeLocalNodeBounds(cache, node); if (node->data().role != ui::AX_ROLE_INLINE_TEXT_BOX) { - gfx::Rect global_bounds = - ComputeGlobalNodeBounds(cache, node, local_bounds); + gfx::Rect global_bounds = ComputeGlobalNodeBounds(cache, node); result.Set(RectToV8Object(isolate, global_bounds)); } // Use character offsets to compute the local bounds of this subrange. + gfx::RectF local_bounds(0, 0, node->data().location.width(), + node->data().location.height()); std::string name = node->data().GetStringAttribute(ui::AX_ATTR_NAME); std::vector<int> character_offsets = node->data().GetIntListAttribute(ui::AX_ATTR_CHARACTER_OFFSETS);
diff --git a/chromeos/chromeos_switches.cc b/chromeos/chromeos_switches.cc index 42245cb4..910a9f4 100644 --- a/chromeos/chromeos_switches.cc +++ b/chromeos/chromeos_switches.cc
@@ -62,10 +62,6 @@ // Path for app's OEM manifest file. const char kAppOemManifestFile[] = "app-mode-oem-manifest"; -// Always starts ARC after login screen without Play Store in almost all cases. -// Secondary profile is an exception where ARC will not start. -const char kArcAlwaysStart[] = "arc-always-start"; - // Signals ARC support status on this device. This can take one of the // following three values. // - none: ARC is not installed on this device. (default) @@ -79,6 +75,14 @@ // Signals the availability of the ARC instance on this device. const char kArcAvailable[] = "arc-available"; +// Defines how to start ARC. This can take one of the following values: +// - always-start automatically start with Play Store UI support. +// - always-start-with-no-play-store automatically start without Play Store UI. +// In both cases ARC starts after login screen in almost all cases. Secondary +// profile is an exception where ARC won't start. +// If it is not set, then ARC is started in default mode. +const char kArcStartMode[] = "arc-start-mode"; + // Screenshot testing: specifies the directoru where artifacts will be stored. const char kArtifactsDir[] = "artifacts-dir";
diff --git a/chromeos/chromeos_switches.h b/chromeos/chromeos_switches.h index de55381e..9000ef0 100644 --- a/chromeos/chromeos_switches.h +++ b/chromeos/chromeos_switches.h
@@ -28,9 +28,9 @@ CHROMEOS_EXPORT extern const char kAllowRAInDevMode[]; CHROMEOS_EXPORT extern const char kAppAutoLaunched[]; CHROMEOS_EXPORT extern const char kAppOemManifestFile[]; -CHROMEOS_EXPORT extern const char kArcAlwaysStart[]; CHROMEOS_EXPORT extern const char kArcAvailability[]; CHROMEOS_EXPORT extern const char kArcAvailable[]; +CHROMEOS_EXPORT extern const char kArcStartMode[]; CHROMEOS_EXPORT extern const char kArtifactsDir[]; CHROMEOS_EXPORT extern const char kAshWebUIInit[]; CHROMEOS_EXPORT extern const char kCellularFirst[];
diff --git a/components/arc/arc_util.cc b/components/arc/arc_util.cc index 58133783..0942b9b 100644 --- a/components/arc/arc_util.cc +++ b/components/arc/arc_util.cc
@@ -30,6 +30,9 @@ constexpr char kAvailabilityNone[] = "none"; constexpr char kAvailabilityInstalled[] = "installed"; constexpr char kAvailabilityOfficiallySupported[] = "officially-supported"; +constexpr char kAlwaysStart[] = "always-start"; +constexpr char kAlwaysStartWithNoPlayStore[] = + "always-start-with-no-play-store"; void SetArcCpuRestrictionCallback( login_manager::ContainerCpuRestrictionState state, @@ -49,8 +52,8 @@ const auto* command_line = base::CommandLine::ForCurrentProcess(); if (command_line->HasSwitch(chromeos::switches::kArcAvailability)) { - std::string value = command_line->GetSwitchValueASCII( - chromeos::switches::kArcAvailability); + const std::string value = + command_line->GetSwitchValueASCII(chromeos::switches::kArcAvailability); DCHECK(value == kAvailabilityNone || value == kAvailabilityInstalled || value == kAvailabilityOfficiallySupported) << "Unknown flag value: " << value; @@ -67,14 +70,29 @@ base::FeatureList::IsEnabled(kEnableArcFeature)); } -bool ShouldArcAlwaysStart() { - return base::CommandLine::ForCurrentProcess()->HasSwitch( - chromeos::switches::kArcAlwaysStart); +bool IsPlayStoreAvailable() { + const auto* command_line = base::CommandLine::ForCurrentProcess(); + if (!command_line->HasSwitch(chromeos::switches::kArcStartMode)) + return true; + + const std::string value = + command_line->GetSwitchValueASCII(chromeos::switches::kArcStartMode); + return value != kAlwaysStartWithNoPlayStore; } -void SetArcAlwaysStartForTesting() { - base::CommandLine::ForCurrentProcess()->AppendSwitch( - chromeos::switches::kArcAlwaysStart); +bool ShouldArcAlwaysStart() { + const auto* command_line = base::CommandLine::ForCurrentProcess(); + if (!command_line->HasSwitch(chromeos::switches::kArcStartMode)) + return false; + const std::string value = + command_line->GetSwitchValueASCII(chromeos::switches::kArcStartMode); + return value == kAlwaysStartWithNoPlayStore || value == kAlwaysStart; +} + +void SetArcAlwaysStartForTesting(bool play_store_available) { + base::CommandLine::ForCurrentProcess()->AppendSwitchASCII( + chromeos::switches::kArcStartMode, + play_store_available ? kAlwaysStart : kAlwaysStartWithNoPlayStore); } bool IsArcKioskAvailable() {
diff --git a/components/arc/arc_util.h b/components/arc/arc_util.h index d653b5ac..ce129eb03 100644 --- a/components/arc/arc_util.h +++ b/components/arc/arc_util.h
@@ -34,13 +34,18 @@ // check, so it is ok to access them directly. bool IsArcAvailable(); +// Returns true if ARC image has Play Store package. +bool IsPlayStoreAvailable(); + // Returns true if ARC should always start within the primary user session // (opted in user or not), and other supported mode such as guest and Kiosk // mode. bool ShouldArcAlwaysStart(); // Enables to always start ARC for testing, by appending the command line flag. -void SetArcAlwaysStartForTesting(); +// If |bool play_store_available| is not set then flag that disables ARC Play +// Store UI is added. +void SetArcAlwaysStartForTesting(bool play_store_available); // Returns true if ARC is installed and running ARC kiosk apps on the current // device is officially supported.
diff --git a/components/arc/arc_util_unittest.cc b/components/arc/arc_util_unittest.cc index 0a52662..b8775211 100644 --- a/components/arc/arc_util_unittest.cc +++ b/components/arc/arc_util_unittest.cc
@@ -23,7 +23,7 @@ namespace arc { namespace { -// If an instance is created, based on the value passed to the consturctor, +// If an instance is created, based on the value passed to the constructor, // EnableARC feature is enabled/disabled in the scope. class ScopedArcFeature { public: @@ -239,5 +239,21 @@ EXPECT_FALSE(IsArcAllowedForUser(ephemeral_user)); } +TEST_F(ArcUtilTest, ArcStartModeDefault) { + auto* command_line = base::CommandLine::ForCurrentProcess(); + command_line->InitFromArgv({"", "--arc-availability=installed"}); + EXPECT_FALSE(ShouldArcAlwaysStart()); + EXPECT_TRUE(IsPlayStoreAvailable()); +} + +TEST_F(ArcUtilTest, ArcStartModeWithoutPlayStore) { + auto* command_line = base::CommandLine::ForCurrentProcess(); + command_line->InitFromArgv( + {"", "--arc-availability=installed", + "--arc-start-mode=always-start-with-no-play-store"}); + EXPECT_TRUE(ShouldArcAlwaysStart()); + EXPECT_FALSE(IsPlayStoreAvailable()); +} + } // namespace } // namespace arc
diff --git a/components/content_settings/core/common/content_settings.cc b/components/content_settings/core/common/content_settings.cc index 4cf2d13..5e8a2b3 100644 --- a/components/content_settings/core/common/content_settings.cc +++ b/components/content_settings/core/common/content_settings.cc
@@ -57,6 +57,7 @@ {CONTENT_SETTINGS_TYPE_PERMISSION_AUTOBLOCKER_DATA, 31}, {CONTENT_SETTINGS_TYPE_SUBRESOURCE_FILTER, 32}, {CONTENT_SETTINGS_TYPE_SUBRESOURCE_FILTER_DATA, 33}, + {CONTENT_SETTINGS_TYPE_PASSWORD_PROTECTION, 34}, }; int ContentSettingTypeToHistogramValue(ContentSettingsType content_setting,
diff --git a/components/guest_view/renderer/guest_view_request.cc b/components/guest_view/renderer/guest_view_request.cc index ea96bc9..b9be455 100644 --- a/components/guest_view/renderer/guest_view_request.cc +++ b/components/guest_view/renderer/guest_view_request.cc
@@ -91,14 +91,7 @@ v8::HandleScope handle_scope(isolate()); blink::WebFrame* frame = guest_proxy_render_view->GetWebView()->MainFrame(); - // TODO(lazyboy,nasko): The WebLocalFrame branch is not used when running - // on top of out-of-process iframes. Remove it once the code is converted. - v8::Local<v8::Value> window; - if (frame->IsWebLocalFrame()) { - window = frame->MainWorldScriptContext()->Global(); - } else { - window = frame->ToWebRemoteFrame()->GlobalProxy(); - } + v8::Local<v8::Value> window = frame->GlobalProxy(); const int argc = 1; std::unique_ptr<v8::Local<v8::Value>[]> argv(new v8::Local<v8::Value>[argc]);
diff --git a/components/safe_browsing/password_protection/password_protection_request.cc b/components/safe_browsing/password_protection/password_protection_request.cc index 909c848..f23e47e 100644 --- a/components/safe_browsing/password_protection/password_protection_request.cc +++ b/components/safe_browsing/password_protection/password_protection_request.cc
@@ -36,12 +36,14 @@ password_form_action_(password_form_action), password_form_frame_url_(password_form_frame_url), saved_domain_(saved_domain), - request_type_(type), + trigger_type_(type), password_field_exists_(password_field_exists), password_protection_service_(pps), request_timeout_in_ms_(request_timeout_in_ms), weakptr_factory_(this) { DCHECK_CURRENTLY_ON(BrowserThread::UI); + DCHECK(trigger_type_ == LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE || + trigger_type_ == LoginReputationClientRequest::PASSWORD_REUSE_EVENT); } PasswordProtectionRequest::~PasswordProtectionRequest() { @@ -85,7 +87,7 @@ std::unique_ptr<LoginReputationClientResponse> cached_response = base::MakeUnique<LoginReputationClientResponse>(); auto verdict = password_protection_service_->GetCachedVerdict( - main_frame_url_, cached_response.get()); + main_frame_url_, trigger_type_, cached_response.get()); if (verdict != LoginReputationClientResponse::VERDICT_TYPE_UNSPECIFIED) Finish(PasswordProtectionService::RESPONSE_ALREADY_CACHED, std::move(cached_response)); @@ -96,11 +98,11 @@ void PasswordProtectionRequest::FillRequestProto() { request_proto_ = base::MakeUnique<LoginReputationClientRequest>(); request_proto_->set_page_url(main_frame_url_.spec()); - request_proto_->set_trigger_type(request_type_); - password_protection_service_->FillUserPopulation(request_type_, + request_proto_->set_trigger_type(trigger_type_); + password_protection_service_->FillUserPopulation(trigger_type_, request_proto_.get()); request_proto_->set_stored_verdict_cnt( - password_protection_service_->GetStoredVerdictCount()); + password_protection_service_->GetStoredVerdictCount(trigger_type_)); LoginReputationClientRequest::Frame* main_frame = request_proto_->add_frames(); main_frame->set_url(main_frame_url_.spec()); @@ -108,7 +110,7 @@ password_protection_service_->FillReferrerChain( main_frame_url_, -1 /* tab id not available */, main_frame); - switch (request_type_) { + switch (trigger_type_) { case LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE: { LoginReputationClientRequest::Frame::Form* password_form; if (password_form_frame_url_ == main_frame_url_) { @@ -247,7 +249,7 @@ DCHECK_CURRENTLY_ON(BrowserThread::UI); tracker_.TryCancelAll(); - if (request_type_ == LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE) { + if (trigger_type_ == LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE) { UMA_HISTOGRAM_ENUMERATION(kPasswordOnFocusRequestOutcomeHistogramName, outcome, PasswordProtectionService::MAX_OUTCOME); } else { @@ -256,7 +258,7 @@ } if (outcome == PasswordProtectionService::SUCCEEDED && response) { - switch (request_type_) { + switch (trigger_type_) { case LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE: UMA_HISTOGRAM_ENUMERATION( "PasswordProtection.Verdict.PasswordFieldOnFocus",
diff --git a/components/safe_browsing/password_protection/password_protection_request.h b/components/safe_browsing/password_protection/password_protection_request.h index 721739b..756a65d 100644 --- a/components/safe_browsing/password_protection/password_protection_request.h +++ b/components/safe_browsing/password_protection/password_protection_request.h
@@ -74,8 +74,8 @@ content::WebContents* web_contents() const { return web_contents_; } - LoginReputationClientRequest::TriggerType request_type() const { - return request_type_; + LoginReputationClientRequest::TriggerType trigger_type() const { + return trigger_type_; } private: @@ -129,7 +129,7 @@ const std::string saved_domain_; // If this request is for unfamiliar login page or for a password reuse event. - const LoginReputationClientRequest::TriggerType request_type_; + const LoginReputationClientRequest::TriggerType trigger_type_; // If there is a password field on the page. const bool password_field_exists_;
diff --git a/components/safe_browsing/password_protection/password_protection_service.cc b/components/safe_browsing/password_protection/password_protection_service.cc index c7ec2a9d..230f115 100644 --- a/components/safe_browsing/password_protection/password_protection_service.cc +++ b/components/safe_browsing/password_protection/password_protection_service.cc
@@ -38,6 +38,7 @@ const int kRequestTimeoutMs = 10000; const char kPasswordProtectionRequestUrl[] = "https://sb-ssl.google.com/safebrowsing/clientreport/login"; +const char kPasswordOnFocusCacheKey[] = "password_on_focus_cache_key"; // Helper function to determine if the given origin matches content settings // map's patterns. @@ -87,7 +88,8 @@ scoped_refptr<net::URLRequestContextGetter> request_context_getter, HistoryService* history_service, HostContentSettingsMap* host_content_settings_map) - : stored_verdict_count_(-1), + : stored_verdict_count_password_on_focus_(-1), + stored_verdict_count_password_entry_(-1), database_manager_(database_manager), request_context_getter_(request_context_getter), history_service_observer_(this), @@ -122,24 +124,49 @@ hostname.find('.') != std::string::npos; } +// We cache both types of pings under the same content settings type ( +// CONTENT_SETTINGS_TYPE_PASSWORD_PROTECTION). Since UNFAMILIAR_LOGING_PAGE +// verdicts are only enabled on extended reporting users, we cache them one +// layer lower in the content setting DictionaryValue than PASSWORD_REUSE_EVENT +// verdicts. +// In other words, to cache a UNFAMILIAR_LOGIN_PAGE verdict we needs two levels +// of keys: (1) origin, (2) cache expression returned in verdict. +// To cache a PASSWORD_REUSE_EVENT, three levels of keys are used: +// (1) origin, (2) 2nd level key is always |kPasswordOnFocusCacheKey|, +// (3) cache expression. LoginReputationClientResponse::VerdictType PasswordProtectionService::GetCachedVerdict( const GURL& url, + TriggerType trigger_type, LoginReputationClientResponse* out_response) { + DCHECK(trigger_type == LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE || + trigger_type == LoginReputationClientRequest::PASSWORD_REUSE_EVENT); + if (!url.is_valid()) return LoginReputationClientResponse::VERDICT_TYPE_UNSPECIFIED; - DCHECK(content_settings_); - GURL hostname = GetHostNameWithHTTPScheme(url); - std::unique_ptr<base::DictionaryValue> verdict_dictionary = + std::unique_ptr<base::DictionaryValue> cache_dictionary = base::DictionaryValue::From(content_settings_->GetWebsiteSetting( hostname, GURL(), CONTENT_SETTINGS_TYPE_PASSWORD_PROTECTION, std::string(), nullptr)); - // Return early if there is no verdict cached for this origin. - if (!verdict_dictionary.get() || verdict_dictionary->empty()) + + if (!cache_dictionary.get() || cache_dictionary->empty()) return LoginReputationClientResponse::VERDICT_TYPE_UNSPECIFIED; + base::DictionaryValue* verdict_dictionary = nullptr; + if (trigger_type == LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE) { + // All UNFAMILIAR_LOGIN_PAGE verdicts (a.k.a password on focus ping) + // are cached under |kPasswordOnFocusCacheKey|. + if (!cache_dictionary->HasKey(kPasswordOnFocusCacheKey)) { + return LoginReputationClientResponse::VERDICT_TYPE_UNSPECIFIED; + } + DCHECK(cache_dictionary->GetDictionaryWithoutPathExpansion( + kPasswordOnFocusCacheKey, &verdict_dictionary)); + } else { + verdict_dictionary = cache_dictionary.get(); + } + std::vector<std::string> paths; GeneratePathVariantsWithoutQuery(url, &paths); int max_path_depth = -1; @@ -148,8 +175,12 @@ // For all the verdicts of the same origin, we key them by |cache_expression|. // Its corresponding value is a DictionaryValue contains its creation time and // the serialized verdict proto. - for (base::DictionaryValue::Iterator it(*verdict_dictionary.get()); - !it.IsAtEnd(); it.Advance()) { + for (base::DictionaryValue::Iterator it(*verdict_dictionary); !it.IsAtEnd(); + it.Advance()) { + if (trigger_type == LoginReputationClientRequest::PASSWORD_REUSE_EVENT && + it.key() == kPasswordOnFocusCacheKey) { + continue; + } base::DictionaryValue* verdict_entry = nullptr; CHECK(verdict_dictionary->GetDictionaryWithoutPathExpansion( it.key() /* cache_expression */, &verdict_entry)); @@ -180,39 +211,64 @@ void PasswordProtectionService::CacheVerdict( const GURL& url, + TriggerType trigger_type, LoginReputationClientResponse* verdict, const base::Time& receive_time) { DCHECK(verdict); DCHECK(content_settings_); + DCHECK(trigger_type == LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE || + trigger_type == LoginReputationClientRequest::PASSWORD_REUSE_EVENT); GURL hostname = GetHostNameWithHTTPScheme(url); - std::unique_ptr<base::DictionaryValue> verdict_dictionary = + int* stored_verdict_count = + trigger_type == LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE + ? &stored_verdict_count_password_on_focus_ + : &stored_verdict_count_password_entry_; + std::unique_ptr<base::DictionaryValue> cache_dictionary = base::DictionaryValue::From(content_settings_->GetWebsiteSetting( hostname, GURL(), CONTENT_SETTINGS_TYPE_PASSWORD_PROTECTION, std::string(), nullptr)); - if (!verdict_dictionary.get()) - verdict_dictionary = base::MakeUnique<base::DictionaryValue>(); + if (!cache_dictionary.get()) + cache_dictionary = base::MakeUnique<base::DictionaryValue>(); std::unique_ptr<base::DictionaryValue> verdict_entry = CreateDictionaryFromVerdict(verdict, receive_time); + base::DictionaryValue* verdict_dictionary = nullptr; + if (trigger_type == LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE) { + // All UNFAMILIAR_LOGIN_PAGE verdicts (a.k.a password on focus ping) + // are cached under |kPasswordOnFocusCacheKey|. + if (!cache_dictionary->HasKey(kPasswordOnFocusCacheKey)) { + cache_dictionary->SetDictionaryWithoutPathExpansion( + kPasswordOnFocusCacheKey, base::MakeUnique<base::DictionaryValue>()); + } + DCHECK(cache_dictionary->GetDictionaryWithoutPathExpansion( + kPasswordOnFocusCacheKey, &verdict_dictionary)); + } else { + verdict_dictionary = cache_dictionary.get(); + } + // Increases stored verdict count if we haven't seen this cache expression // before. if (!verdict_dictionary->HasKey(verdict->cache_expression())) - stored_verdict_count_ = GetStoredVerdictCount() + 1; + *stored_verdict_count = GetStoredVerdictCount(trigger_type) + 1; // If same cache_expression is already in this verdict_dictionary, we simply // override it. verdict_dictionary->SetWithoutPathExpansion(verdict->cache_expression(), std::move(verdict_entry)); content_settings_->SetWebsiteSettingDefaultScope( hostname, GURL(), CONTENT_SETTINGS_TYPE_PASSWORD_PROTECTION, - std::string(), std::move(verdict_dictionary)); + std::string(), std::move(cache_dictionary)); } void PasswordProtectionService::CleanUpExpiredVerdicts() { DCHECK(content_settings_); - if (GetStoredVerdictCount() <= 0) + + if (GetStoredVerdictCount( + LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE) <= 0 && + GetStoredVerdictCount( + LoginReputationClientRequest::PASSWORD_REUSE_EVENT) <= 0) return; ContentSettingsForOneType password_protection_settings; @@ -224,44 +280,29 @@ password_protection_settings) { GURL primary_pattern_url = GURL(source.primary_pattern.ToString()); // Find all verdicts associated with this origin. - std::unique_ptr<base::DictionaryValue> verdict_dictionary = + std::unique_ptr<base::DictionaryValue> cache_dictionary = base::DictionaryValue::From(content_settings_->GetWebsiteSetting( primary_pattern_url, GURL(), CONTENT_SETTINGS_TYPE_PASSWORD_PROTECTION, std::string(), nullptr)); - std::vector<std::string> expired_keys; - for (base::DictionaryValue::Iterator it(*verdict_dictionary.get()); - !it.IsAtEnd(); it.Advance()) { - base::DictionaryValue* verdict_entry = nullptr; - CHECK(verdict_dictionary->GetDictionaryWithoutPathExpansion( - it.key(), &verdict_entry)); - int verdict_received_time; - LoginReputationClientResponse verdict; - CHECK(ParseVerdictEntry(verdict_entry, &verdict_received_time, &verdict)); + bool has_expired_password_on_focus_entry = RemoveExpiredVerdicts( + LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE, + cache_dictionary.get()); + bool has_expired_password_reuse_entry = RemoveExpiredVerdicts( + LoginReputationClientRequest::PASSWORD_REUSE_EVENT, + cache_dictionary.get()); - if (IsCacheExpired(verdict_received_time, verdict.cache_duration_sec())) { - // Since DictionaryValue::Iterator cannot be used to modify the - // dictionary, we record the keys of expired verdicts in |expired_keys| - // and remove them in the next for-loop. - expired_keys.push_back(it.key()); - } - } - - for (const std::string& key : expired_keys) { - verdict_dictionary->RemoveWithoutPathExpansion(key, nullptr); - stored_verdict_count_--; - } - - if (verdict_dictionary->size() == 0u) { + if (cache_dictionary->size() == 0u) { content_settings_->ClearSettingsForOneTypeWithPredicate( CONTENT_SETTINGS_TYPE_PASSWORD_PROTECTION, base::Time(), base::Bind(&OriginMatchPrimaryPattern, primary_pattern_url)); - } else if (expired_keys.size() > 0u) { + } else if (has_expired_password_on_focus_entry || + has_expired_password_reuse_entry) { // Set the website setting of this origin with the updated // |verdict_diectionary|. content_settings_->SetWebsiteSettingDefaultScope( primary_pattern_url, GURL(), CONTENT_SETTINGS_TYPE_PASSWORD_PROTECTION, std::string(), - std::move(verdict_dictionary)); + std::move(cache_dictionary)); } } } @@ -272,14 +313,15 @@ const GURL& password_form_action, const GURL& password_form_frame_url, const std::string& saved_domain, - LoginReputationClientRequest::TriggerType type, + TriggerType trigger_type, bool password_field_exists) { DCHECK_CURRENTLY_ON(BrowserThread::UI); scoped_refptr<PasswordProtectionRequest> request( new PasswordProtectionRequest( web_contents, main_frame_url, password_form_action, - password_form_frame_url, saved_domain, type, password_field_exists, - this, GetRequestTimeoutInMS())); + password_form_frame_url, saved_domain, trigger_type, + password_field_exists, this, GetRequestTimeoutInMS())); + DCHECK(request); request->Start(); requests_.insert(std::move(request)); @@ -332,11 +374,11 @@ if (response) { if (!already_cached) { - CacheVerdict(request->main_frame_url(), response.get(), - base::Time::Now()); + CacheVerdict(request->main_frame_url(), request->trigger_type(), + response.get(), base::Time::Now()); } - if (request->request_type() == + if (request->trigger_type() == LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE && response->verdict_type() == LoginReputationClientResponse::PHISHING && base::FeatureList::IsEnabled(kPasswordProtectionInterstitial)) { @@ -379,30 +421,49 @@ return url.Resolve("?key=" + net::EscapeQueryParamValue(api_key, true)); } -int PasswordProtectionService::GetStoredVerdictCount() { +int PasswordProtectionService::GetStoredVerdictCount(TriggerType trigger_type) { DCHECK(content_settings_); + DCHECK(trigger_type == LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE || + trigger_type == LoginReputationClientRequest::PASSWORD_REUSE_EVENT); + int* stored_verdict_count = + trigger_type == LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE + ? &stored_verdict_count_password_on_focus_ + : &stored_verdict_count_password_entry_; // If we have already computed this, return its value. - if (stored_verdict_count_ >= 0) - return stored_verdict_count_; + if (*stored_verdict_count >= 0) + return *stored_verdict_count; ContentSettingsForOneType password_protection_settings; content_settings_->GetSettingsForOneType( CONTENT_SETTINGS_TYPE_PASSWORD_PROTECTION, std::string(), &password_protection_settings); - stored_verdict_count_ = 0; + stored_verdict_count_password_on_focus_ = 0; + stored_verdict_count_password_entry_ = 0; if (password_protection_settings.empty()) return 0; for (const ContentSettingPatternSource& source : password_protection_settings) { - std::unique_ptr<base::DictionaryValue> verdict_dictionary = + std::unique_ptr<base::DictionaryValue> cache_dictionary = base::DictionaryValue::From(content_settings_->GetWebsiteSetting( GURL(source.primary_pattern.ToString()), GURL(), CONTENT_SETTINGS_TYPE_PASSWORD_PROTECTION, std::string(), nullptr)); - if (verdict_dictionary.get() && !verdict_dictionary->empty()) - stored_verdict_count_ += static_cast<int>(verdict_dictionary->size()); + if (cache_dictionary.get() && !cache_dictionary->empty()) { + stored_verdict_count_password_entry_ += + static_cast<int>(cache_dictionary->size()); + if (cache_dictionary->HasKey(kPasswordOnFocusCacheKey)) { + // Substracts 1 from password_entry count if |kPasswordOnFocusCacheKey| + // presents. + stored_verdict_count_password_entry_ -= 1; + base::DictionaryValue* password_on_focus_dict = nullptr; + cache_dictionary->GetDictionaryWithoutPathExpansion( + kPasswordOnFocusCacheKey, &password_on_focus_dict); + stored_verdict_count_password_on_focus_ += + static_cast<int>(password_on_focus_dict->size()); + } + } } - return stored_verdict_count_; + return *stored_verdict_count; } int PasswordProtectionService::GetRequestTimeoutInMS() { @@ -410,7 +471,7 @@ } void PasswordProtectionService::FillUserPopulation( - const LoginReputationClientRequest::TriggerType& request_type, + TriggerType trigger_type, LoginReputationClientRequest* request_proto) { ChromeUserPopulation* user_population = request_proto->mutable_population(); user_population->set_user_population( @@ -440,8 +501,10 @@ bool expired, const history::URLRows& deleted_rows, const std::set<GURL>& favicon_urls) { - if (stored_verdict_count_ <= 0) + if (stored_verdict_count_password_on_focus_ <= 0 && + stored_verdict_count_password_entry_ <= 0) { return; + } BrowserThread::PostTask( BrowserThread::UI, FROM_HERE, @@ -463,7 +526,8 @@ if (all_history) { content_settings_->ClearSettingsForOneType( CONTENT_SETTINGS_TYPE_PASSWORD_PROTECTION); - stored_verdict_count_ = 0; + stored_verdict_count_password_on_focus_ = 0; + stored_verdict_count_password_entry_ = 0; return; } @@ -474,24 +538,104 @@ for (const history::URLRow& row : deleted_rows) { if (!row.url().SchemeIsHTTPOrHTTPS()) continue; + GURL url_key = GetHostNameWithHTTPScheme(row.url()); - std::unique_ptr<base::DictionaryValue> verdict_dictionary = - base::DictionaryValue::From(content_settings_->GetWebsiteSetting( - url_key, GURL(), CONTENT_SETTINGS_TYPE_PASSWORD_PROTECTION, - std::string(), nullptr)); - - // Move on if we have no cached verdict for this deleted history row. - if (!verdict_dictionary.get() || verdict_dictionary->empty()) - continue; - - int verdict_count = static_cast<int>(verdict_dictionary->size()); - stored_verdict_count_ = GetStoredVerdictCount() - verdict_count; + stored_verdict_count_password_on_focus_ = + GetStoredVerdictCount( + LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE) - + GetVerdictCountForURL( + url_key, LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE); + stored_verdict_count_password_entry_ = + GetStoredVerdictCount( + LoginReputationClientRequest::PASSWORD_REUSE_EVENT) - + GetVerdictCountForURL( + url_key, LoginReputationClientRequest::PASSWORD_REUSE_EVENT); content_settings_->ClearSettingsForOneTypeWithPredicate( CONTENT_SETTINGS_TYPE_PASSWORD_PROTECTION, base::Time(), base::Bind(&OriginMatchPrimaryPattern, url_key)); } } +int PasswordProtectionService::GetVerdictCountForURL(const GURL& url, + TriggerType trigger_type) { + DCHECK(trigger_type == LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE || + trigger_type == LoginReputationClientRequest::PASSWORD_REUSE_EVENT); + std::unique_ptr<base::DictionaryValue> cache_dictionary = + base::DictionaryValue::From(content_settings_->GetWebsiteSetting( + url, GURL(), CONTENT_SETTINGS_TYPE_PASSWORD_PROTECTION, std::string(), + nullptr)); + if (!cache_dictionary.get() || cache_dictionary->empty()) + return 0; + + if (trigger_type == LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE) { + base::DictionaryValue* password_on_focus_dict = nullptr; + cache_dictionary->GetDictionaryWithoutPathExpansion( + kPasswordOnFocusCacheKey, &password_on_focus_dict); + return password_on_focus_dict ? password_on_focus_dict->size() : 0; + } else { + return cache_dictionary->HasKey(kPasswordOnFocusCacheKey) + ? cache_dictionary->size() - 1 + : cache_dictionary->size(); + } +} + +bool PasswordProtectionService::RemoveExpiredVerdicts( + TriggerType trigger_type, + base::DictionaryValue* cache_dictionary) { + DCHECK(trigger_type == LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE || + trigger_type == LoginReputationClientRequest::PASSWORD_REUSE_EVENT); + base::DictionaryValue* verdict_dictionary = nullptr; + if (trigger_type == LoginReputationClientRequest::PASSWORD_REUSE_EVENT) { + verdict_dictionary = cache_dictionary; + } else { + if (!cache_dictionary->GetDictionaryWithoutPathExpansion( + kPasswordOnFocusCacheKey, &verdict_dictionary)) { + return false; + } + } + + if (!verdict_dictionary || verdict_dictionary->empty()) + return false; + + std::vector<std::string> expired_keys; + for (base::DictionaryValue::Iterator it(*verdict_dictionary); !it.IsAtEnd(); + it.Advance()) { + if (trigger_type == LoginReputationClientRequest::PASSWORD_REUSE_EVENT && + it.key() == std::string(kPasswordOnFocusCacheKey)) + continue; + + base::DictionaryValue* verdict_entry = nullptr; + CHECK(verdict_dictionary->GetDictionaryWithoutPathExpansion( + it.key(), &verdict_entry)); + int verdict_received_time; + LoginReputationClientResponse verdict; + CHECK(ParseVerdictEntry(verdict_entry, &verdict_received_time, &verdict)); + + if (IsCacheExpired(verdict_received_time, verdict.cache_duration_sec())) { + // Since DictionaryValue::Iterator cannot be used to modify the + // dictionary, we record the keys of expired verdicts in |expired_keys| + // and remove them in the next for-loop. + expired_keys.push_back(it.key()); + } + } + + for (const std::string& key : expired_keys) { + verdict_dictionary->RemoveWithoutPathExpansion(key, nullptr); + if (trigger_type == LoginReputationClientRequest::PASSWORD_REUSE_EVENT) + stored_verdict_count_password_entry_--; + else + stored_verdict_count_password_on_focus_--; + } + + if (trigger_type == LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE && + verdict_dictionary->size() == 0U) { + cache_dictionary->RemoveWithoutPathExpansion(kPasswordOnFocusCacheKey, + nullptr); + } + + return expired_keys.size() > 0U; +} + // static bool PasswordProtectionService::ParseVerdictEntry( base::DictionaryValue* verdict_entry,
diff --git a/components/safe_browsing/password_protection/password_protection_service.h b/components/safe_browsing/password_protection/password_protection_service.h index 89870aa..10036f4 100644 --- a/components/safe_browsing/password_protection/password_protection_service.h +++ b/components/safe_browsing/password_protection/password_protection_service.h
@@ -49,6 +49,7 @@ // HostContentSettingsMap instance. class PasswordProtectionService : public history::HistoryServiceObserver { public: + using TriggerType = LoginReputationClientRequest::TriggerType; // The outcome of the request. These values are used for UMA. // DO NOT CHANGE THE ORDERING OF THESE VALUES. enum RequestOutcome { @@ -87,11 +88,13 @@ // any thread. LoginReputationClientResponse::VerdictType GetCachedVerdict( const GURL& url, + TriggerType trigger_type, LoginReputationClientResponse* out_response); - // Stores |verdict| in |settings| based on |url|, |verdict| and - // |receive_time|. + // Stores |verdict| in |settings| based on its |trigger_type|, |url|, + // |verdict| and |receive_time|. virtual void CacheVerdict(const GURL& url, + TriggerType trigger_type, LoginReputationClientResponse* verdict, const base::Time& receive_time); @@ -106,7 +109,7 @@ const GURL& password_form_action, const GURL& password_form_frame_url, const std::string& saved_domain, - LoginReputationClientRequest::TriggerType type, + TriggerType trigger_type, bool password_field_exists); virtual void MaybeStartPasswordFieldOnFocusRequest( @@ -152,9 +155,9 @@ // the requests. void CancelPendingRequests(); - // Gets the total number of verdict (no matter expired or not) we cached for - // current active profile. - virtual int GetStoredVerdictCount(); + // Gets the total number of verdicts of the specified |trigger_type| we cached + // for this profile. This counts both expired and active verdicts. + virtual int GetStoredVerdictCount(TriggerType trigger_type); scoped_refptr<net::URLRequestContextGetter> request_context_getter() { return request_context_getter_; @@ -173,9 +176,8 @@ int event_tab_id, // -1 if tab id is not available. LoginReputationClientRequest::Frame* frame) = 0; - void FillUserPopulation( - const LoginReputationClientRequest::TriggerType& request_type, - LoginReputationClientRequest* request_proto); + void FillUserPopulation(TriggerType trigger_type, + LoginReputationClientRequest* request_proto); virtual bool IsExtendedReporting() = 0; @@ -223,6 +225,15 @@ void RemoveContentSettingsOnURLsDeleted(bool all_history, const history::URLRows& deleted_rows); + // Helper function called by RemoveContentSettingsOnURLsDeleted(..). It + // calculate the number of verdicts of |type| that associate with |url|. + int GetVerdictCountForURL(const GURL& url, TriggerType type); + + // Remove verdict of |type| from |cache_dictionary|. Return false if no + // verdict removed, true otherwise. + bool RemoveExpiredVerdicts(TriggerType type, + base::DictionaryValue* cache_dictionary); + static bool ParseVerdictEntry(base::DictionaryValue* verdict_entry, int* out_verdict_received_time, LoginReputationClientResponse* out_verdict); @@ -245,8 +256,12 @@ static void RecordNoPingingReason(const base::Feature& feature, RequestOutcome reason); - // Number of verdict stored for this profile. - int stored_verdict_count_; + // Number of verdict stored for this profile for password on focus pings. + int stored_verdict_count_password_on_focus_; + + // Number of verdict stored for this profile for protected password entry + // pings. + int stored_verdict_count_password_entry_; scoped_refptr<SafeBrowsingDatabaseManager> database_manager_;
diff --git a/components/safe_browsing/password_protection/password_protection_service_unittest.cc b/components/safe_browsing/password_protection/password_protection_service_unittest.cc index d297ef1..1baee7c 100644 --- a/components/safe_browsing/password_protection/password_protection_service_unittest.cc +++ b/components/safe_browsing/password_protection/password_protection_service_unittest.cc
@@ -201,18 +201,19 @@ } void CacheVerdict(const GURL& url, + LoginReputationClientRequest::TriggerType trigger, LoginReputationClientResponse::VerdictType verdict, int cache_duration_sec, const std::string& cache_expression, const base::Time& verdict_received_time) { LoginReputationClientResponse response( CreateVerdictProto(verdict, cache_duration_sec, cache_expression)); - password_protection_service_->CacheVerdict(url, &response, + password_protection_service_->CacheVerdict(url, trigger, &response, verdict_received_time); } - size_t GetStoredVerdictCount() { - return password_protection_service_->GetStoredVerdictCount(); + size_t GetStoredVerdictCount(LoginReputationClientRequest::TriggerType type) { + return password_protection_service_->GetStoredVerdictCount(type); } protected: @@ -304,80 +305,173 @@ GURL("http://evil.com/worse/index.html"), cache_expression_with_slash)); } -TEST_F(PasswordProtectionServiceTest, TestCachedVerdicts) { - ASSERT_EQ(0U, GetStoredVerdictCount()); +TEST_F(PasswordProtectionServiceTest, TestCachePasswordReuseVerdicts) { + ASSERT_EQ(0U, GetStoredVerdictCount( + LoginReputationClientRequest::PASSWORD_REUSE_EVENT)); + // Assume each verdict has a TTL of 10 minutes. // Cache a verdict for http://www.test.com/foo/index.html CacheVerdict(GURL("http://www.test.com/foo/index.html"), + LoginReputationClientRequest::PASSWORD_REUSE_EVENT, LoginReputationClientResponse::SAFE, 10 * 60, "test.com/foo", base::Time::Now()); - EXPECT_EQ(1U, GetStoredVerdictCount()); + EXPECT_EQ(1U, GetStoredVerdictCount( + LoginReputationClientRequest::PASSWORD_REUSE_EVENT)); // Cache another verdict with the some origin and cache_expression should // override the cache. CacheVerdict(GURL("http://www.test.com/foo/index2.html"), + LoginReputationClientRequest::PASSWORD_REUSE_EVENT, LoginReputationClientResponse::PHISHING, 10 * 60, "test.com/foo", base::Time::Now()); - EXPECT_EQ(1U, GetStoredVerdictCount()); + EXPECT_EQ(1U, GetStoredVerdictCount( + LoginReputationClientRequest::PASSWORD_REUSE_EVENT)); LoginReputationClientResponse out_verdict; - EXPECT_EQ(LoginReputationClientResponse::PHISHING, - password_protection_service_->GetCachedVerdict( - GURL("http://www.test.com/foo/index2.html"), &out_verdict)); + EXPECT_EQ( + LoginReputationClientResponse::PHISHING, + password_protection_service_->GetCachedVerdict( + GURL("http://www.test.com/foo/index2.html"), + LoginReputationClientRequest::PASSWORD_REUSE_EVENT, &out_verdict)); // Cache another verdict with the same origin but different cache_expression // will not increase setting count, but will increase the number of verdicts // in the given origin. CacheVerdict(GURL("http://www.test.com/bar/index2.html"), + LoginReputationClientRequest::PASSWORD_REUSE_EVENT, LoginReputationClientResponse::SAFE, 10 * 60, "test.com/bar", base::Time::Now()); - EXPECT_EQ(2U, GetStoredVerdictCount()); + EXPECT_EQ(2U, GetStoredVerdictCount( + LoginReputationClientRequest::PASSWORD_REUSE_EVENT)); + + // Now cache a UNFAMILIAR_LOGIN_PAGE verdict, stored verdict count for + // PASSWORD_REUSE_EVENT should be the same. + CacheVerdict(GURL("http://www.test.com/foobar/index3.html"), + LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE, + LoginReputationClientResponse::SAFE, 10 * 60, "test.com/foobar", + base::Time::Now()); + EXPECT_EQ(2U, GetStoredVerdictCount( + LoginReputationClientRequest::PASSWORD_REUSE_EVENT)); + EXPECT_EQ(1U, GetStoredVerdictCount( + LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE)); +} + +TEST_F(PasswordProtectionServiceTest, TestCacheUnfamiliarLoginVerdicts) { + ASSERT_EQ(0U, GetStoredVerdictCount( + LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE)); + + // Assume each verdict has a TTL of 10 minutes. + // Cache a verdict for http://www.test.com/foo/index.html + CacheVerdict(GURL("http://www.test.com/foo/index.html"), + LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE, + LoginReputationClientResponse::SAFE, 10 * 60, "test.com/foo", + base::Time::Now()); + + EXPECT_EQ(1U, GetStoredVerdictCount( + LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE)); + + // Cache another verdict with the same origin but different cache_expression + // will not increase setting count, but will increase the number of verdicts + // in the given origin. + CacheVerdict(GURL("http://www.test.com/bar/index2.html"), + LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE, + LoginReputationClientResponse::SAFE, 10 * 60, "test.com/bar", + base::Time::Now()); + EXPECT_EQ(2U, GetStoredVerdictCount( + LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE)); + + // Now cache a PASSWORD_REUSE_EVENT verdict, stored verdict count for + // UNFAMILIAR_LOGIN_PAGE should be the same. + CacheVerdict(GURL("http://www.test.com/foobar/index3.html"), + LoginReputationClientRequest::PASSWORD_REUSE_EVENT, + LoginReputationClientResponse::SAFE, 10 * 60, "test.com/foobar", + base::Time::Now()); + EXPECT_EQ(2U, GetStoredVerdictCount( + LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE)); + EXPECT_EQ(1U, GetStoredVerdictCount( + LoginReputationClientRequest::PASSWORD_REUSE_EVENT)); } TEST_F(PasswordProtectionServiceTest, TestGetCachedVerdicts) { - ASSERT_EQ(0U, GetStoredVerdictCount()); - // Prepare 2 verdicts of the same origin with different cache expressions, - // one is expired, the other is not. + ASSERT_EQ(0U, GetStoredVerdictCount( + LoginReputationClientRequest::PASSWORD_REUSE_EVENT)); + ASSERT_EQ(0U, GetStoredVerdictCount( + LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE)); + // Prepare 3 verdicts of the same origin with different cache expressions, + // one is expired, one is not, the other is of a different type. base::Time now = base::Time::Now(); CacheVerdict(GURL("http://test.com/login.html"), + LoginReputationClientRequest::PASSWORD_REUSE_EVENT, LoginReputationClientResponse::SAFE, 10 * 60, "test.com", now); CacheVerdict( GURL("http://test.com/def/index.jsp"), + LoginReputationClientRequest::PASSWORD_REUSE_EVENT, LoginReputationClientResponse::PHISHING, 10 * 60, "test.com/def", base::Time::FromDoubleT(now.ToDoubleT() - 24.0 * 60.0 * 60.0)); // Yesterday, expired. - ASSERT_EQ(2U, GetStoredVerdictCount()); + CacheVerdict(GURL("http://test.com/bar/login.html"), + LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE, + LoginReputationClientResponse::PHISHING, 10 * 60, "test.com/bar", + now); + + ASSERT_EQ(2U, GetStoredVerdictCount( + LoginReputationClientRequest::PASSWORD_REUSE_EVENT)); + ASSERT_EQ(1U, GetStoredVerdictCount( + LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE)); // Return VERDICT_TYPE_UNSPECIFIED if look up for a URL with unknown origin. LoginReputationClientResponse actual_verdict; - EXPECT_EQ(LoginReputationClientResponse::VERDICT_TYPE_UNSPECIFIED, - password_protection_service_->GetCachedVerdict( - GURL("http://www.unknown.com/"), &actual_verdict)); + EXPECT_EQ( + LoginReputationClientResponse::VERDICT_TYPE_UNSPECIFIED, + password_protection_service_->GetCachedVerdict( + GURL("http://www.unknown.com/"), + LoginReputationClientRequest::PASSWORD_REUSE_EVENT, &actual_verdict)); // Return SAFE if look up for a URL that matches "test.com" cache expression. - EXPECT_EQ(LoginReputationClientResponse::SAFE, - password_protection_service_->GetCachedVerdict( - GURL("http://test.com/xyz/foo.jsp"), &actual_verdict)); + EXPECT_EQ( + LoginReputationClientResponse::SAFE, + password_protection_service_->GetCachedVerdict( + GURL("http://test.com/xyz/foo.jsp"), + LoginReputationClientRequest::PASSWORD_REUSE_EVENT, &actual_verdict)); // Return VERDICT_TYPE_UNSPECIFIED if look up for a URL whose variants match // test.com/def, but the corresponding verdict is expired. - EXPECT_EQ(LoginReputationClientResponse::VERDICT_TYPE_UNSPECIFIED, - password_protection_service_->GetCachedVerdict( - GURL("http://test.com/def/ghi/index.html"), &actual_verdict)); + EXPECT_EQ( + LoginReputationClientResponse::VERDICT_TYPE_UNSPECIFIED, + password_protection_service_->GetCachedVerdict( + GURL("http://test.com/def/ghi/index.html"), + LoginReputationClientRequest::PASSWORD_REUSE_EVENT, &actual_verdict)); } TEST_F(PasswordProtectionServiceTest, TestRemoveCachedVerdictOnURLsDeleted) { - ASSERT_EQ(0U, GetStoredVerdictCount()); + ASSERT_EQ(0U, GetStoredVerdictCount( + LoginReputationClientRequest::PASSWORD_REUSE_EVENT)); + ASSERT_EQ(0U, GetStoredVerdictCount( + LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE)); // Prepare 2 verdicts. One is for origin "http://foo.com", and the other is // for "http://bar.com". base::Time now = base::Time::Now(); CacheVerdict(GURL("http://foo.com/abc/index.jsp"), + LoginReputationClientRequest::PASSWORD_REUSE_EVENT, LoginReputationClientResponse::LOW_REPUTATION, 10 * 60, "foo.com/abc", now); CacheVerdict(GURL("http://bar.com/index.jsp"), + LoginReputationClientRequest::PASSWORD_REUSE_EVENT, LoginReputationClientResponse::PHISHING, 10 * 60, "bar.com", now); - ASSERT_EQ(2U, GetStoredVerdictCount()); + ASSERT_EQ(2U, GetStoredVerdictCount( + LoginReputationClientRequest::PASSWORD_REUSE_EVENT)); + + CacheVerdict(GURL("http://foo.com/abc/index.jsp"), + LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE, + LoginReputationClientResponse::LOW_REPUTATION, 10 * 60, + "foo.com/abc", now); + CacheVerdict(GURL("http://bar.com/index.jsp"), + LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE, + LoginReputationClientResponse::PHISHING, 10 * 60, "bar.com", + now); + ASSERT_EQ(2U, GetStoredVerdictCount( + LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE)); // Delete a bar.com URL. Corresponding content setting keyed on // origin "http://bar.com" should be removed, @@ -390,17 +484,31 @@ password_protection_service_->RemoveContentSettingsOnURLsDeleted( false /* all_history */, deleted_urls); - EXPECT_EQ(1U, GetStoredVerdictCount()); + EXPECT_EQ(1U, GetStoredVerdictCount( + LoginReputationClientRequest::PASSWORD_REUSE_EVENT)); + EXPECT_EQ(1U, GetStoredVerdictCount( + LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE)); + LoginReputationClientResponse actual_verdict; + EXPECT_EQ( + LoginReputationClientResponse::VERDICT_TYPE_UNSPECIFIED, + password_protection_service_->GetCachedVerdict( + GURL("http://bar.com"), + LoginReputationClientRequest::PASSWORD_REUSE_EVENT, &actual_verdict)); EXPECT_EQ(LoginReputationClientResponse::VERDICT_TYPE_UNSPECIFIED, password_protection_service_->GetCachedVerdict( - GURL("http://bar.com"), &actual_verdict)); + GURL("http://bar.com"), + LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE, + &actual_verdict)); // If delete all history. All password protection content settings should be // gone. password_protection_service_->RemoveContentSettingsOnURLsDeleted( true /* all_history */, history::URLRows()); - EXPECT_EQ(0U, GetStoredVerdictCount()); + EXPECT_EQ(0U, GetStoredVerdictCount( + LoginReputationClientRequest::PASSWORD_REUSE_EVENT)); + EXPECT_EQ(0U, GetStoredVerdictCount( + LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE)); } TEST_F(PasswordProtectionServiceTest, VerifyCanGetReputationOfURL) { @@ -454,8 +562,10 @@ TEST_F(PasswordProtectionServiceTest, TestNoRequestSentIfVerdictAlreadyCached) { histograms_.ExpectTotalCount(kPasswordOnFocusRequestOutcomeHistogramName, 0); - CacheVerdict(GURL(kTargetUrl), LoginReputationClientResponse::LOW_REPUTATION, - 600, GURL(kTargetUrl).host(), base::Time::Now()); + CacheVerdict(GURL(kTargetUrl), + LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE, + LoginReputationClientResponse::LOW_REPUTATION, 600, + GURL(kTargetUrl).host(), base::Time::Now()); InitializeAndStartPasswordOnFocusRequest(false /* match whitelist */, 10000 /* timeout in ms*/); base::RunLoop().RunUntilIdle(); @@ -562,42 +672,87 @@ } TEST_F(PasswordProtectionServiceTest, TestCleanUpExpiredVerdict) { - ASSERT_EQ(0U, GetStoredVerdictCount()); - // Prepare 4 verdicts: + // Prepare 4 verdicts for PASSWORD_REUSE_EVENT: // (1) "foo.com/abc" valid // (2) "foo.com/def" expired // (3) "bar.com/abc" expired // (4) "bar.com/def" expired base::Time now = base::Time::Now(); CacheVerdict(GURL("https://foo.com/abc/index.jsp"), + LoginReputationClientRequest::PASSWORD_REUSE_EVENT, LoginReputationClientResponse::LOW_REPUTATION, 10 * 60, "foo.com/abc", now); CacheVerdict(GURL("https://foo.com/def/index.jsp"), + LoginReputationClientRequest::PASSWORD_REUSE_EVENT, LoginReputationClientResponse::LOW_REPUTATION, 0, "foo.com/def", now); CacheVerdict(GURL("https://bar.com/abc/index.jsp"), + LoginReputationClientRequest::PASSWORD_REUSE_EVENT, LoginReputationClientResponse::PHISHING, 0, "bar.com/abc", now); CacheVerdict(GURL("https://bar.com/def/index.jsp"), + LoginReputationClientRequest::PASSWORD_REUSE_EVENT, LoginReputationClientResponse::PHISHING, 0, "bar.com/def", now); - ASSERT_EQ(4U, GetStoredVerdictCount()); + ASSERT_EQ(4U, GetStoredVerdictCount( + LoginReputationClientRequest::PASSWORD_REUSE_EVENT)); + + // Prepare 2 verdicts for UNFAMILIAR_LOGIN_PAGE: + // (1) "bar.com/def" valid + // (2) "bar.com/xyz" expired + CacheVerdict(GURL("https://bar.com/def/index.jsp"), + LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE, + LoginReputationClientResponse::SAFE, 10 * 60, "bar.com/def", + now); + CacheVerdict(GURL("https://bar.com/xyz/index.jsp"), + LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE, + LoginReputationClientResponse::PHISHING, 0, "bar.com/xyz", now); + ASSERT_EQ(2U, GetStoredVerdictCount( + LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE)); password_protection_service_->CleanUpExpiredVerdicts(); - ASSERT_EQ(1U, GetStoredVerdictCount()); + ASSERT_EQ(1U, GetStoredVerdictCount( + LoginReputationClientRequest::PASSWORD_REUSE_EVENT)); + ASSERT_EQ(1U, GetStoredVerdictCount( + LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE)); LoginReputationClientResponse actual_verdict; - // Has cached verdict for foo.com/abc. - EXPECT_EQ(LoginReputationClientResponse::LOW_REPUTATION, + // Has cached PASSWORD_REUSE_EVENT verdict for foo.com/abc. + EXPECT_EQ( + LoginReputationClientResponse::LOW_REPUTATION, + password_protection_service_->GetCachedVerdict( + GURL("https://foo.com/abc/test.jsp"), + LoginReputationClientRequest::PASSWORD_REUSE_EVENT, &actual_verdict)); + // No cached PASSWORD_REUSE_EVENT verdict for foo.com/def. + EXPECT_EQ( + LoginReputationClientResponse::VERDICT_TYPE_UNSPECIFIED, + password_protection_service_->GetCachedVerdict( + GURL("https://foo.com/def/index.jsp"), + LoginReputationClientRequest::PASSWORD_REUSE_EVENT, &actual_verdict)); + // No cached PASSWORD_REUSE_EVENT verdict for bar.com/abc. + EXPECT_EQ( + LoginReputationClientResponse::VERDICT_TYPE_UNSPECIFIED, + password_protection_service_->GetCachedVerdict( + GURL("https://bar.com/abc/index.jsp"), + LoginReputationClientRequest::PASSWORD_REUSE_EVENT, &actual_verdict)); + // No cached PASSWORD_REUSE_EVENT verdict for bar.com/def. + EXPECT_EQ( + LoginReputationClientResponse::VERDICT_TYPE_UNSPECIFIED, + password_protection_service_->GetCachedVerdict( + GURL("https://bar.com/def/index.jsp"), + LoginReputationClientRequest::PASSWORD_REUSE_EVENT, &actual_verdict)); + + // Has cached UNFAMILIAR_LOGIN_PAGE verdict for bar.com/def. + EXPECT_EQ(LoginReputationClientResponse::SAFE, password_protection_service_->GetCachedVerdict( - GURL("https://foo.com/abc/test.jsp"), &actual_verdict)); - // No cached verdict for foo.com/def. + GURL("https://bar.com/def/index.jsp"), + LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE, + &actual_verdict)); + + // No cached UNFAMILIAR_LOGIN_PAGE verdict for bar.com/xyz. EXPECT_EQ(LoginReputationClientResponse::VERDICT_TYPE_UNSPECIFIED, password_protection_service_->GetCachedVerdict( - GURL("https://foo.com/def/index.jsp"), &actual_verdict)); - // Nothing in content setting for bar.com. - EXPECT_EQ(nullptr, content_setting_map_->GetWebsiteSetting( - GURL("https://bar.com"), GURL(), - CONTENT_SETTINGS_TYPE_PASSWORD_PROTECTION, - std::string(), nullptr)); + GURL("https://bar.com/xyz/index.jsp"), + LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE, + &actual_verdict)); } TEST_F(PasswordProtectionServiceTest, VerifyPasswordOnFocusRequestProto) {
diff --git a/content/browser/accessibility/browser_accessibility.cc b/content/browser/accessibility/browser_accessibility.cc index 3fb2659..3e24280 100644 --- a/content/browser/accessibility/browser_accessibility.cc +++ b/content/browser/accessibility/browser_accessibility.cc
@@ -355,15 +355,11 @@ } gfx::Rect BrowserAccessibility::GetFrameBoundsRect() const { - gfx::RectF bounds = GetLocation(); - FixEmptyBounds(&bounds); - return RelativeToAbsoluteBounds(bounds, true); + return RelativeToAbsoluteBounds(gfx::RectF(), true); } gfx::Rect BrowserAccessibility::GetPageBoundsRect() const { - gfx::RectF bounds = GetLocation(); - FixEmptyBounds(&bounds); - return RelativeToAbsoluteBounds(bounds, false); + return RelativeToAbsoluteBounds(gfx::RectF(), false); } gfx::Rect BrowserAccessibility::GetPageBoundsForRange(int start, int len) @@ -1044,66 +1040,27 @@ return text; } -void BrowserAccessibility::FixEmptyBounds(gfx::RectF* bounds) const { - if (bounds->width() > 0 && bounds->height() > 0) - return; - - for (size_t i = 0; i < InternalChildCount(); ++i) { - // Compute the bounds of each child - this calls FixEmptyBounds - // recursively if necessary. - BrowserAccessibility* child = InternalGetChild(i); - gfx::Rect child_bounds = child->GetPageBoundsRect(); - - // Ignore children that don't have valid bounds themselves. - if (child_bounds.width() == 0 || child_bounds.height() == 0) - continue; - - // For the first valid child, just set the bounds to that child's bounds. - if (bounds->width() == 0 || bounds->height() == 0) { - *bounds = gfx::RectF(child_bounds); - continue; - } - - // Union each additional child's bounds. - bounds->Union(gfx::RectF(child_bounds)); - } -} - gfx::Rect BrowserAccessibility::RelativeToAbsoluteBounds( gfx::RectF bounds, bool frame_only) const { const BrowserAccessibility* node = this; while (node) { - if (node->GetData().transform) - node->GetData().transform->TransformRect(&bounds); + bounds = + node->manager()->ax_tree()->RelativeToTreeBounds(node->node(), bounds); - const BrowserAccessibility* container = - node->manager()->GetFromID(node->GetData().offset_container_id); - if (!container) { - if (node == node->manager()->GetRoot() && !frame_only) { - container = node->PlatformGetParent(); - } else { - container = node->manager()->GetRoot(); - } - } - - if (!container || container == node) - break; - - gfx::RectF container_bounds = container->GetLocation(); - bounds.Offset(container_bounds.x(), container_bounds.y()); - - if (container->manager()->UseRootScrollOffsetsWhenComputingBounds() || - container->PlatformGetParent()) { + // On some platforms we need to unapply root scroll offsets. + const BrowserAccessibility* root = node->manager()->GetRoot(); + if (!node->manager()->UseRootScrollOffsetsWhenComputingBounds() && + !root->PlatformGetParent()) { int sx = 0; int sy = 0; - if (container->GetIntAttribute(ui::AX_ATTR_SCROLL_X, &sx) && - container->GetIntAttribute(ui::AX_ATTR_SCROLL_Y, &sy)) { - bounds.Offset(-sx, -sy); + if (root->GetIntAttribute(ui::AX_ATTR_SCROLL_X, &sx) && + root->GetIntAttribute(ui::AX_ATTR_SCROLL_Y, &sy)) { + bounds.Offset(sx, sy); } } - node = container; + node = root->PlatformGetParent(); } return gfx::ToEnclosingRect(bounds);
diff --git a/content/browser/accessibility/browser_accessibility.h b/content/browser/accessibility/browser_accessibility.h index b4a6f2c..5412aba 100644 --- a/content/browser/accessibility/browser_accessibility.h +++ b/content/browser/accessibility/browser_accessibility.h
@@ -422,12 +422,6 @@ // text, depending on the platform. base::string16 GetInnerText() const; - // If a bounding rectangle is empty, compute it based on the union of its - // children, since most accessibility APIs don't like elements with no - // bounds, but "virtual" elements in the accessibility tree that don't - // correspond to a layed-out element sometimes don't have bounds. - void FixEmptyBounds(gfx::RectF* bounds) const; - DISALLOW_COPY_AND_ASSIGN(BrowserAccessibility); };
diff --git a/content/browser/accessibility/browser_accessibility_manager.h b/content/browser/accessibility/browser_accessibility_manager.h index cc4910e1..3f1d7b5 100644 --- a/content/browser/accessibility/browser_accessibility_manager.h +++ b/content/browser/accessibility/browser_accessibility_manager.h
@@ -338,6 +338,7 @@ // Accessors. ui::AXTreeIDRegistry::AXTreeID ax_tree_id() const { return ax_tree_id_; } float device_scale_factor() const { return device_scale_factor_; } + const ui::AXTree* ax_tree() const { return tree_.get(); } // AXTreeDelegate implementation. void OnNodeDataWillChange(ui::AXTree* tree,
diff --git a/content/browser/appcache/appcache_job.cc b/content/browser/appcache/appcache_job.cc index 271553f..5bd29cc 100644 --- a/content/browser/appcache/appcache_job.cc +++ b/content/browser/appcache/appcache_job.cc
@@ -23,7 +23,8 @@ std::unique_ptr<AppCacheJob> job; if (base::CommandLine::ForCurrentProcess()->HasSwitch( switches::kEnableNetworkService)) { - job.reset(new AppCacheURLLoaderJob); + job.reset( + new AppCacheURLLoaderJob(*(request->GetResourceRequest()), storage)); } else { job.reset(new AppCacheURLRequestJob(request->GetURLRequest(), network_delegate, storage, host, @@ -36,6 +37,26 @@ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); } +bool AppCacheJob::IsWaiting() const { + return delivery_type_ == AWAITING_DELIVERY_ORDERS; +} + +bool AppCacheJob::IsDeliveringAppCacheResponse() const { + return delivery_type_ == APPCACHED_DELIVERY; +} + +bool AppCacheJob::IsDeliveringNetworkResponse() const { + return delivery_type_ == NETWORK_DELIVERY; +} + +bool AppCacheJob::IsDeliveringErrorResponse() const { + return delivery_type_ == ERROR_DELIVERY; +} + +bool AppCacheJob::IsCacheEntryNotFound() const { + return cache_entry_not_found_; +} + base::WeakPtr<AppCacheJob> AppCacheJob::GetWeakPtr() { return weak_factory_.GetWeakPtr(); } @@ -48,6 +69,9 @@ return nullptr; } -AppCacheJob::AppCacheJob() : weak_factory_(this) {} +AppCacheJob::AppCacheJob() + : cache_entry_not_found_(false), + delivery_type_(AWAITING_DELIVERY_ORDERS), + weak_factory_(this) {} } // namespace content
diff --git a/content/browser/appcache/appcache_job.h b/content/browser/appcache/appcache_job.h index e43bb121..c18c772 100644 --- a/content/browser/appcache/appcache_job.h +++ b/content/browser/appcache/appcache_job.h
@@ -35,6 +35,13 @@ // of the AppCache code. class CONTENT_EXPORT AppCacheJob : public base::SupportsWeakPtr<AppCacheJob> { public: + enum DeliveryType { + AWAITING_DELIVERY_ORDERS, + APPCACHED_DELIVERY, + NETWORK_DELIVERY, + ERROR_DELIVERY + }; + // Callback that will be invoked before the request is restarted. The caller // can use this opportunity to grab state from the job to determine how it // should behave when the request is restarted. @@ -63,19 +70,19 @@ virtual bool IsStarted() const = 0; // Returns true if the job is waiting for instructions. - virtual bool IsWaiting() const = 0; + virtual bool IsWaiting() const; // Returns true if the job is delivering a response from the cache. - virtual bool IsDeliveringAppCacheResponse() const = 0; + virtual bool IsDeliveringAppCacheResponse() const; // Returns true if the job is delivering a response from the network. - virtual bool IsDeliveringNetworkResponse() const = 0; + virtual bool IsDeliveringNetworkResponse() const; // Returns true if the job is delivering an error response. - virtual bool IsDeliveringErrorResponse() const = 0; + virtual bool IsDeliveringErrorResponse() const; // Returns true if the cache entry was not found in the cache. - virtual bool IsCacheEntryNotFound() const = 0; + virtual bool IsCacheEntryNotFound() const; // Informs the job of what response it should deliver. Only one of these // methods should be called, and only once per job. A job will sit idle and @@ -111,6 +118,12 @@ SEQUENCE_CHECKER(sequence_checker_); + // Set to true if the AppCache entry is not found. + bool cache_entry_not_found_; + + // The jobs delivery status. + DeliveryType delivery_type_; + base::WeakPtrFactory<AppCacheJob> weak_factory_; DISALLOW_COPY_AND_ASSIGN(AppCacheJob);
diff --git a/content/browser/appcache/appcache_request_handler.cc b/content/browser/appcache/appcache_request_handler.cc index 870fa7d..1e2fe1b 100644 --- a/content/browser/appcache/appcache_request_handler.cc +++ b/content/browser/appcache/appcache_request_handler.cc
@@ -9,8 +9,13 @@ #include "base/bind.h" #include "content/browser/appcache/appcache.h" #include "content/browser/appcache/appcache_backend_impl.h" +#include "content/browser/appcache/appcache_host.h" +#include "content/browser/appcache/appcache_navigation_handle_core.h" #include "content/browser/appcache/appcache_policy.h" #include "content/browser/appcache/appcache_request.h" +#include "content/browser/appcache/appcache_url_loader_factory.h" +#include "content/browser/appcache/appcache_url_loader_job.h" +#include "content/browser/appcache/appcache_url_loader_request.h" #include "content/browser/appcache/appcache_url_request_job.h" #include "content/browser/service_worker/service_worker_request_handler.h" #include "net/url_request/url_request.h" @@ -223,6 +228,18 @@ CompleteCrossSiteTransfer(old_process_id_, old_host_id_); } +// static +std::unique_ptr<AppCacheRequestHandler> +AppCacheRequestHandler::InitializeForNavigationNetworkService( + const ResourceRequest& request, + AppCacheNavigationHandleCore* appcache_handle_core) { + std::unique_ptr<AppCacheRequestHandler> handler = + appcache_handle_core->host()->CreateRequestHandler( + AppCacheURLLoaderRequest::Create(request), request.resource_type, + request.should_reset_appcache); + return handler; +} + void AppCacheRequestHandler::OnDestructionImminent(AppCacheHost* host) { storage()->CancelDelegateCallbacks(this); host_ = NULL; // no need to RemoveObserver, the host is being deleted @@ -316,12 +333,22 @@ // If a page falls into the scope of a ServiceWorker, any matching AppCaches // should be ignored. This depends on the ServiceWorker handler being invoked // prior to the AppCache handler. - if (ServiceWorkerRequestHandler::IsControlledByServiceWorker( + // TODO(ananta) + // We need to handle this for AppCache requests initiated for the network + // service + if (request_->GetURLRequest() && + ServiceWorkerRequestHandler::IsControlledByServiceWorker( request_->GetURLRequest())) { host_->enable_cache_selection(false); return nullptr; } + if (storage()->IsInitialized() && + service_->storage()->usage_map()->find(request_->GetURL().GetOrigin()) == + service_->storage()->usage_map()->end()) { + return nullptr; + } + host_->enable_cache_selection(true); const AppCacheHost* spawning_host = @@ -503,4 +530,19 @@ ContinueMaybeLoadSubResource(); } +void AppCacheRequestHandler::MaybeCreateLoader( + const ResourceRequest& resource_request, + ResourceContext* resource_context, + LoaderCallback callback) { + // MaybeLoadMainResource will invoke navigation_request_job's methods + // asynchronously via AppCacheStorage::Delegate. + navigation_request_job_ = MaybeLoadMainResource(nullptr); + if (!navigation_request_job_.get()) { + std::move(callback).Run(StartLoaderCallback()); + return; + } + navigation_request_job_->AsURLLoaderJob()->set_loader_callback( + std::move(callback)); +} + } // namespace content
diff --git a/content/browser/appcache/appcache_request_handler.h b/content/browser/appcache/appcache_request_handler.h index 3b7e167..b0ed05f 100644 --- a/content/browser/appcache/appcache_request_handler.h +++ b/content/browser/appcache/appcache_request_handler.h
@@ -16,6 +16,7 @@ #include "content/browser/appcache/appcache_entry.h" #include "content/browser/appcache/appcache_host.h" #include "content/browser/appcache/appcache_service_impl.h" +#include "content/browser/loader/url_loader_request_handler.h" #include "content/common/content_export.h" #include "content/public/common/resource_type.h" @@ -26,9 +27,11 @@ namespace content { class AppCacheJob; +class AppCacheNavigationHandleCore; class AppCacheRequest; class AppCacheRequestHandlerTest; class AppCacheURLRequestJob; +struct ResourceRequest; // An instance is created for each net::URLRequest. The instance survives all // http transactions involved in the processing of its net::URLRequest, and is @@ -39,7 +42,8 @@ : public base::SupportsUserData::Data, public AppCacheHost::Observer, public AppCacheServiceImpl::Observer, - public AppCacheStorage::Delegate { + public AppCacheStorage::Delegate, + public URLLoaderRequestHandler { public: ~AppCacheRequestHandler() override; @@ -69,6 +73,11 @@ type == RESOURCE_TYPE_SHARED_WORKER; } + static std::unique_ptr<AppCacheRequestHandler> + InitializeForNavigationNetworkService( + const ResourceRequest& request, + AppCacheNavigationHandleCore* appcache_handle_core); + private: friend class AppCacheHost; @@ -135,6 +144,11 @@ // AppCacheHost::Observer override void OnCacheSelectionComplete(AppCacheHost* host) override; + // URLLoaderRequestHandler override + void MaybeCreateLoader(const ResourceRequest& resource_request, + ResourceContext* resource_context, + LoaderCallback callback) override; + // Data members ----------------------------------------------- // What host we're servicing a request for. @@ -195,6 +209,13 @@ std::unique_ptr<AppCacheRequest> request_; + // In the network service world we are queried via the URLLoaderRequestHandler + // interface to see if the navigation request can be handled via the + // AppCache. We hold onto the AppCache job created here until the client + // binds to it (Serviced via AppCache). If the request cannot be handled via + // the AppCache, we delete the job. + std::unique_ptr<AppCacheJob> navigation_request_job_; + friend class content::AppCacheRequestHandlerTest; DISALLOW_COPY_AND_ASSIGN(AppCacheRequestHandler); };
diff --git a/content/browser/appcache/appcache_storage.cc b/content/browser/appcache/appcache_storage.cc index 0299ddc1..666acd56 100644 --- a/content/browser/appcache/appcache_storage.cc +++ b/content/browser/appcache/appcache_storage.cc
@@ -18,9 +18,11 @@ const int64_t AppCacheStorage::kUnitializedId = -1; AppCacheStorage::AppCacheStorage(AppCacheServiceImpl* service) - : last_cache_id_(kUnitializedId), last_group_id_(kUnitializedId), - last_response_id_(kUnitializedId), service_(service) { -} + : last_cache_id_(kUnitializedId), + last_group_id_(kUnitializedId), + last_response_id_(kUnitializedId), + service_(service), + weak_factory_(this) {} AppCacheStorage::~AppCacheStorage() { DCHECK(delegate_references_.empty()); @@ -94,6 +96,10 @@ info_load->StartIfNeeded(); } +base::WeakPtr<AppCacheStorage> AppCacheStorage::GetWeakPtr() { + return weak_factory_.GetWeakPtr(); +} + void AppCacheStorage::UpdateUsageMapAndNotify(const GURL& origin, int64_t new_usage) { DCHECK_GE(new_usage, 0);
diff --git a/content/browser/appcache/appcache_storage.h b/content/browser/appcache/appcache_storage.h index d01de851..10a3d4c 100644 --- a/content/browser/appcache/appcache_storage.h +++ b/content/browser/appcache/appcache_storage.h
@@ -15,6 +15,7 @@ #include "base/gtest_prod_util.h" #include "base/macros.h" #include "base/memory/ref_counted.h" +#include "base/memory/weak_ptr.h" #include "content/browser/appcache/appcache_working_set.h" #include "content/common/content_export.h" #include "net/base/completion_callback.h" @@ -194,6 +195,9 @@ virtual void DeleteResponses(const GURL& manifest_url, const std::vector<int64_t>& response_ids) = 0; + // Returns true if the AppCacheStorage instance is initialized. + virtual bool IsInitialized() = 0; + // Generates unique storage ids for different object types. int64_t NewCacheId() { return ++last_cache_id_; } int64_t NewGroupId() { return ++last_group_id_; } @@ -207,6 +211,9 @@ // Simple ptr back to the service object that owns us. AppCacheServiceImpl* service() { return service_; } + // Returns a weak pointer reference to the AppCacheStorage instance. + base::WeakPtr<AppCacheStorage> GetWeakPtr(); + protected: friend class content::AppCacheQuotaClientTest; friend class content::AppCacheResponseTest; @@ -326,6 +333,10 @@ FRIEND_TEST_ALL_PREFIXES(content::AppCacheStorageTest, DelegateReferences); FRIEND_TEST_ALL_PREFIXES(content::AppCacheStorageTest, UsageMap); + // The WeakPtrFactory below must occur last in the class definition so they + // get destroyed last. + base::WeakPtrFactory<AppCacheStorage> weak_factory_; + DISALLOW_COPY_AND_ASSIGN(AppCacheStorage); };
diff --git a/content/browser/appcache/appcache_storage_impl.cc b/content/browser/appcache/appcache_storage_impl.cc index 2159d159..0307853 100644 --- a/content/browser/appcache/appcache_storage_impl.cc +++ b/content/browser/appcache/appcache_storage_impl.cc
@@ -1779,6 +1779,10 @@ StartDeletingResponses(response_ids); } +bool AppCacheStorageImpl::IsInitialized() { + return IsInitTaskComplete(); +} + void AppCacheStorageImpl::DelayedStartDeletingUnusedResponses() { // Only if we haven't already begun. if (!did_start_deleting_responses_) {
diff --git a/content/browser/appcache/appcache_storage_impl.h b/content/browser/appcache/appcache_storage_impl.h index 82a6f5a2..067b3e6 100644 --- a/content/browser/appcache/appcache_storage_impl.h +++ b/content/browser/appcache/appcache_storage_impl.h
@@ -73,6 +73,7 @@ const std::vector<int64_t>& response_ids) override; void DeleteResponses(const GURL& manifest_url, const std::vector<int64_t>& response_ids) override; + bool IsInitialized() override; private: // The AppCacheStorageImpl class methods and datamembers may only be
diff --git a/content/browser/appcache/appcache_url_loader_factory.cc b/content/browser/appcache/appcache_url_loader_factory.cc index 37c105a..aa2bdbeb 100644 --- a/content/browser/appcache/appcache_url_loader_factory.cc +++ b/content/browser/appcache/appcache_url_loader_factory.cc
@@ -6,157 +6,40 @@ #include "base/bind.h" #include "base/logging.h" -#include "content/browser/appcache/appcache_entry.h" -#include "content/browser/appcache/appcache_policy.h" -#include "content/browser/appcache/appcache_request.h" -#include "content/browser/appcache/appcache_storage.h" -#include "content/browser/appcache/chrome_appcache_service.h" +#include "content/browser/appcache/appcache_request_handler.h" +#include "content/browser/appcache/appcache_url_loader_job.h" +#include "content/browser/appcache/appcache_url_loader_request.h" #include "content/browser/url_loader_factory_getter.h" -#include "content/common/network_service.mojom.h" #include "content/common/resource_request.h" -#include "content/common/url_loader.mojom.h" #include "content/common/url_loader_factory.mojom.h" #include "content/public/browser/browser_thread.h" -#include "mojo/public/cpp/bindings/associated_binding.h" -#include "mojo/public/cpp/bindings/associated_interface_ptr.h" +#include "mojo/public/cpp/bindings/binding.h" #include "mojo/public/cpp/bindings/binding_set.h" +#include "mojo/public/cpp/bindings/interface_ptr.h" namespace content { -namespace { - -// Handles AppCache URL loads for the network service. -class AppCacheURLLoader : public AppCacheStorage::Delegate, - public mojom::URLLoader { - public: - AppCacheURLLoader(const ResourceRequest& request, - mojom::URLLoaderAssociatedRequest url_loader_request, - int32_t routing_id, - int32_t request_id, - mojom::URLLoaderClientPtr client_info, - ChromeAppCacheService* appcache_service, - URLLoaderFactoryGetter* factory_getter) - : request_(request), - routing_id_(routing_id), - request_id_(request_id), - client_info_(std::move(client_info)), - appcache_service_(appcache_service), - factory_getter_(factory_getter), - binding_(this, std::move(url_loader_request)) { - binding_.set_connection_error_handler(base::Bind( - &AppCacheURLLoader::OnConnectionError, base::Unretained(this))); - } - - ~AppCacheURLLoader() override {} - - void Start() { - // If the origin does not exist in the AppCache usage map, then we can - // safely call the network service here. - if (appcache_service_->storage()->usage_map()->find( - request_.url.GetOrigin()) == - appcache_service_->storage()->usage_map()->end()) { - factory_getter_->GetNetworkFactory()->get()->CreateLoaderAndStart( - mojo::MakeRequest(&network_loader_request_), routing_id_, request_id_, - mojom::kURLLoadOptionSendSSLInfo, request_, std::move(client_info_)); - return; - } - - appcache_service_->storage()->FindResponseForMainRequest(request_.url, - GURL(), this); - } - - // mojom::URLLoader implementation: - void FollowRedirect() override { network_loader_request_->FollowRedirect(); } - - void SetPriority(net::RequestPriority priority, - int32_t intra_priority_value) override { - DCHECK(false); - } - - private: - // AppCacheStorage::Delegate methods. - void OnMainResponseFound(const GURL& url, - const AppCacheEntry& entry, - const GURL& fallback_url, - const AppCacheEntry& fallback_entry, - int64_t cache_id, - int64_t group_id, - const GURL& manifest_url) override { - AppCachePolicy* policy = appcache_service_->appcache_policy(); - bool was_blocked_by_policy = - !manifest_url.is_empty() && policy && - !policy->CanLoadAppCache(manifest_url, - request_.first_party_for_cookies); - - if (was_blocked_by_policy || !entry.has_response_id() || - cache_id == kAppCacheNoCacheId) { - factory_getter_->GetNetworkFactory()->get()->CreateLoaderAndStart( - mojo::MakeRequest(&network_loader_request_), routing_id_, request_id_, - mojom::kURLLoadOptionSendSSLInfo, request_, std::move(client_info_)); - } else { - DLOG(WARNING) << "AppCache found for url " << url - << " Returning AppCache factory\n"; - // TODO(ananta) - // Provide the plumbing to initiate AppCache requests here. - factory_getter_->GetNetworkFactory()->get()->CreateLoaderAndStart( - mojo::MakeRequest(&network_loader_request_), routing_id_, request_id_, - mojom::kURLLoadOptionSendSSLInfo, request_, std::move(client_info_)); - } - } - - void OnConnectionError() { delete this; } - - // The current request. - ResourceRequest request_; - - // URLLoader proxy for the network service. - mojom::URLLoaderAssociatedPtr network_loader_request_; - - // Routing id of the request. This is 0 for navigation requests. For - // subresource requests it is non zero. - int routing_id_; - - // Request id. - int request_id_; - - // The URLLoaderClient pointer. We call this interface with notifications - // about the URL load - mojom::URLLoaderClientPtr client_info_; - - // Used to query AppCacheStorage to see if a request can be served out of the - /// AppCache. - scoped_refptr<ChromeAppCacheService> appcache_service_; - - // Used to retrieve the network service factory to pass requests to the - // network service. - scoped_refptr<URLLoaderFactoryGetter> factory_getter_; - - // Binds the URLLoaderClient with us. - mojo::AssociatedBinding<mojom::URLLoader> binding_; - - DISALLOW_COPY_AND_ASSIGN(AppCacheURLLoader); -}; - -} // namespace - // Implements the URLLoaderFactory mojom for AppCache requests. AppCacheURLLoaderFactory::AppCacheURLLoaderFactory( - ChromeAppCacheService* appcache_service, + mojom::URLLoaderFactoryRequest request, URLLoaderFactoryGetter* factory_getter) - : appcache_service_(appcache_service), factory_getter_(factory_getter) {} + : binding_(this, std::move(request)), factory_getter_(factory_getter) { + binding_.set_connection_error_handler(base::Bind( + &AppCacheURLLoaderFactory::OnConnectionError, base::Unretained(this))); +} AppCacheURLLoaderFactory::~AppCacheURLLoaderFactory() {} // static -void AppCacheURLLoaderFactory::CreateURLLoaderFactory( - mojom::URLLoaderFactoryRequest request, - ChromeAppCacheService* appcache_service, +mojom::URLLoaderFactoryPtr AppCacheURLLoaderFactory::CreateURLLoaderFactory( URLLoaderFactoryGetter* factory_getter) { - std::unique_ptr<AppCacheURLLoaderFactory> factory_instance( - new AppCacheURLLoaderFactory(appcache_service, factory_getter)); - AppCacheURLLoaderFactory* raw_factory = factory_instance.get(); - raw_factory->loader_factory_bindings_.AddBinding(std::move(factory_instance), - std::move(request)); + mojom::URLLoaderFactoryPtr loader_factory; + mojom::URLLoaderFactoryRequest request = mojo::MakeRequest(&loader_factory); + + // This instance will get deleted when the client drops the connection. + // Please see OnConnectionError() for details. + new AppCacheURLLoaderFactory(std::move(request), factory_getter); + return loader_factory; } void AppCacheURLLoaderFactory::CreateLoaderAndStart( @@ -167,12 +50,7 @@ const ResourceRequest& request, mojom::URLLoaderClientPtr client) { DCHECK_CURRENTLY_ON(BrowserThread::IO); - - // This will get deleted when the connection is dropped by the client. - AppCacheURLLoader* loader = new AppCacheURLLoader( - request, std::move(url_loader_request), routing_id, request_id, - std::move(client), appcache_service_.get(), factory_getter_.get()); - loader->Start(); + NOTREACHED() << "Currently not implemented"; } void AppCacheURLLoaderFactory::SyncLoad(int32_t routing_id, @@ -182,4 +60,8 @@ NOTREACHED(); } +void AppCacheURLLoaderFactory::OnConnectionError() { + base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, this); +} + } // namespace content \ No newline at end of file
diff --git a/content/browser/appcache/appcache_url_loader_factory.h b/content/browser/appcache/appcache_url_loader_factory.h index f615395..2e39001 100644 --- a/content/browser/appcache/appcache_url_loader_factory.h +++ b/content/browser/appcache/appcache_url_loader_factory.h
@@ -7,11 +7,13 @@ #include "base/memory/ref_counted.h" #include "content/common/url_loader_factory.mojom.h" -#include "mojo/public/cpp/bindings/strong_binding_set.h" +#include "mojo/public/cpp/bindings/binding.h" #include "url/gurl.h" namespace content { -class ChromeAppCacheService; + +class AppCacheJob; +class AppCacheServiceImpl; class URLLoaderFactoryGetter; // Implements the URLLoaderFactory mojom for AppCache requests. @@ -20,13 +22,12 @@ ~AppCacheURLLoaderFactory() override; // Factory function to create an instance of the factory. - // The |appcache_service| parameter is used to query the underlying - // AppCacheStorage instance to check if we can service requests from the - // AppCache. We pass unhandled requests to the network service retrieved from - // the |factory_getter|. - static void CreateURLLoaderFactory(mojom::URLLoaderFactoryRequest request, - ChromeAppCacheService* appcache_service, - URLLoaderFactoryGetter* factory_getter); + // 1. The |factory_getter| parameter is used to query the network service + // to pass network requests to. + // Returns a URLLoaderFactoryPtr instance which controls the lifetime of the + // factory. + static mojom::URLLoaderFactoryPtr CreateURLLoaderFactory( + URLLoaderFactoryGetter* factory_getter); // mojom::URLLoaderFactory implementation. void CreateLoaderAndStart( @@ -42,19 +43,18 @@ SyncLoadCallback callback) override; private: - AppCacheURLLoaderFactory(ChromeAppCacheService* appcache_service, + AppCacheURLLoaderFactory(mojom::URLLoaderFactoryRequest request, URLLoaderFactoryGetter* factory_getter); - // Used to query AppCacheStorage to see if a request can be served out of the - /// AppCache. - scoped_refptr<ChromeAppCacheService> appcache_service_; + void OnConnectionError(); + + // Mojo binding. + mojo::Binding<mojom::URLLoaderFactory> binding_; // Used to retrieve the network service factory to pass unhandled requests to // the network service. scoped_refptr<URLLoaderFactoryGetter> factory_getter_; - mojo::StrongBindingSet<mojom::URLLoaderFactory> loader_factory_bindings_; - DISALLOW_COPY_AND_ASSIGN(AppCacheURLLoaderFactory); };
diff --git a/content/browser/appcache/appcache_url_loader_job.cc b/content/browser/appcache/appcache_url_loader_job.cc index 09f1545..86d90fe 100644 --- a/content/browser/appcache/appcache_url_loader_job.cc +++ b/content/browser/appcache/appcache_url_loader_job.cc
@@ -3,51 +3,288 @@ // found in the LICENSE file. #include "content/browser/appcache/appcache_url_loader_job.h" -#include "content/browser/appcache/appcache_entry.h" + +#include "base/strings/string_number_conversions.h" +#include "content/browser/appcache/appcache_histograms.h" +#include "content/common/net_adapters.h" +#include "content/public/common/resource_type.h" +#include "net/http/http_status_code.h" namespace content { -AppCacheURLLoaderJob::~AppCacheURLLoaderJob() {} +AppCacheURLLoaderJob::~AppCacheURLLoaderJob() { + if (storage_.get()) + storage_->CancelDelegateCallbacks(this); +} void AppCacheURLLoaderJob::Kill() {} bool AppCacheURLLoaderJob::IsStarted() const { - return false; -} - -bool AppCacheURLLoaderJob::IsWaiting() const { - return false; -} - -bool AppCacheURLLoaderJob::IsDeliveringAppCacheResponse() const { - return false; -} - -bool AppCacheURLLoaderJob::IsDeliveringNetworkResponse() const { - return false; -} - -bool AppCacheURLLoaderJob::IsDeliveringErrorResponse() const { - return false; -} - -bool AppCacheURLLoaderJob::IsCacheEntryNotFound() const { - return false; + return delivery_type_ != AWAITING_DELIVERY_ORDERS; } void AppCacheURLLoaderJob::DeliverAppCachedResponse(const GURL& manifest_url, int64_t cache_id, const AppCacheEntry& entry, - bool is_fallback) {} + bool is_fallback) { + if (!storage_.get()) { + DeliverErrorResponse(); + return; + } -void AppCacheURLLoaderJob::DeliverNetworkResponse() {} + delivery_type_ = APPCACHED_DELIVERY; -void AppCacheURLLoaderJob::DeliverErrorResponse() {} + AppCacheHistograms::AddAppCacheJobStartDelaySample(base::TimeTicks::Now() - + start_time_tick_); -const GURL& AppCacheURLLoaderJob::GetURL() const { - return url_; + manifest_url_ = manifest_url; + cache_id_ = cache_id; + entry_ = entry; + is_fallback_ = is_fallback; + + // TODO(ananta) + // Implement the AppCacheServiceImpl::Observer interface or add weak pointer + // support to it. + storage_->LoadResponseInfo(manifest_url_, entry_.response_id(), this); } -AppCacheURLLoaderJob::AppCacheURLLoaderJob() {} +void AppCacheURLLoaderJob::DeliverNetworkResponse() { + delivery_type_ = NETWORK_DELIVERY; + + AppCacheHistograms::AddNetworkJobStartDelaySample(base::TimeTicks::Now() - + start_time_tick_); + + DCHECK(!loader_callback_.is_null()); + // In network service land, if we are processing a navigation request, we + // need to inform the loader callback that we are not going to handle this + // request. The loader callback is valid only for navigation requests. + std::move(loader_callback_).Run(StartLoaderCallback()); +} + +void AppCacheURLLoaderJob::DeliverErrorResponse() { + delivery_type_ = ERROR_DELIVERY; + + // We expect the URLLoaderClient pointer to be valid at this point. + DCHECK(client_info_); + + // AppCacheURLRequestJob uses ERR_FAILED as the error code here. That seems + // to map to HTTP_INTERNAL_SERVER_ERROR. + std::string status("HTTP/1.1 "); + status.append(base::IntToString(net::HTTP_INTERNAL_SERVER_ERROR)); + status.append(" "); + status.append(net::GetHttpReasonPhrase(net::HTTP_INTERNAL_SERVER_ERROR)); + status.append("\0\0", 2); + + ResourceResponseHead response; + response.headers = new net::HttpResponseHeaders(status); + client_info_->OnReceiveResponse(response, base::nullopt, nullptr); + + NotifyCompleted(net::ERR_FAILED); + + AppCacheHistograms::AddErrorJobStartDelaySample(base::TimeTicks::Now() - + start_time_tick_); +} + +const GURL& AppCacheURLLoaderJob::GetURL() const { + return request_.url; +} + +AppCacheURLLoaderJob* AppCacheURLLoaderJob::AsURLLoaderJob() { + return this; +} + +void AppCacheURLLoaderJob::FollowRedirect() { + DCHECK(false); +} + +void AppCacheURLLoaderJob::SetPriority(net::RequestPriority priority, + int32_t intra_priority_value) { + NOTREACHED() << "We don't support SetPriority()"; +} + +void AppCacheURLLoaderJob::Start(mojom::URLLoaderRequest request, + mojom::URLLoaderClientPtr client) { + DCHECK(!binding_.is_bound()); + binding_.Bind(std::move(request)); + + binding_.set_connection_error_handler(base::Bind( + &AppCacheURLLoaderJob::OnConnectionError, StaticAsWeakPtr(this))); + + client_info_ = std::move(client); + + // Send the cached AppCacheResponse if any. + if (info_.get()) + SendResponseInfo(); +} + +AppCacheURLLoaderJob::AppCacheURLLoaderJob(const ResourceRequest& request, + AppCacheStorage* storage) + : request_(request), + storage_(storage->GetWeakPtr()), + start_time_tick_(base::TimeTicks::Now()), + cache_id_(kAppCacheNoCacheId), + is_fallback_(false), + binding_(this), + writable_handle_watcher_(FROM_HERE, + mojo::SimpleWatcher::ArmingPolicy::MANUAL) {} + +void AppCacheURLLoaderJob::OnResponseInfoLoaded( + AppCacheResponseInfo* response_info, + int64_t response_id) { + DCHECK(IsDeliveringAppCacheResponse()); + + if (!storage_.get()) { + DeliverErrorResponse(); + return; + } + + if (response_info) { + info_ = response_info; + reader_.reset( + storage_->CreateResponseReader(manifest_url_, entry_.response_id())); + + DCHECK(!loader_callback_.is_null()); + std::move(loader_callback_) + .Run(base::Bind(&AppCacheURLLoaderJob::Start, StaticAsWeakPtr(this))); + + // TODO(ananta) + // Handle range requests. + + response_body_stream_ = std::move(data_pipe_.producer_handle); + + // TODO(ananta) + // Move the asynchronous reading and mojo pipe handling code to a helper + // class. That would also need a change to BlobURLLoader. + + // Wait for the data pipe to be ready to accept data. + writable_handle_watcher_.Watch( + response_body_stream_.get(), MOJO_HANDLE_SIGNAL_WRITABLE, + base::Bind(&AppCacheURLLoaderJob::OnResponseBodyStreamReady, + StaticAsWeakPtr(this))); + + if (client_info_) + SendResponseInfo(); + + ReadMore(); + } else { + // Error case here. We fallback to the network. + DeliverNetworkResponse(); + AppCacheHistograms::CountResponseRetrieval( + false, IsResourceTypeFrame(request_.resource_type), + manifest_url_.GetOrigin()); + + cache_entry_not_found_ = true; + } +} + +void AppCacheURLLoaderJob::OnReadComplete(int result) { + DLOG(WARNING) << "AppCache read completed with result: " << result; + + bool is_main_resource = IsResourceTypeFrame(request_.resource_type); + + if (result == 0) { + NotifyCompleted(result); + AppCacheHistograms::CountResponseRetrieval(true, is_main_resource, + manifest_url_.GetOrigin()); + return; + } else if (result < 0) { + // TODO(ananta) + // Populate the relevant fields of the ResourceRequestCompletionStatus + // structure. + NotifyCompleted(result); + AppCacheHistograms::CountResponseRetrieval(false, is_main_resource, + manifest_url_.GetOrigin()); + return; + } + + uint32_t bytes_written = static_cast<uint32_t>(result); + response_body_stream_ = pending_write_->Complete(bytes_written); + pending_write_ = nullptr; + ReadMore(); +} + +void AppCacheURLLoaderJob::OnConnectionError() { + if (storage_.get()) + storage_->CancelDelegateCallbacks(this); + base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, this); +} + +void AppCacheURLLoaderJob::SendResponseInfo() { + DCHECK(client_info_); + + // If this is null it means the response information was sent to the client. + if (!data_pipe_.consumer_handle.is_valid()) + return; + + const net::HttpResponseInfo* http_info = info_->http_response_info(); + + ResourceResponseHead response_head; + response_head.headers = http_info->headers; + + // TODO(ananta) + // Copy more fields. + http_info->headers->GetMimeType(&response_head.mime_type); + http_info->headers->GetCharset(&response_head.charset); + + response_head.request_time = http_info->request_time; + response_head.response_time = http_info->response_time; + response_head.content_length = info_->response_data_size(); + + client_info_->OnReceiveResponse(response_head, http_info->ssl_info, + mojom::DownloadedTempFilePtr()); + + client_info_->OnStartLoadingResponseBody( + std::move(data_pipe_.consumer_handle)); +} + +void AppCacheURLLoaderJob::ReadMore() { + DCHECK(!pending_write_.get()); + + uint32_t num_bytes; + // TODO: we should use the abstractions in MojoAsyncResourceHandler. + MojoResult result = NetToMojoPendingBuffer::BeginWrite( + &response_body_stream_, &pending_write_, &num_bytes); + if (result == MOJO_RESULT_SHOULD_WAIT) { + // The pipe is full. We need to wait for it to have more space. + writable_handle_watcher_.ArmOrNotify(); + return; + } else if (result != MOJO_RESULT_OK) { + // The response body stream is in a bad state. Bail. + // TODO(ananta) + // Add proper error handling here. + NotifyCompleted(net::ERR_FAILED); + writable_handle_watcher_.Cancel(); + response_body_stream_.reset(); + return; + } + + CHECK_GT(static_cast<uint32_t>(std::numeric_limits<int>::max()), num_bytes); + scoped_refptr<NetToMojoIOBuffer> buffer = + new NetToMojoIOBuffer(pending_write_.get()); + + reader_->ReadData( + buffer.get(), info_->response_data_size(), + base::Bind(&AppCacheURLLoaderJob::OnReadComplete, StaticAsWeakPtr(this))); +} + +void AppCacheURLLoaderJob::OnResponseBodyStreamReady(MojoResult result) { + // TODO(ananta) + // Add proper error handling here. + if (result != MOJO_RESULT_OK) { + DCHECK(false); + NotifyCompleted(net::ERR_FAILED); + } + ReadMore(); +} + +void AppCacheURLLoaderJob::NotifyCompleted(int error_code) { + if (storage_.get()) + storage_->CancelDelegateCallbacks(this); + // TODO(ananta) + // Fill other details in the ResourceRequestCompletionStatus structure. + ResourceRequestCompletionStatus request_complete_data; + request_complete_data.error_code = error_code; + client_info_->OnComplete(request_complete_data); +} } // namespace content
diff --git a/content/browser/appcache/appcache_url_loader_job.h b/content/browser/appcache/appcache_url_loader_job.h index 3d526c9..3a1e125 100644 --- a/content/browser/appcache/appcache_url_loader_job.h +++ b/content/browser/appcache/appcache_url_loader_job.h
@@ -6,30 +6,40 @@ #define CONTENT_BROWSER_APPCACHE_APPCACHE_URL_LOADER_JOB_H_ #include "base/logging.h" +#include "base/memory/ref_counted.h" +#include "base/memory/weak_ptr.h" #include "base/strings/string16.h" +#include "base/time/time.h" +#include "content/browser/appcache/appcache_entry.h" #include "content/browser/appcache/appcache_job.h" +#include "content/browser/appcache/appcache_response.h" +#include "content/browser/appcache/appcache_storage.h" +#include "content/browser/loader/url_loader_request_handler.h" #include "content/common/content_export.h" +#include "content/common/resource_request.h" +#include "content/common/url_loader.mojom.h" +#include "mojo/public/cpp/bindings/binding.h" +#include "mojo/public/cpp/system/data_pipe.h" namespace content { -class AppCacheHost; class AppCacheRequest; -class AppCacheStorage; +class NetToMojoPendingBuffer; // AppCacheJob wrapper for a mojom::URLLoader implementation which returns // responses stored in the AppCache. -class CONTENT_EXPORT AppCacheURLLoaderJob : public AppCacheJob { +class CONTENT_EXPORT AppCacheURLLoaderJob : public AppCacheJob, + public AppCacheStorage::Delegate, + public mojom::URLLoader { public: ~AppCacheURLLoaderJob() override; + // Sets up the bindings. + void Start(mojom::URLLoaderRequest request, mojom::URLLoaderClientPtr client); + // AppCacheJob overrides. void Kill() override; bool IsStarted() const override; - bool IsWaiting() const override; - bool IsDeliveringAppCacheResponse() const override; - bool IsDeliveringNetworkResponse() const override; - bool IsDeliveringErrorResponse() const override; - bool IsCacheEntryNotFound() const override; void DeliverAppCachedResponse(const GURL& manifest_url, int64_t cache_id, const AppCacheEntry& entry, @@ -37,14 +47,90 @@ void DeliverNetworkResponse() override; void DeliverErrorResponse() override; const GURL& GetURL() const override; + AppCacheURLLoaderJob* AsURLLoaderJob() override; + + // mojom::URLLoader implementation: + void FollowRedirect() override; + void SetPriority(net::RequestPriority priority, + int32_t intra_priority_value) override; + + void set_loader_callback(LoaderCallback callback) { + loader_callback_ = std::move(callback); + } protected: // AppCacheJob::Create() creates this instance. friend class AppCacheJob; - AppCacheURLLoaderJob(); + AppCacheURLLoaderJob(const ResourceRequest& request, + AppCacheStorage* storage); - GURL url_; + // AppCacheStorage::Delegate methods + void OnResponseInfoLoaded(AppCacheResponseInfo* response_info, + int64_t response_id) override; + + // AppCacheResponseReader completion callback + void OnReadComplete(int result); + + void OnConnectionError(); + + // Helper to send the AppCacheResponseInfo to the URLLoaderClient. + void SendResponseInfo(); + + // Helper function to read the data from the AppCache. + void ReadMore(); + + // Callback invoked when the data pipe can be written to. + void OnResponseBodyStreamReady(MojoResult result); + + // Notifies the client about request completion. + void NotifyCompleted(int error_code); + + // The current request. + ResourceRequest request_; + + base::WeakPtr<AppCacheStorage> storage_; + + // The response details. + scoped_refptr<AppCacheResponseInfo> info_; + + // Used to read the cache. + std::unique_ptr<AppCacheResponseReader> reader_; + + // Time when the request started. + base::TimeTicks start_time_tick_; + + // The AppCache manifest URL. + GURL manifest_url_; + + // The AppCache id. + int64_t cache_id_; + + AppCacheEntry entry_; + + // Set to true if we are loading fallback content. + bool is_fallback_; + + // The data pipe used to transfer AppCache data to the client. + mojo::DataPipe data_pipe_; + + // Binds the URLLoaderClient with us. + mojo::Binding<mojom::URLLoader> binding_; + + // The URLLoaderClient pointer. We call this interface with notifications + // about the URL load + mojom::URLLoaderClientPtr client_info_; + + // mojo data pipe entities. + mojo::ScopedDataPipeProducerHandle response_body_stream_; + + scoped_refptr<NetToMojoPendingBuffer> pending_write_; + + mojo::SimpleWatcher writable_handle_watcher_; + + // The Callback to be invoked in the network service land to indicate if + // the request can be serviced via the AppCache. + LoaderCallback loader_callback_; DISALLOW_COPY_AND_ASSIGN(AppCacheURLLoaderJob); };
diff --git a/content/browser/appcache/appcache_url_loader_request.cc b/content/browser/appcache/appcache_url_loader_request.cc index c85de029..11c85ba 100644 --- a/content/browser/appcache/appcache_url_loader_request.cc +++ b/content/browser/appcache/appcache_url_loader_request.cc
@@ -9,27 +9,27 @@ // static std::unique_ptr<AppCacheURLLoaderRequest> AppCacheURLLoaderRequest::Create( - std::unique_ptr<ResourceRequest> request) { + const ResourceRequest& request) { return std::unique_ptr<AppCacheURLLoaderRequest>( - new AppCacheURLLoaderRequest(std::move(request))); + new AppCacheURLLoaderRequest(request)); } AppCacheURLLoaderRequest::~AppCacheURLLoaderRequest() {} const GURL& AppCacheURLLoaderRequest::GetURL() const { - return request_->url; + return request_.url; } const std::string& AppCacheURLLoaderRequest::GetMethod() const { - return request_->method; + return request_.method; } const GURL& AppCacheURLLoaderRequest::GetFirstPartyForCookies() const { - return request_->first_party_for_cookies; + return request_.first_party_for_cookies; } const GURL AppCacheURLLoaderRequest::GetReferrer() const { - return request_->referrer; + return request_.referrer; } bool AppCacheURLLoaderRequest::IsSuccess() const { @@ -54,11 +54,11 @@ } ResourceRequest* AppCacheURLLoaderRequest::GetResourceRequest() { - return request_.get(); + return &request_; } AppCacheURLLoaderRequest::AppCacheURLLoaderRequest( - std::unique_ptr<ResourceRequest> request) - : request_(std::move(request)) {} + const ResourceRequest& request) + : request_(request) {} } // namespace content
diff --git a/content/browser/appcache/appcache_url_loader_request.h b/content/browser/appcache/appcache_url_loader_request.h index 13581f1..97e3f77 100644 --- a/content/browser/appcache/appcache_url_loader_request.h +++ b/content/browser/appcache/appcache_url_loader_request.h
@@ -17,7 +17,7 @@ // Factory function to create an instance of the AppCacheResourceRequest // class. static std::unique_ptr<AppCacheURLLoaderRequest> Create( - std::unique_ptr<ResourceRequest> request); + const ResourceRequest& request); ~AppCacheURLLoaderRequest() override; @@ -38,14 +38,13 @@ bool IsError() const override; int GetResponseCode() const override; std::string GetResponseHeaderByName(const std::string& name) const override; - ResourceRequest* GetResourceRequest() override; protected: - explicit AppCacheURLLoaderRequest(std::unique_ptr<ResourceRequest> request); + explicit AppCacheURLLoaderRequest(const ResourceRequest& request); private: - std::unique_ptr<ResourceRequest> request_; + ResourceRequest request_; DISALLOW_COPY_AND_ASSIGN(AppCacheURLLoaderRequest); };
diff --git a/content/browser/appcache/appcache_url_request_job.cc b/content/browser/appcache/appcache_url_request_job.cc index 8a89def..b17d3d77 100644 --- a/content/browser/appcache/appcache_url_request_job.cc +++ b/content/browser/appcache/appcache_url_request_job.cc
@@ -60,26 +60,6 @@ return has_been_started_; } -bool AppCacheURLRequestJob::IsWaiting() const { - return delivery_type_ == AWAITING_DELIVERY_ORDERS; -} - -bool AppCacheURLRequestJob::IsDeliveringAppCacheResponse() const { - return delivery_type_ == APPCACHED_DELIVERY; -} - -bool AppCacheURLRequestJob::IsDeliveringNetworkResponse() const { - return delivery_type_ == NETWORK_DELIVERY; -} - -bool AppCacheURLRequestJob::IsDeliveringErrorResponse() const { - return delivery_type_ == ERROR_DELIVERY; -} - -bool AppCacheURLRequestJob::IsCacheEntryNotFound() const { - return cache_entry_not_found_; -} - void AppCacheURLRequestJob::DeliverAppCachedResponse(const GURL& manifest_url, int64_t cache_id, const AppCacheEntry& entry, @@ -128,11 +108,9 @@ storage_(storage), has_been_started_(false), has_been_killed_(false), - delivery_type_(AWAITING_DELIVERY_ORDERS), cache_id_(kAppCacheNoCacheId), is_fallback_(false), is_main_resource_(is_main_resource), - cache_entry_not_found_(false), on_prepare_to_restart_callback_(restart_callback) { DCHECK(storage_); }
diff --git a/content/browser/appcache/appcache_url_request_job.h b/content/browser/appcache/appcache_url_request_job.h index 56b3cfa..f4f23a7 100644 --- a/content/browser/appcache/appcache_url_request_job.h +++ b/content/browser/appcache/appcache_url_request_job.h
@@ -44,11 +44,6 @@ // AppCacheJob overrides. void Kill() override; bool IsStarted() const override; - bool IsWaiting() const override; - bool IsDeliveringAppCacheResponse() const override; - bool IsDeliveringNetworkResponse() const override; - bool IsDeliveringErrorResponse() const override; - bool IsCacheEntryNotFound() const override; void DeliverAppCachedResponse(const GURL& manifest_url, int64_t cache_id, const AppCacheEntry& entry, @@ -83,13 +78,6 @@ bool is_main_resource, const OnPrepareToRestartCallback& restart_callback_); - enum DeliveryType { - AWAITING_DELIVERY_ORDERS, - APPCACHED_DELIVERY, - NETWORK_DELIVERY, - ERROR_DELIVERY - }; - // Returns true if one of the Deliver methods has been called. bool has_delivery_orders() const { return !IsWaiting(); } @@ -140,13 +128,11 @@ base::TimeTicks start_time_tick_; bool has_been_started_; bool has_been_killed_; - DeliveryType delivery_type_; GURL manifest_url_; int64_t cache_id_; AppCacheEntry entry_; bool is_fallback_; bool is_main_resource_; // Used for histogram logging. - bool cache_entry_not_found_; scoped_refptr<AppCacheResponseInfo> info_; scoped_refptr<net::GrowableIOBuffer> handler_source_buffer_; std::unique_ptr<AppCacheResponseReader> handler_source_reader_;
diff --git a/content/browser/appcache/mock_appcache_storage.cc b/content/browser/appcache/mock_appcache_storage.cc index a5c5382..1bd3bed5 100644 --- a/content/browser/appcache/mock_appcache_storage.cc +++ b/content/browser/appcache/mock_appcache_storage.cc
@@ -201,6 +201,10 @@ } } +bool MockAppCacheStorage::IsInitialized() { + return false; +} + void MockAppCacheStorage::ProcessGetAllInfo( scoped_refptr<DelegateReference> delegate_ref) { if (delegate_ref->delegate)
diff --git a/content/browser/appcache/mock_appcache_storage.h b/content/browser/appcache/mock_appcache_storage.h index b19404b..d8a6ee3 100644 --- a/content/browser/appcache/mock_appcache_storage.h +++ b/content/browser/appcache/mock_appcache_storage.h
@@ -81,6 +81,7 @@ const std::vector<int64_t>& response_ids) override; void DeleteResponses(const GURL& manifest_url, const std::vector<int64_t>& response_ids) override; + bool IsInitialized() override; private: friend class AppCacheRequestHandlerTest;
diff --git a/content/browser/devtools/protocol/devtools_protocol_browsertest.cc b/content/browser/devtools/protocol/devtools_protocol_browsertest.cc index 2845733e..addd4e1 100644 --- a/content/browser/devtools/protocol/devtools_protocol_browsertest.cc +++ b/content/browser/devtools/protocol/devtools_protocol_browsertest.cc
@@ -1669,14 +1669,6 @@ command_params.reset(new base::DictionaryValue()); command_params->SetBoolean("discover", false); SendCommand("Target.setDiscoverTargets", std::move(command_params), true); - params = WaitForNotification("Target.targetDestroyed", true); - EXPECT_TRUE(params->GetString("targetId", &temp)); - EXPECT_TRUE(ids.find(temp) != ids.end()); - ids.erase(temp); - params = WaitForNotification("Target.targetDestroyed", true); - EXPECT_TRUE(params->GetString("targetId", &temp)); - EXPECT_TRUE(ids.find(temp) != ids.end()); - ids.erase(temp); EXPECT_TRUE(notifications_.empty()); command_params.reset(new base::DictionaryValue());
diff --git a/content/browser/devtools/protocol/target_handler.cc b/content/browser/devtools/protocol/target_handler.cc index 7a51b79..0c32e8f3 100644 --- a/content/browser/devtools/protocol/target_handler.cc +++ b/content/browser/devtools/protocol/target_handler.cc
@@ -218,7 +218,8 @@ auto it = reported_hosts_.find(host->GetId()); if (it == reported_hosts_.end()) return; - frontend_->TargetDestroyed(host->GetId()); + if (discover_) + frontend_->TargetDestroyed(host->GetId()); reported_hosts_.erase(it); }
diff --git a/content/browser/frame_host/form_submission_throttle.cc b/content/browser/frame_host/form_submission_throttle.cc index 5784bbf..5a235d86 100644 --- a/content/browser/frame_host/form_submission_throttle.cc +++ b/content/browser/frame_host/form_submission_throttle.cc
@@ -60,8 +60,12 @@ RenderFrameHostImpl* render_frame = handle->frame_tree_node()->current_frame_host(); + // TODO(estark): Move this check into NavigationRequest and split it into (1) + // check report-only CSP, (2) upgrade request if needed, (3) check enforced + // CSP to match how frame-src works. https://crbug.com/713388 if (render_frame->IsAllowedByCsp(CSPDirective::FormAction, url, is_redirect, - handle->source_location())) { + handle->source_location(), + CSPContext::CHECK_ALL_CSP)) { return NavigationThrottle::PROCEED; }
diff --git a/content/browser/frame_host/mixed_content_navigation_throttle.h b/content/browser/frame_host/mixed_content_navigation_throttle.h index 2313a7d..c7ca00f7 100644 --- a/content/browser/frame_host/mixed_content_navigation_throttle.h +++ b/content/browser/frame_host/mixed_content_navigation_throttle.h
@@ -30,10 +30,6 @@ // // Current mixed content W3C draft that drives this implementation: // https://w3c.github.io/webappsec-mixed-content/ -// -// TODO(carlosk): For HSTS to work properly in PlzNavigate when these browser -// side mixed content checks happen it needs to be ported to the browser as a -// navigation throttle implementation. See https://crbug.com/692157. class MixedContentNavigationThrottle : public NavigationThrottle { public: static std::unique_ptr<NavigationThrottle> CreateThrottleForNavigation(
diff --git a/content/browser/frame_host/navigation_request.cc b/content/browser/frame_host/navigation_request.cc index 521b288..0d1b534 100644 --- a/content/browser/frame_host/navigation_request.cc +++ b/content/browser/frame_host/navigation_request.cc
@@ -950,9 +950,43 @@ RenderFrameHostImpl* parent = parent_ftn->current_frame_host(); DCHECK(parent); + // CSP checking happens in three phases, per steps 3-5 of + // https://fetch.spec.whatwg.org/#main-fetch: + // + // (1) Check report-only policies and trigger reports for any violations. + // (2) Upgrade the request to HTTPS if necessary. + // (3) Check enforced policies (triggering reports for any violations of those + // policies) and block the request if necessary. + // + // This sequence of events allows site owners to learn about (via step 1) any + // requests that are upgraded in step 2. + + bool allowed = parent->IsAllowedByCsp( + CSPDirective::FrameSrc, common_params_.url, is_redirect, + common_params_.source_location.value_or(SourceLocation()), + CSPContext::CHECK_REPORT_ONLY_CSP); + + // Checking report-only CSP should never return false because no requests are + // blocked by report-only policies. + DCHECK(allowed); + + // TODO(mkwst,estark): upgrade-insecure-requests does not work when following + // redirects. Trying to uprade the new URL on redirect here is fruitless: the + // redirect URL cannot be changed at this point. upgrade-insecure-requests + // needs to move to the net stack to resolve this. https://crbug.com/615885 + if (!is_redirect) { + GURL new_url; + if (parent->ShouldModifyRequestUrlForCsp( + common_params_.url, true /* is subresource */, &new_url)) { + common_params_.url = new_url; + request_params_.original_url = new_url; + } + } + if (parent->IsAllowedByCsp( CSPDirective::FrameSrc, common_params_.url, is_redirect, - common_params_.source_location.value_or(SourceLocation()))) { + common_params_.source_location.value_or(SourceLocation()), + CSPContext::CHECK_ENFORCED_CSP)) { return CONTENT_SECURITY_POLICY_CHECK_PASSED; }
diff --git a/content/browser/frame_host/render_widget_host_view_child_frame_browsertest.cc b/content/browser/frame_host/render_widget_host_view_child_frame_browsertest.cc index d03ebb4b..b572962 100644 --- a/content/browser/frame_host/render_widget_host_view_child_frame_browsertest.cc +++ b/content/browser/frame_host/render_widget_host_view_child_frame_browsertest.cc
@@ -3,8 +3,11 @@ // found in the LICENSE file. #include "base/macros.h" +#include "cc/surfaces/surface_id.h" +#include "cc/surfaces/surface_sequence.h" #include "content/browser/frame_host/frame_tree_node.h" #include "content/browser/web_contents/web_contents_impl.h" +#include "content/common/frame_messages.h" #include "content/common/view_messages.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/web_contents.h" @@ -114,4 +117,92 @@ EXPECT_EQ(gfx::Size(75, 75), rwhv->GetVisibleViewportSize()); } +// A class to filter RequireSequence and SatisfySequence messages sent from +// an embedding renderer for its child's Surfaces. +class SurfaceRefMessageFilter : public BrowserMessageFilter { + public: + SurfaceRefMessageFilter() + : BrowserMessageFilter(FrameMsgStart), + require_message_loop_runner_(new content::MessageLoopRunner), + satisfy_message_loop_runner_(new content::MessageLoopRunner), + satisfy_received_(false), + require_received_first_(false) {} + + void WaitForRequire() { require_message_loop_runner_->Run(); } + + void WaitForSatisfy() { satisfy_message_loop_runner_->Run(); } + + bool require_received_first() { return require_received_first_; } + + protected: + ~SurfaceRefMessageFilter() override {} + + private: + // BrowserMessageFilter: + bool OnMessageReceived(const IPC::Message& message) override { + IPC_BEGIN_MESSAGE_MAP(SurfaceRefMessageFilter, message) + IPC_MESSAGE_HANDLER(FrameHostMsg_RequireSequence, OnRequire) + IPC_MESSAGE_HANDLER(FrameHostMsg_SatisfySequence, OnSatisfy) + IPC_END_MESSAGE_MAP() + return false; + } + + void OnRequire(const cc::SurfaceId& id, const cc::SurfaceSequence sequence) { + content::BrowserThread::PostTask( + content::BrowserThread::UI, FROM_HERE, + base::Bind(&SurfaceRefMessageFilter::OnRequireOnUI, this)); + } + + void OnRequireOnUI() { + if (!satisfy_received_) + require_received_first_ = true; + require_message_loop_runner_->Quit(); + } + + void OnSatisfy(const cc::SurfaceSequence sequence) { + content::BrowserThread::PostTask( + content::BrowserThread::UI, FROM_HERE, + base::Bind(&SurfaceRefMessageFilter::OnSatisfyOnUI, this)); + } + + void OnSatisfyOnUI() { + satisfy_received_ = true; + satisfy_message_loop_runner_->Quit(); + } + + scoped_refptr<content::MessageLoopRunner> require_message_loop_runner_; + scoped_refptr<content::MessageLoopRunner> satisfy_message_loop_runner_; + bool satisfy_received_; + bool require_received_first_; + + DISALLOW_COPY_AND_ASSIGN(SurfaceRefMessageFilter); +}; + +// Test that when a child frame submits its first compositor frame, the +// embedding renderer process properly acquires and releases references to the +// new Surface. See https://crbug.com/701175. +IN_PROC_BROWSER_TEST_F(RenderWidgetHostViewChildFrameTest, + ChildFrameSurfaceReference) { + EXPECT_TRUE(NavigateToURL( + shell(), embedded_test_server()->GetURL( + "a.com", "/cross_site_iframe_factory.html?a(a)"))); + + FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents()) + ->GetFrameTree() + ->root(); + ASSERT_EQ(1U, root->child_count()); + + scoped_refptr<SurfaceRefMessageFilter> filter = new SurfaceRefMessageFilter(); + root->current_frame_host()->GetProcess()->AddFilter(filter.get()); + + GURL foo_url = embedded_test_server()->GetURL("foo.com", "/title1.html"); + NavigateFrameToURL(root->child_at(0), foo_url); + + // If one of these messages isn't received, this test times out. + filter->WaitForRequire(); + filter->WaitForSatisfy(); + + EXPECT_TRUE(filter->require_received_first()); +} + } // namespace content
diff --git a/content/browser/indexed_db/indexed_db_transaction.cc b/content/browser/indexed_db/indexed_db_transaction.cc index 8bc011e5..63a1f13 100644 --- a/content/browser/indexed_db/indexed_db_transaction.cc +++ b/content/browser/indexed_db/indexed_db_transaction.cc
@@ -377,26 +377,28 @@ committed = true; } else { base::TimeDelta active_time = base::Time::Now() - diagnostics_.start_time; - uint64_t size = transaction_->GetTransactionSize() / 1024; + uint64_t size_kb = transaction_->GetTransactionSize() / 1024; + // All histograms record 1KB to 1GB. switch (mode_) { case blink::kWebIDBTransactionModeReadOnly: UMA_HISTOGRAM_MEDIUM_TIMES( "WebCore.IndexedDB.Transaction.ReadOnly.TimeActive", active_time); - UMA_HISTOGRAM_MEMORY_KB( - "WebCore.IndexedDB.Transaction.ReadOnly.SizeOnCommit", size); + UMA_HISTOGRAM_COUNTS_1M( + "WebCore.IndexedDB.Transaction.ReadOnly.SizeOnCommit2", size_kb); break; case blink::kWebIDBTransactionModeReadWrite: UMA_HISTOGRAM_MEDIUM_TIMES( "WebCore.IndexedDB.Transaction.ReadWrite.TimeActive", active_time); - UMA_HISTOGRAM_MEMORY_KB( - "WebCore.IndexedDB.Transaction.ReadWrite.SizeOnCommit", size); + UMA_HISTOGRAM_COUNTS_1M( + "WebCore.IndexedDB.Transaction.ReadWrite.SizeOnCommit2", size_kb); break; case blink::kWebIDBTransactionModeVersionChange: UMA_HISTOGRAM_MEDIUM_TIMES( "WebCore.IndexedDB.Transaction.VersionChange.TimeActive", active_time); - UMA_HISTOGRAM_MEMORY_KB( - "WebCore.IndexedDB.Transaction.VersionChange.SizeOnCommit", size); + UMA_HISTOGRAM_COUNTS_1M( + "WebCore.IndexedDB.Transaction.VersionChange.SizeOnCommit2", + size_kb); break; default: NOTREACHED();
diff --git a/content/browser/loader/navigation_url_loader_network_service.cc b/content/browser/loader/navigation_url_loader_network_service.cc index e9e9ac9..e358cb19 100644 --- a/content/browser/loader/navigation_url_loader_network_service.cc +++ b/content/browser/loader/navigation_url_loader_network_service.cc
@@ -9,6 +9,7 @@ #include "base/memory/ptr_util.h" #include "base/trace_event/trace_event.h" #include "content/browser/appcache/appcache_navigation_handle.h" +#include "content/browser/appcache/appcache_request_handler.h" #include "content/browser/blob_storage/chrome_blob_storage_context.h" #include "content/browser/frame_host/frame_tree_node.h" #include "content/browser/frame_host/navigation_request_info.h" @@ -166,7 +167,11 @@ } if (appcache_handle_core) { - // TODO: add appcache code here. + std::unique_ptr<URLLoaderRequestHandler> appcache_handler = + AppCacheRequestHandler::InitializeForNavigationNetworkService( + *resource_request_, appcache_handle_core); + if (appcache_handler) + handlers_.push_back(std::move(appcache_handler)); } Restart(std::move(url_loader_request), std::move(url_loader_client_ptr_));
diff --git a/content/browser/presentation/presentation_service_impl.cc b/content/browser/presentation/presentation_service_impl.cc index ea75760..4f3e8b2 100644 --- a/content/browser/presentation/presentation_service_impl.cc +++ b/content/browser/presentation/presentation_service_impl.cc
@@ -123,7 +123,8 @@ void PresentationServiceImpl::ListenForScreenAvailability(const GURL& url) { DVLOG(2) << "ListenForScreenAvailability " << url.spec(); if (!controller_delegate_) { - client_->OnScreenAvailabilityUpdated(url, false); + client_->OnScreenAvailabilityUpdated( + url, blink::mojom::ScreenAvailability::UNAVAILABLE); return; } @@ -491,7 +492,10 @@ void PresentationServiceImpl::ScreenAvailabilityListenerImpl ::OnScreenAvailabilityChanged(bool available) { - service_->client_->OnScreenAvailabilityUpdated(availability_url_, available); + service_->client_->OnScreenAvailabilityUpdated( + availability_url_, available + ? blink::mojom::ScreenAvailability::AVAILABLE + : blink::mojom::ScreenAvailability::UNAVAILABLE); } void PresentationServiceImpl::ScreenAvailabilityListenerImpl
diff --git a/content/browser/presentation/presentation_service_impl_unittest.cc b/content/browser/presentation/presentation_service_impl_unittest.cc index c7fe639c..2535bce 100644 --- a/content/browser/presentation/presentation_service_impl_unittest.cc +++ b/content/browser/presentation/presentation_service_impl_unittest.cc
@@ -196,7 +196,8 @@ : public blink::mojom::PresentationServiceClient { public: MOCK_METHOD2(OnScreenAvailabilityUpdated, - void(const GURL& url, bool available)); + void(const GURL& url, + blink::mojom::ScreenAvailability availability)); MOCK_METHOD2(OnConnectionStateChanged, void(const PresentationInfo& connection, PresentationConnectionState new_state)); @@ -317,7 +318,11 @@ ASSERT_TRUE(listener_it->second); base::RunLoop run_loop; - EXPECT_CALL(mock_client_, OnScreenAvailabilityUpdated(url, available)) + blink::mojom::ScreenAvailability expected_availability = + available ? blink::mojom::ScreenAvailability::AVAILABLE + : blink::mojom::ScreenAvailability::UNAVAILABLE; + EXPECT_CALL(mock_client_, + OnScreenAvailabilityUpdated(url, expected_availability)) .WillOnce(InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit)); listener_it->second->OnScreenAvailabilityChanged(available); run_loop.Run();
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc index fc876c6..b5bb568 100644 --- a/content/browser/renderer_host/render_process_host_impl.cc +++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -1778,11 +1778,14 @@ resource_coordinator::ResourceCoordinatorInterface* RenderProcessHostImpl::GetProcessResourceCoordinator() { if (!process_resource_coordinator_) { + base::ProcessHandle process_handle = GetHandle(); + DCHECK(process_handle); + process_resource_coordinator_ = base::MakeUnique<resource_coordinator::ResourceCoordinatorInterface>( ServiceManagerConnection::GetForProcess()->GetConnector(), resource_coordinator::CoordinationUnitType::kProcess, - base::Process(GetHandle()).Pid()); + base::Process(process_handle).Pid()); } return process_resource_coordinator_.get(); } @@ -3201,6 +3204,7 @@ if (route_provider_binding_.is_bound()) route_provider_binding_.Close(); associated_interfaces_.reset(); + process_resource_coordinator_.reset(); ResetChannelProxy(); UpdateProcessPriority();
diff --git a/content/browser/url_loader_factory_getter.cc b/content/browser/url_loader_factory_getter.cc index 4cf6d39..d5013516 100644 --- a/content/browser/url_loader_factory_getter.cc +++ b/content/browser/url_loader_factory_getter.cc
@@ -5,7 +5,6 @@ #include "content/browser/url_loader_factory_getter.h" #include "base/bind.h" -#include "content/browser/appcache/appcache_url_loader_factory.h" #include "content/browser/storage_partition_impl.h" #include "content/common/network_service.mojom.h" @@ -26,9 +25,7 @@ BrowserThread::IO, FROM_HERE, base::BindOnce(&URLLoaderFactoryGetter::InitializeOnIOThread, this, network_factory.PassInterface(), - blob_factory.PassInterface(), - scoped_refptr<ChromeAppCacheService>( - partition->GetAppCacheService()))); + blob_factory.PassInterface())); } mojom::URLLoaderFactoryPtr* URLLoaderFactoryGetter::GetNetworkFactory() { @@ -52,22 +49,13 @@ this, test_factory.PassInterface())); } -mojom::URLLoaderFactoryPtr* URLLoaderFactoryGetter::GetAppCacheFactory() { - DCHECK_CURRENTLY_ON(BrowserThread::IO); - return &appcache_factory_; -} - URLLoaderFactoryGetter::~URLLoaderFactoryGetter() {} void URLLoaderFactoryGetter::InitializeOnIOThread( mojom::URLLoaderFactoryPtrInfo network_factory, - mojom::URLLoaderFactoryPtrInfo blob_factory, - scoped_refptr<ChromeAppCacheService> appcache_service) { + mojom::URLLoaderFactoryPtrInfo blob_factory) { network_factory_.Bind(std::move(network_factory)); blob_factory_.Bind(std::move(blob_factory)); - - AppCacheURLLoaderFactory::CreateURLLoaderFactory( - mojo::MakeRequest(&appcache_factory_), appcache_service.get(), this); } void URLLoaderFactoryGetter::SetTestNetworkFactoryOnIOThread(
diff --git a/content/browser/url_loader_factory_getter.h b/content/browser/url_loader_factory_getter.h index 0af16fd..1ea7281 100644 --- a/content/browser/url_loader_factory_getter.h +++ b/content/browser/url_loader_factory_getter.h
@@ -13,7 +13,6 @@ namespace content { -class ChromeAppCacheService; class StoragePartitionImpl; // Holds on to URLLoaderFactory for a given StoragePartition and allows code @@ -43,25 +42,18 @@ CONTENT_EXPORT void SetNetworkFactoryForTesting( mojom::URLLoaderFactoryPtr test_factory); - // Called on the IO thread to get the URLLoaderFactory for AppCache. The - // pointer should not be cached. - mojom::URLLoaderFactoryPtr* GetAppCacheFactory(); - private: friend class base::DeleteHelper<URLLoaderFactoryGetter>; friend struct BrowserThread::DeleteOnThread<BrowserThread::IO>; CONTENT_EXPORT ~URLLoaderFactoryGetter(); - void InitializeOnIOThread( - mojom::URLLoaderFactoryPtrInfo network_factory, - mojom::URLLoaderFactoryPtrInfo blob_factory, - scoped_refptr<ChromeAppCacheService> appcache_service); + void InitializeOnIOThread(mojom::URLLoaderFactoryPtrInfo network_factory, + mojom::URLLoaderFactoryPtrInfo blob_factory); void SetTestNetworkFactoryOnIOThread( mojom::URLLoaderFactoryPtrInfo test_factory); // Only accessed on IO thread. mojom::URLLoaderFactoryPtr network_factory_; - mojom::URLLoaderFactoryPtr appcache_factory_; mojom::URLLoaderFactoryPtr blob_factory_; mojom::URLLoaderFactoryPtr test_factory_;
diff --git a/content/browser/webrtc/webrtc_image_capture_browsertest.cc b/content/browser/webrtc/webrtc_image_capture_browsertest.cc index 687c325..eb541ba 100644 --- a/content/browser/webrtc/webrtc_image_capture_browsertest.cc +++ b/content/browser/webrtc/webrtc_image_capture_browsertest.cc
@@ -28,6 +28,14 @@ #define MAYBE_GetTrackCapabilities DISABLED_GetTrackCapabilities #define MAYBE_GetTrackSettings DISABLED_GetTrackSettings #define MAYBE_ManipulateZoom DISABLED_ManipulateZoom +#elif defined(OS_ANDROID) +#define MAYBE_GetPhotoCapabilities GetPhotoCapabilities +#define MAYBE_TakePhoto TakePhoto +#define MAYBE_GrabFrame GrabFrame +// TODO(mcasas): these fail on Android devices: https://crbug.com/731904. +#define MAYBE_GetTrackCapabilities DISABLED_GetTrackCapabilities +#define MAYBE_GetTrackSettings DISABLED_GetTrackSettings +#define MAYBE_ManipulateZoom DISABLED_ManipulateZoom #else #define MAYBE_GetPhotoCapabilities GetPhotoCapabilities #define MAYBE_TakePhoto TakePhoto
diff --git a/content/common/content_security_policy/content_security_policy.cc b/content/common/content_security_policy/content_security_policy.cc index 299a4c2..f0e93a50 100644 --- a/content/common/content_security_policy/content_security_policy.cc +++ b/content/common/content_security_policy/content_security_policy.cc
@@ -15,6 +15,7 @@ switch (directive) { case CSPDirective::DefaultSrc: case CSPDirective::FormAction: + case CSPDirective::UpgradeInsecureRequests: return CSPDirective::Unknown; case CSPDirective::FrameSrc: @@ -186,4 +187,14 @@ return text.str(); } +// static +bool ContentSecurityPolicy::ShouldUpgradeInsecureRequest( + const ContentSecurityPolicy& policy) { + for (const CSPDirective& directive : policy.directives) { + if (directive.name == CSPDirective::UpgradeInsecureRequests) + return true; + } + return false; +} + } // namespace content
diff --git a/content/common/content_security_policy/content_security_policy.h b/content/common/content_security_policy/content_security_policy.h index d4de5237..d531b4c 100644 --- a/content/common/content_security_policy/content_security_policy.h +++ b/content/common/content_security_policy/content_security_policy.h
@@ -45,6 +45,10 @@ bool is_redirect, CSPContext* context, const SourceLocation& source_location); + + // Returns true if |policy| specifies that an insecure HTTP request should be + // upgraded to HTTPS. + static bool ShouldUpgradeInsecureRequest(const ContentSecurityPolicy& policy); }; } // namespace content
diff --git a/content/common/content_security_policy/content_security_policy_unittest.cc b/content/common/content_security_policy/content_security_policy_unittest.cc index ee9ae79..e14a041 100644 --- a/content/common/content_security_policy/content_security_policy_unittest.cc +++ b/content/common/content_security_policy/content_security_policy_unittest.cc
@@ -238,4 +238,20 @@ false, &context, SourceLocation())); } +TEST(ContentSecurityPolicy, ShouldUpgradeInsecureRequest) { + std::vector<std::string> report_end_points; // empty + CSPSource source("https", "example.com", false, url::PORT_UNSPECIFIED, false, + ""); + CSPSourceList source_list(false, false, {source}); + ContentSecurityPolicy policy( + EmptyCspHeader(), {CSPDirective(CSPDirective::DefaultSrc, source_list)}, + report_end_points); + + EXPECT_FALSE(ContentSecurityPolicy::ShouldUpgradeInsecureRequest(policy)); + + policy.directives.push_back( + CSPDirective(CSPDirective::UpgradeInsecureRequests, CSPSourceList())); + EXPECT_TRUE(ContentSecurityPolicy::ShouldUpgradeInsecureRequest(policy)); +} + } // namespace content
diff --git a/content/common/content_security_policy/csp_context.cc b/content/common/content_security_policy/csp_context.cc index 194a8a1..7d3aebef 100644 --- a/content/common/content_security_policy/csp_context.cc +++ b/content/common/content_security_policy/csp_context.cc
@@ -6,6 +6,26 @@ namespace content { +namespace { + +// Helper function that returns true if |policy| should be checked under +// |check_csp_disposition|. +bool ShouldCheckPolicy(const ContentSecurityPolicy& policy, + CSPContext::CheckCSPDisposition check_csp_disposition) { + switch (check_csp_disposition) { + case CSPContext::CHECK_REPORT_ONLY_CSP: + return policy.header.type == blink::kWebContentSecurityPolicyTypeReport; + case CSPContext::CHECK_ENFORCED_CSP: + return policy.header.type == blink::kWebContentSecurityPolicyTypeEnforce; + case CSPContext::CHECK_ALL_CSP: + return true; + } + NOTREACHED(); + return true; +} + +} // namespace + CSPContext::CSPContext() : has_self_(false) {} CSPContext::~CSPContext() {} @@ -13,18 +33,41 @@ bool CSPContext::IsAllowedByCsp(CSPDirective::Name directive_name, const GURL& url, bool is_redirect, - const SourceLocation& source_location) { + const SourceLocation& source_location, + CheckCSPDisposition check_csp_disposition) { if (SchemeShouldBypassCSP(url.scheme_piece())) return true; bool allow = true; for (const auto& policy : policies_) { - allow &= ContentSecurityPolicy::Allow(policy, directive_name, url, - is_redirect, this, source_location); + if (ShouldCheckPolicy(policy, check_csp_disposition)) { + allow &= ContentSecurityPolicy::Allow(policy, directive_name, url, + is_redirect, this, source_location); + } } return allow; } +bool CSPContext::ShouldModifyRequestUrlForCsp( + const GURL& url, + bool is_subresource_or_form_submission, + GURL* new_url) { + for (const auto& policy : policies_) { + if (url.scheme() == "http" && + ContentSecurityPolicy::ShouldUpgradeInsecureRequest(policy) && + is_subresource_or_form_submission) { + *new_url = url; + GURL::Replacements replacements; + replacements.SetSchemeStr("https"); + if (url.port() == "80") + replacements.SetPortStr("443"); + *new_url = new_url->ReplaceComponents(replacements); + return true; + } + } + return false; +} + void CSPContext::SetSelf(const url::Origin origin) { if (origin.unique()) { // TODO(arthursonzogni): Decide what to do with unique origins.
diff --git a/content/common/content_security_policy/csp_context.h b/content/common/content_security_policy/csp_context.h index 4cf89b9..51471f43 100644 --- a/content/common/content_security_policy/csp_context.h +++ b/content/common/content_security_policy/csp_context.h
@@ -24,6 +24,18 @@ // is in content/browser/frame_host/render_frame_host_impl.h class CONTENT_EXPORT CSPContext { public: + // This enum represents what set of policies should be checked by + // IsAllowedByCsp(). + enum CheckCSPDisposition { + // Only check report-only policies. + CHECK_REPORT_ONLY_CSP, + // Only check enforced policies. (Note that enforced policies can still + // trigger reports.) + CHECK_ENFORCED_CSP, + // Check all policies. + CHECK_ALL_CSP, + }; + CSPContext(); virtual ~CSPContext(); @@ -36,7 +48,15 @@ bool IsAllowedByCsp(CSPDirective::Name directive_name, const GURL& url, bool is_redirect, - const SourceLocation& source_location); + const SourceLocation& source_location, + CheckCSPDisposition check_csp_disposition); + + // Returns true if the request URL needs to be modified (e.g. upgraded to + // HTTPS) according to the CSP. If true, |new_url| will contain the new URL + // that should be used instead of |url|. + bool ShouldModifyRequestUrlForCsp(const GURL& url, + bool is_suresource_or_form_submssion, + GURL* new_url); void SetSelf(const url::Origin origin); bool AllowSelf(const GURL& url);
diff --git a/content/common/content_security_policy/csp_context_unittest.cc b/content/common/content_security_policy/csp_context_unittest.cc index ce32854..d3a7c16 100644 --- a/content/common/content_security_policy/csp_context_unittest.cc +++ b/content/common/content_security_policy/csp_context_unittest.cc
@@ -25,6 +25,8 @@ return scheme_to_bypass_.count(scheme.as_string()); } + void ClearViolations() { violations_.clear(); } + void set_sanitize_data_for_use_in_csp_violation(bool value) { sanitize_data_for_use_in_csp_violation_ = value; } @@ -70,15 +72,15 @@ context.AddContentSecurityPolicy( BuildPolicy(CSPDirective::DefaultSrc, {source})); - EXPECT_FALSE(context.IsAllowedByCsp(CSPDirective::FrameSrc, - GURL("data:text/html,<html></html>"), - false, SourceLocation())); + EXPECT_FALSE(context.IsAllowedByCsp( + CSPDirective::FrameSrc, GURL("data:text/html,<html></html>"), false, + SourceLocation(), CSPContext::CHECK_ALL_CSP)); context.AddSchemeToBypassCSP("data"); - EXPECT_TRUE(context.IsAllowedByCsp(CSPDirective::FrameSrc, - GURL("data:text/html,<html></html>"), - false, SourceLocation())); + EXPECT_TRUE(context.IsAllowedByCsp( + CSPDirective::FrameSrc, GURL("data:text/html,<html></html>"), false, + SourceLocation(), CSPContext::CHECK_ALL_CSP)); } TEST(CSPContextTest, MultiplePolicies) { @@ -95,13 +97,17 @@ BuildPolicy(CSPDirective::FrameSrc, {source_a, source_c})); EXPECT_TRUE(context.IsAllowedByCsp( - CSPDirective::FrameSrc, GURL("http://a.com"), false, SourceLocation())); + CSPDirective::FrameSrc, GURL("http://a.com"), false, SourceLocation(), + CSPContext::CHECK_ALL_CSP)); EXPECT_FALSE(context.IsAllowedByCsp( - CSPDirective::FrameSrc, GURL("http://b.com"), false, SourceLocation())); + CSPDirective::FrameSrc, GURL("http://b.com"), false, SourceLocation(), + CSPContext::CHECK_ALL_CSP)); EXPECT_FALSE(context.IsAllowedByCsp( - CSPDirective::FrameSrc, GURL("http://c.com"), false, SourceLocation())); + CSPDirective::FrameSrc, GURL("http://c.com"), false, SourceLocation(), + CSPContext::CHECK_ALL_CSP)); EXPECT_FALSE(context.IsAllowedByCsp( - CSPDirective::FrameSrc, GURL("http://d.com"), false, SourceLocation())); + CSPDirective::FrameSrc, GURL("http://d.com"), false, SourceLocation(), + CSPContext::CHECK_ALL_CSP)); } TEST(CSPContextTest, SanitizeDataForUseInCspViolation) { @@ -120,7 +126,8 @@ // When the |blocked_url| and |source_location| aren't sensitive information. { EXPECT_FALSE(context.IsAllowedByCsp(CSPDirective::FrameSrc, blocked_url, - false, source_location)); + false, source_location, + CSPContext::CHECK_ALL_CSP)); ASSERT_EQ(1u, context.violations().size()); EXPECT_EQ(context.violations()[0].blocked_url, blocked_url); EXPECT_EQ(context.violations()[0].source_location.url, @@ -138,7 +145,8 @@ // When the |blocked_url| and |source_location| are sensitive information. { EXPECT_FALSE(context.IsAllowedByCsp(CSPDirective::FrameSrc, blocked_url, - false, source_location)); + false, source_location, + CSPContext::CHECK_ALL_CSP)); ASSERT_EQ(2u, context.violations().size()); EXPECT_EQ(context.violations()[1].blocked_url, blocked_url.GetOrigin()); EXPECT_EQ(context.violations()[1].source_location.url, "http://a.com/"); @@ -168,7 +176,8 @@ BuildPolicy(CSPDirective::FrameSrc, {source_c})); EXPECT_FALSE(context.IsAllowedByCsp( - CSPDirective::FrameSrc, GURL("http://c.com"), false, SourceLocation())); + CSPDirective::FrameSrc, GURL("http://c.com"), false, SourceLocation(), + CSPContext::CHECK_ALL_CSP)); ASSERT_EQ(2u, context.violations().size()); const char console_message_a[] = "Refused to frame 'http://c.com/' because it violates the following " @@ -180,4 +189,88 @@ EXPECT_EQ(console_message_b, context.violations()[1].console_message); } +// Tests that the CheckCSPDisposition parameter is obeyed. +TEST(CSPContextTest, CheckCSPDisposition) { + CSPSource source("", "example.com", false, url::PORT_UNSPECIFIED, false, ""); + CSPContextTest context; + + // Add an enforced policy. + context.AddContentSecurityPolicy( + BuildPolicy(CSPDirective::FrameSrc, {source})); + + // Add a report-only policy. + ContentSecurityPolicy report_only = + BuildPolicy(CSPDirective::DefaultSrc, {source}); + report_only.header.type = blink::kWebContentSecurityPolicyTypeReport; + context.AddContentSecurityPolicy(report_only); + + // With CHECK_ALL_CSP, both policies should be checked and violations should + // be reported. + EXPECT_FALSE(context.IsAllowedByCsp( + CSPDirective::FrameSrc, GURL("https://not-example.com"), false, + SourceLocation(), CSPContext::CHECK_ALL_CSP)); + ASSERT_EQ(2u, context.violations().size()); + const char console_message_a[] = + "Refused to frame 'https://not-example.com/' because it violates the " + "following " + "Content Security Policy directive: \"frame-src example.com\".\n"; + const char console_message_b[] = + "[Report Only] Refused to frame 'https://not-example.com/' because it " + "violates the following " + "Content Security Policy directive: \"default-src example.com\". Note " + "that 'frame-src' was not explicitly set, so 'default-src' is used as a " + "fallback.\n"; + // Both console messages must appear in the reported violations. + EXPECT_TRUE((console_message_a == context.violations()[0].console_message && + console_message_b == context.violations()[1].console_message) || + (console_message_a == context.violations()[1].console_message && + console_message_b == context.violations()[0].console_message)); + + // With CHECK_REPORT_ONLY_CSP, the request should be allowed but reported. + context.ClearViolations(); + EXPECT_TRUE(context.IsAllowedByCsp( + CSPDirective::FrameSrc, GURL("https://not-example.com"), false, + SourceLocation(), CSPContext::CHECK_REPORT_ONLY_CSP)); + ASSERT_EQ(1u, context.violations().size()); + EXPECT_EQ(console_message_b, context.violations()[0].console_message); + + // With CHECK_ENFORCED_CSP, the request should be blocked and only the + // enforced policy violation should be reported. + context.ClearViolations(); + EXPECT_FALSE(context.IsAllowedByCsp( + CSPDirective::FrameSrc, GURL("https://not-example.com"), false, + SourceLocation(), CSPContext::CHECK_ENFORCED_CSP)); + ASSERT_EQ(1u, context.violations().size()); + EXPECT_EQ(console_message_a, context.violations()[0].console_message); +} + +// Tests HTTP subresources and form submissions have their URLs upgraded when +// upgrade-insecure-requests is present. +TEST(CSPContextTest, ShouldModifyRequestUrlForCsp) { + CSPContextTest context; + context.AddContentSecurityPolicy(BuildPolicy( + CSPDirective::UpgradeInsecureRequests, std::vector<CSPSource>())); + GURL new_url; + // An HTTP subresource or form submission should be upgraded. + EXPECT_TRUE(context.ShouldModifyRequestUrlForCsp(GURL("http://example.com"), + true, &new_url)); + EXPECT_EQ(GURL("https://example.com"), new_url); + EXPECT_TRUE(context.ShouldModifyRequestUrlForCsp( + GURL("http://example.com:80"), true, &new_url)); + EXPECT_EQ(GURL("https://example.com:443"), new_url); + // Non-standard ports should not be modified. + EXPECT_TRUE(context.ShouldModifyRequestUrlForCsp( + GURL("http://example-weird-port.com:8088"), true, &new_url)); + EXPECT_EQ(GURL("https://example-weird-port.com:8088"), new_url); + + // Non-HTTP URLs don't need to be modified. + EXPECT_FALSE(context.ShouldModifyRequestUrlForCsp(GURL("https://example.com"), + true, &new_url)); + EXPECT_FALSE(context.ShouldModifyRequestUrlForCsp( + GURL("data:text/html,<html></html>"), true, &new_url)); + // Nor do main-frame navigation requests. + EXPECT_FALSE(context.ShouldModifyRequestUrlForCsp(GURL("http://example.com"), + false, &new_url)); +} + } // namespace content
diff --git a/content/common/content_security_policy/csp_directive.cc b/content/common/content_security_policy/csp_directive.cc index 8727e82..d518a4b5 100644 --- a/content/common/content_security_policy/csp_directive.cc +++ b/content/common/content_security_policy/csp_directive.cc
@@ -28,6 +28,8 @@ return "frame-src"; case FormAction: return "form-action"; + case UpgradeInsecureRequests: + return "upgrade-insecure-requests"; case Unknown: return ""; } @@ -45,6 +47,8 @@ return CSPDirective::FrameSrc; if (name == "form-action") return CSPDirective::FormAction; + if (name == "upgrade-insecure-requests") + return CSPDirective::UpgradeInsecureRequests; return CSPDirective::Unknown; }
diff --git a/content/common/content_security_policy/csp_directive.h b/content/common/content_security_policy/csp_directive.h index 15c0069..914ab18 100644 --- a/content/common/content_security_policy/csp_directive.h +++ b/content/common/content_security_policy/csp_directive.h
@@ -26,6 +26,7 @@ ChildSrc, FrameSrc, FormAction, + UpgradeInsecureRequests, Unknown, NameLast = Unknown,
diff --git a/content/common/throttling_url_loader.cc b/content/common/throttling_url_loader.cc index aee6e0d..beec7cc 100644 --- a/content/common/throttling_url_loader.cc +++ b/content/common/throttling_url_loader.cc
@@ -124,7 +124,7 @@ } mojom::URLLoaderClientPtr client; - client_binding_.Bind(mojo::MakeRequest(&client, std::move(task_runner))); + client_binding_.Bind(mojo::MakeRequest(&client), std::move(task_runner)); factory->CreateLoaderAndStart(mojo::MakeRequest(&url_loader_), routing_id, request_id, options, *url_request, std::move(client)); @@ -257,7 +257,7 @@ case DEFERRED_START: { mojom::URLLoaderClientPtr client; client_binding_.Bind( - mojo::MakeRequest(&client, std::move(start_info_->task_runner))); + mojo::MakeRequest(&client), std::move(start_info_->task_runner)); start_info_->url_loader_factory->CreateLoaderAndStart( mojo::MakeRequest(&url_loader_), start_info_->routing_id, start_info_->request_id, start_info_->options,
diff --git a/content/content_resources.grd b/content/content_resources.grd index 7eb6571..e28a8db7 100644 --- a/content/content_resources.grd +++ b/content/content_resources.grd
@@ -47,6 +47,7 @@ <include name="IDR_COMMON_SANDBOX_PROFILE" file="common/common.sb" type="BINDATA" /> <include name="IDR_PPAPI_SANDBOX_PROFILE" file="ppapi_plugin/ppapi.sb" type="BINDATA" /> <include name="IDR_RENDERER_SANDBOX_PROFILE" file="renderer/renderer.sb" type="BINDATA" /> + <include name="IDR_RENDERER_SANDBOX_V2_PROFILE" file="renderer/renderer_v2.sb" type="BINDATA" /> <include name="IDR_UTILITY_SANDBOX_PROFILE" file="utility/utility.sb" type="BINDATA" /> </if> <if expr="not is_ios">
diff --git a/content/renderer/child_frame_compositing_helper.cc b/content/renderer/child_frame_compositing_helper.cc index 022d3009..8d715a2 100644 --- a/content/renderer/child_frame_compositing_helper.cc +++ b/content/renderer/child_frame_compositing_helper.cc
@@ -49,14 +49,32 @@ int routing_id) : sender_(std::move(sender)), routing_id_(routing_id) {} + void AddPendingSequence(const cc::SurfaceSequence& sequence) { + ReleasePendingSequenceIfNecessary(); + pending_sequence_ = sequence; + } + private: - ~IframeSurfaceReferenceFactory() override = default; + ~IframeSurfaceReferenceFactory() override { + ReleasePendingSequenceIfNecessary(); + } + + void ReleasePendingSequenceIfNecessary() const { + if (pending_sequence_.is_valid()) { + sender_->Send( + new FrameHostMsg_SatisfySequence(routing_id_, pending_sequence_)); + pending_sequence_ = cc::SurfaceSequence(); + } + } // cc::SequenceSurfaceReferenceFactory implementation: void RequireSequence(const cc::SurfaceId& surface_id, const cc::SurfaceSequence& sequence) const override { sender_->Send( new FrameHostMsg_RequireSequence(routing_id_, surface_id, sequence)); + // If there is a temporary reference that was waiting on a new one to be + // created, it is now safe to release it. + ReleasePendingSequenceIfNecessary(); } void SatisfySequence(const cc::SurfaceSequence& sequence) const override { @@ -64,6 +82,7 @@ } const scoped_refptr<ThreadSafeSender> sender_; + mutable cc::SurfaceSequence pending_sequence_; const int routing_id_; DISALLOW_COPY_AND_ASSIGN(IframeSurfaceReferenceFactory); @@ -79,8 +98,23 @@ routing_id_(routing_id), browser_plugin_instance_id_(browser_plugin_instance_id) {} + void AddPendingSequence(const cc::SurfaceSequence& sequence) { + ReleasePendingSequenceIfNecessary(); + pending_sequence_ = sequence; + } + private: - ~BrowserPluginSurfaceReferenceFactory() override = default; + ~BrowserPluginSurfaceReferenceFactory() override { + ReleasePendingSequenceIfNecessary(); + } + + void ReleasePendingSequenceIfNecessary() const { + if (pending_sequence_.is_valid()) { + sender_->Send(new BrowserPluginHostMsg_SatisfySequence( + routing_id_, browser_plugin_instance_id_, pending_sequence_)); + pending_sequence_ = cc::SurfaceSequence(); + } + } // cc::SequenceSurfaceRefrenceFactory implementation: void SatisfySequence(const cc::SurfaceSequence& seq) const override { @@ -92,9 +126,13 @@ const cc::SurfaceSequence& sequence) const override { sender_->Send(new BrowserPluginHostMsg_RequireSequence( routing_id_, browser_plugin_instance_id_, surface_id, sequence)); + // If there is a temporary reference that was waiting on a new one to be + // created, it is now safe to release it. + ReleasePendingSequenceIfNecessary(); } const scoped_refptr<ThreadSafeSender> sender_; + mutable cc::SurfaceSequence pending_sequence_; const int routing_id_; const int browser_plugin_instance_id_; @@ -223,6 +261,19 @@ if (IsUseZoomForDSFEnabled()) scale_factor = 1.0f; + // The RWHV creates a destruction dependency on the surface that needs to be + // satisfied. The reference factory will satisfy it when a new reference has + // been created. + if (render_frame_proxy_) { + static_cast<IframeSurfaceReferenceFactory*>( + surface_reference_factory_.get()) + ->AddPendingSequence(sequence); + } else { + static_cast<BrowserPluginSurfaceReferenceFactory*>( + surface_reference_factory_.get()) + ->AddPendingSequence(sequence); + } + cc::SurfaceInfo modified_surface_info(surface_info.id(), scale_factor, surface_info.size_in_pixels()); surface_layer->SetPrimarySurfaceInfo(modified_surface_info); @@ -238,17 +289,6 @@ UpdateVisibility(true); - // The RWHV creates a destruction dependency on the surface that needs to be - // satisfied. Note: render_frame_proxy_ is null in the case our client is a - // BrowserPlugin; in this case the BrowserPlugin sends its own SatisfySequence - // message. - if (render_frame_proxy_) { - render_frame_proxy_->Send( - new FrameHostMsg_SatisfySequence(host_routing_id_, sequence)); - } else if (browser_plugin_.get()) { - browser_plugin_->SendSatisfySequence(sequence); - } - CheckSizeAndAdjustLayerProperties( surface_info.size_in_pixels(), surface_info.device_scale_factor(), static_cast<cc_blink::WebLayerImpl*>(web_layer_.get())->layer());
diff --git a/content/renderer/dom_automation_controller.cc b/content/renderer/dom_automation_controller.cc index ab675a8..7973ba4e 100644 --- a/content/renderer/dom_automation_controller.cc +++ b/content/renderer/dom_automation_controller.cc
@@ -12,8 +12,8 @@ #include "content/renderer/render_view_impl.h" #include "gin/handle.h" #include "gin/object_template_builder.h" -#include "third_party/WebKit/public/web/WebFrame.h" #include "third_party/WebKit/public/web/WebKit.h" +#include "third_party/WebKit/public/web/WebLocalFrame.h" namespace content { @@ -22,7 +22,7 @@ // static void DomAutomationController::Install(RenderFrame* render_frame, - blink::WebFrame* frame) { + blink::WebLocalFrame* frame) { v8::Isolate* isolate = blink::MainThreadIsolate(); v8::HandleScope handle_scope(isolate); v8::Local<v8::Context> context = frame->MainWorldScriptContext();
diff --git a/content/renderer/dom_automation_controller.h b/content/renderer/dom_automation_controller.h index d684f96..8742ec40 100644 --- a/content/renderer/dom_automation_controller.h +++ b/content/renderer/dom_automation_controller.h
@@ -74,7 +74,7 @@ */ namespace blink { -class WebFrame; +class WebLocalFrame; } namespace gin { @@ -90,7 +90,7 @@ public: static gin::WrapperInfo kWrapperInfo; - static void Install(RenderFrame* render_frame, blink::WebFrame* frame); + static void Install(RenderFrame* render_frame, blink::WebLocalFrame* frame); // Makes the renderer send a javascript value to the app. // The value to be sent can be either of type String,
diff --git a/content/renderer/gin_browsertest.cc b/content/renderer/gin_browsertest.cc index a8639a1..097dfe2 100644 --- a/content/renderer/gin_browsertest.cc +++ b/content/renderer/gin_browsertest.cc
@@ -11,8 +11,8 @@ #include "gin/per_isolate_data.h" #include "gin/wrappable.h" #include "testing/gtest/include/gtest/gtest.h" -#include "third_party/WebKit/public/web/WebFrame.h" #include "third_party/WebKit/public/web/WebKit.h" +#include "third_party/WebKit/public/web/WebLocalFrame.h" #include "third_party/WebKit/public/web/WebView.h" namespace content { @@ -65,8 +65,7 @@ { v8::Isolate* isolate = blink::MainThreadIsolate(); v8::HandleScope handle_scope(isolate); - v8::Context::Scope context_scope( - view_->GetWebView()->MainFrame()->MainWorldScriptContext()); + v8::Context::Scope context_scope(GetMainFrame()->MainWorldScriptContext()); // We create the object inside a scope so it's not kept alive by a handle // on the stack.
diff --git a/content/renderer/gpu/gpu_benchmarking_extension.cc b/content/renderer/gpu/gpu_benchmarking_extension.cc index e05aab51..e37cba66 100644 --- a/content/renderer/gpu/gpu_benchmarking_extension.cc +++ b/content/renderer/gpu/gpu_benchmarking_extension.cc
@@ -544,7 +544,7 @@ gin::WrapperInfo GpuBenchmarking::kWrapperInfo = {gin::kEmbedderNativeGin}; // static -void GpuBenchmarking::Install(blink::WebFrame* frame) { +void GpuBenchmarking::Install(blink::WebLocalFrame* frame) { v8::Isolate* isolate = blink::MainThreadIsolate(); v8::HandleScope handle_scope(isolate); v8::Local<v8::Context> context = frame->MainWorldScriptContext();
diff --git a/content/renderer/gpu/gpu_benchmarking_extension.h b/content/renderer/gpu/gpu_benchmarking_extension.h index 2b69d2b..fbb0022c 100644 --- a/content/renderer/gpu/gpu_benchmarking_extension.h +++ b/content/renderer/gpu/gpu_benchmarking_extension.h
@@ -9,7 +9,7 @@ #include "gin/wrappable.h" namespace blink { -class WebFrame; +class WebLocalFrame; } namespace gin { @@ -27,7 +27,7 @@ class GpuBenchmarking : public gin::Wrappable<GpuBenchmarking> { public: static gin::WrapperInfo kWrapperInfo; - static void Install(blink::WebFrame* frame); + static void Install(blink::WebLocalFrame* frame); private: GpuBenchmarking();
diff --git a/content/renderer/java/gin_java_bridge_object.cc b/content/renderer/java/gin_java_bridge_object.cc index 95f36382..d747e3c 100644 --- a/content/renderer/java/gin_java_bridge_object.cc +++ b/content/renderer/java/gin_java_bridge_object.cc
@@ -8,14 +8,14 @@ #include "content/public/renderer/render_thread.h" #include "content/renderer/java/gin_java_function_invocation_helper.h" #include "gin/function_template.h" -#include "third_party/WebKit/public/web/WebFrame.h" #include "third_party/WebKit/public/web/WebKit.h" +#include "third_party/WebKit/public/web/WebLocalFrame.h" namespace content { // static GinJavaBridgeObject* GinJavaBridgeObject::InjectNamed( - blink::WebFrame* frame, + blink::WebLocalFrame* frame, const base::WeakPtr<GinJavaBridgeDispatcher>& dispatcher, const std::string& object_name, GinJavaBridgeDispatcher::ObjectID object_id) {
diff --git a/content/renderer/java/gin_java_bridge_object.h b/content/renderer/java/gin_java_bridge_object.h index 25d1840..23c7efa 100644 --- a/content/renderer/java/gin_java_bridge_object.h +++ b/content/renderer/java/gin_java_bridge_object.h
@@ -17,7 +17,7 @@ #include "v8/include/v8-util.h" namespace blink { -class WebFrame; +class WebLocalFrame; } namespace content { @@ -40,7 +40,7 @@ v8::Isolate* isolate) override; static GinJavaBridgeObject* InjectNamed( - blink::WebFrame* frame, + blink::WebLocalFrame* frame, const base::WeakPtr<GinJavaBridgeDispatcher>& dispatcher, const std::string& object_name, GinJavaBridgeDispatcher::ObjectID object_id);
diff --git a/content/renderer/presentation/presentation_dispatcher.cc b/content/renderer/presentation/presentation_dispatcher.cc index bdd44dd..2fe4361 100644 --- a/content/renderer/presentation/presentation_dispatcher.cc +++ b/content/renderer/presentation/presentation_dispatcher.cc
@@ -302,7 +302,7 @@ auto screen_availability = GetScreenAvailability(urls); // Reject Promise if screen availability is unsupported for all URLs. - if (screen_availability == ScreenAvailability::UNSUPPORTED) { + if (screen_availability == blink::mojom::ScreenAvailability::DISABLED) { base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::Bind( @@ -321,12 +321,13 @@ availability_set_.insert(base::WrapUnique(listener)); } - if (screen_availability != ScreenAvailability::UNKNOWN) { + if (screen_availability != blink::mojom::ScreenAvailability::UNKNOWN) { base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::Bind(&blink::WebPresentationAvailabilityCallbacks::OnSuccess, base::Passed(&callback), - screen_availability == ScreenAvailability::AVAILABLE)); + screen_availability == + blink::mojom::ScreenAvailability::AVAILABLE)); } else { listener->availability_callbacks.Add(std::move(callback)); } @@ -423,8 +424,9 @@ blink::WebPresentationConnectionState::kTerminated); } -void PresentationDispatcher::OnScreenAvailabilityUpdated(const GURL& url, - bool available) { +void PresentationDispatcher::OnScreenAvailabilityUpdated( + const GURL& url, + blink::mojom::ScreenAvailability availability) { auto* listening_status = GetListeningStatus(url); if (!listening_status) return; @@ -432,12 +434,10 @@ if (listening_status->listening_state == ListeningState::WAITING) listening_status->listening_state = ListeningState::ACTIVE; - auto new_screen_availability = available ? ScreenAvailability::AVAILABLE - : ScreenAvailability::UNAVAILABLE; - if (listening_status->last_known_availability == new_screen_availability) + if (listening_status->last_known_availability == availability) return; - listening_status->last_known_availability = new_screen_availability; + listening_status->last_known_availability = availability; std::set<AvailabilityListener*> modified_listeners; for (auto& listener : availability_set_) { @@ -445,17 +445,16 @@ continue; auto screen_availability = GetScreenAvailability(listener->urls); - DCHECK(screen_availability == ScreenAvailability::AVAILABLE || - screen_availability == ScreenAvailability::UNAVAILABLE); - bool is_available = (screen_availability == ScreenAvailability::AVAILABLE); - + DCHECK(screen_availability != blink::mojom::ScreenAvailability::UNKNOWN && + screen_availability != blink::mojom::ScreenAvailability::DISABLED); for (auto* observer : listener->availability_observers) - observer->AvailabilityChanged(is_available); + observer->AvailabilityChanged(screen_availability); for (AvailabilityCallbacksMap::iterator iter( &listener->availability_callbacks); !iter.IsAtEnd(); iter.Advance()) { - iter.GetCurrentValue()->OnSuccess(is_available); + iter.GetCurrentValue()->OnSuccess( + screen_availability == blink::mojom::ScreenAvailability::AVAILABLE); } listener->availability_callbacks.Clear(); @@ -478,11 +477,12 @@ listening_status->listening_state = ListeningState::ACTIVE; if (listening_status->last_known_availability == - ScreenAvailability::UNSUPPORTED) { + blink::mojom::ScreenAvailability::DISABLED) { return; } - listening_status->last_known_availability = ScreenAvailability::UNSUPPORTED; + listening_status->last_known_availability = + blink::mojom::ScreenAvailability::DISABLED; const blink::WebString& not_supported_error = blink::WebString::FromUTF8( "getAvailability() isn't supported at the moment. It can be due to " @@ -496,10 +496,15 @@ // ScreenAvailabilityNotSupported should be a browser side setting, which // means all urls in PresentationAvailability should report NotSupported. - // It is not possible to change listening status from Available or - // Unavailable to NotSupported. No need to update observer. + // It is not possible to change listening status from AVAILABLE or + // UNAVAILABLE to DISABLED. auto screen_availability = GetScreenAvailability(listener->urls); - DCHECK_EQ(screen_availability, ScreenAvailability::UNSUPPORTED); + DCHECK_EQ(screen_availability, blink::mojom::ScreenAvailability::DISABLED); + + // RemotePlayback is using a listener but doesn't use callbacks. + // So update observers even though it's not necessary for Presentation API. + for (auto* observer : listener->availability_observers) + observer->AvailabilityChanged(screen_availability); for (AvailabilityCallbacksMap::iterator iter( &listener->availability_callbacks); @@ -730,23 +735,38 @@ } } -// Given a screen availability vector and integer value for each availability: -// UNKNOWN = 0, UNAVAILABLE = 1, UNSUPPORTED = 2, and AVAILABLE = 3, the max -// value of the vector is the overall availability. -PresentationDispatcher::ScreenAvailability -PresentationDispatcher::GetScreenAvailability( +blink::mojom::ScreenAvailability PresentationDispatcher::GetScreenAvailability( const std::vector<GURL>& urls) const { - int current_availability = 0; // UNKNOWN; + bool has_disabled = false; + bool has_source_not_supported = false; + bool has_unavailable = false; for (const auto& url : urls) { auto* status = GetListeningStatus(url); - auto screen_availability = - status ? status->last_known_availability : ScreenAvailability::UNKNOWN; - current_availability = - std::max(current_availability, static_cast<int>(screen_availability)); + auto screen_availability = status + ? status->last_known_availability + : blink::mojom::ScreenAvailability::UNKNOWN; + if (screen_availability == blink::mojom::ScreenAvailability::AVAILABLE) { + return blink::mojom::ScreenAvailability::AVAILABLE; + } else if (screen_availability == + blink::mojom::ScreenAvailability::DISABLED) { + has_disabled = true; + } else if (screen_availability == + blink::mojom::ScreenAvailability::SOURCE_NOT_SUPPORTED) { + has_source_not_supported = true; + } else if (screen_availability == + blink::mojom::ScreenAvailability::UNAVAILABLE) { + has_unavailable = true; + } } - return static_cast<ScreenAvailability>(current_availability); + if (has_disabled) + return blink::mojom::ScreenAvailability::DISABLED; + if (has_source_not_supported) + return blink::mojom::ScreenAvailability::SOURCE_NOT_SUPPORTED; + if (has_unavailable) + return blink::mojom::ScreenAvailability::UNAVAILABLE; + return blink::mojom::ScreenAvailability::UNKNOWN; } PresentationDispatcher::SendMessageRequest::SendMessageRequest( @@ -799,7 +819,7 @@ PresentationDispatcher::ListeningStatus::ListeningStatus( const GURL& availability_url) : url(availability_url), - last_known_availability(ScreenAvailability::UNKNOWN), + last_known_availability(blink::mojom::ScreenAvailability::UNKNOWN), listening_state(ListeningState::INACTIVE) {} PresentationDispatcher::ListeningStatus::~ListeningStatus() {}
diff --git a/content/renderer/presentation/presentation_dispatcher.h b/content/renderer/presentation/presentation_dispatcher.h index e717cb1..57721b0 100644 --- a/content/renderer/presentation/presentation_dispatcher.h +++ b/content/renderer/presentation/presentation_dispatcher.h
@@ -159,7 +159,9 @@ // blink::mojom::PresentationServiceClient void OnScreenAvailabilityNotSupported(const GURL& url) override; - void OnScreenAvailabilityUpdated(const GURL& url, bool available) override; + void OnScreenAvailabilityUpdated( + const GURL& url, + blink::mojom::ScreenAvailability availability) override; void OnConnectionStateChanged(const PresentationInfo& presentation_info, PresentationConnectionState state) override; void OnConnectionClosed(const PresentationInfo& presentation_info, @@ -219,15 +221,6 @@ ACTIVE, }; - // Do not change order or add new enum values. |GetScreenAvailability| impl - // depends on the order of the enum values. - enum class ScreenAvailability { - UNKNOWN = 0, - UNAVAILABLE, - UNSUPPORTED, - AVAILABLE - }; - using AvailabilityCallbacksMap = IDMap<std::unique_ptr<blink::WebPresentationAvailabilityCallbacks>>; using AvailabilityObserversSet = @@ -250,7 +243,7 @@ ~ListeningStatus(); const GURL url; - ScreenAvailability last_known_availability; + blink::mojom::ScreenAvailability last_known_availability; ListeningState listening_state; }; @@ -279,13 +272,15 @@ void TryRemoveAvailabilityListener(AvailabilityListener* listener); // Returns AVAILABLE if any url in |urls| has screen availability AVAILABLE; - // Returns UNSUPPORTED if any url in |urls| have screen availability - // UNSUPPORTED, and no url has screen availability AVAILABLE; - // Returns UNAVAILABLE if at least one url in |urls| has screen availability - // UNAVAILABLE, and no url has screen availability AVAILABLE or UNSUPPORTED; - // Returns UNKNOWN if all urls in |urls| have screen availability - // UNKNOWN. - ScreenAvailability GetScreenAvailability(const std::vector<GURL>& urls) const; + // otherwise returns DISABLED if at least one url in |urls| has screen + // availability DISABLED; + // otherwise, returns SOURCE_NOT_SUPPORTED if any url in |urls| has screen + // availability SOURCE_NOT_SUPPORTED; + // otherwise, returns UNAVAILABLE if any url in |urls| has screen + // availability UNAVAILABLE; + // otherwise returns UNKNOWN. + blink::mojom::ScreenAvailability GetScreenAvailability( + const std::vector<GURL>& urls) const; DISALLOW_COPY_AND_ASSIGN(PresentationDispatcher); };
diff --git a/content/renderer/presentation/presentation_dispatcher_unittest.cc b/content/renderer/presentation/presentation_dispatcher_unittest.cc index 0c4651f5..aadc61e 100644 --- a/content/renderer/presentation/presentation_dispatcher_unittest.cc +++ b/content/renderer/presentation/presentation_dispatcher_unittest.cc
@@ -35,6 +35,7 @@ using blink::mojom::PresentationConnection; using blink::mojom::PresentationService; using blink::mojom::PresentationServiceClientPtr; +using blink::mojom::ScreenAvailability; // TODO(crbug.com/576808): Add test cases for the following: // - State changes @@ -52,7 +53,7 @@ : urls_(urls) {} ~MockPresentationAvailabilityObserver() override {} - MOCK_METHOD1(AvailabilityChanged, void(bool is_available)); + MOCK_METHOD1(AvailabilityChanged, void(ScreenAvailability availability)); const WebVector<WebURL>& Urls() const override { return urls_; } private: @@ -211,8 +212,6 @@ public: using OnMessageCallback = PresentationConnectionProxy::OnMessageCallback; - enum class URLState { Available, Unavailable, Unsupported, Unknown }; - PresentationDispatcherTest() : gurl1_(GURL("https://www.example.com/1.html")), gurl2_(GURL("https://www.example.com/2.html")), @@ -244,18 +243,24 @@ return static_cast<uint8_t*>(array_buffer_.Data()); } - void ChangeURLState(const GURL& url, URLState state) { + void ChangeURLState(const GURL& url, ScreenAvailability state) { switch (state) { - case URLState::Available: - dispatcher_.OnScreenAvailabilityUpdated(url, true); + case ScreenAvailability::AVAILABLE: + dispatcher_.OnScreenAvailabilityUpdated(url, + ScreenAvailability::AVAILABLE); break; - case URLState::Unavailable: - dispatcher_.OnScreenAvailabilityUpdated(url, false); + case ScreenAvailability::SOURCE_NOT_SUPPORTED: + dispatcher_.OnScreenAvailabilityUpdated( + url, ScreenAvailability::SOURCE_NOT_SUPPORTED); break; - case URLState::Unsupported: + case ScreenAvailability::UNAVAILABLE: + dispatcher_.OnScreenAvailabilityUpdated( + url, ScreenAvailability::UNAVAILABLE); + break; + case ScreenAvailability::DISABLED: dispatcher_.OnScreenAvailabilityNotSupported(url); break; - case URLState::Unknown: + case ScreenAvailability::UNKNOWN: break; } } @@ -265,7 +270,7 @@ // |mock_callback|. void TestGetAvailability( const std::vector<GURL>& urls, - const std::vector<URLState>& states, + const std::vector<ScreenAvailability>& states, MockPresentationAvailabilityCallbacks* mock_callback) { DCHECK_EQ(urls.size(), states.size()); @@ -534,7 +539,7 @@ dispatcher_.GetAvailability( urls_, base::MakeUnique<WebPresentationAvailabilityCallbacks>()); - dispatcher_.OnScreenAvailabilityUpdated(url1_, true); + dispatcher_.OnScreenAvailabilityUpdated(url1_, ScreenAvailability::AVAILABLE); run_loop1.RunUntilIdle(); base::RunLoop run_loop2; @@ -545,10 +550,15 @@ run_loop2.RunUntilIdle(); base::RunLoop run_loop3; - EXPECT_CALL(observer_, AvailabilityChanged(false)); - dispatcher_.OnScreenAvailabilityUpdated(url1_, false); - EXPECT_CALL(observer_, AvailabilityChanged(true)); - dispatcher_.OnScreenAvailabilityUpdated(url1_, true); + EXPECT_CALL(observer_, AvailabilityChanged(ScreenAvailability::UNAVAILABLE)); + dispatcher_.OnScreenAvailabilityUpdated(url1_, + ScreenAvailability::UNAVAILABLE); + EXPECT_CALL(observer_, + AvailabilityChanged(ScreenAvailability::SOURCE_NOT_SUPPORTED)); + dispatcher_.OnScreenAvailabilityUpdated( + url1_, ScreenAvailability::SOURCE_NOT_SUPPORTED); + EXPECT_CALL(observer_, AvailabilityChanged(ScreenAvailability::AVAILABLE)); + dispatcher_.OnScreenAvailabilityUpdated(url1_, ScreenAvailability::AVAILABLE); for (const auto& gurl : gurls_) { EXPECT_CALL(presentation_service_, StopListeningForScreenAvailability(gurl)); @@ -558,8 +568,10 @@ // After stopListening(), |observer_| should no longer be notified. base::RunLoop run_loop4; - EXPECT_CALL(observer_, AvailabilityChanged(false)).Times(0); - dispatcher_.OnScreenAvailabilityUpdated(url1_, false); + EXPECT_CALL(observer_, AvailabilityChanged(ScreenAvailability::UNAVAILABLE)) + .Times(0); + dispatcher_.OnScreenAvailabilityUpdated(url1_, + ScreenAvailability::UNAVAILABLE); run_loop4.RunUntilIdle(); } @@ -587,21 +599,30 @@ auto* mock_callback = new MockPresentationAvailabilityCallbacks(); EXPECT_CALL(*mock_callback, OnSuccess(true)); - TestGetAvailability({url1_}, {URLState::Available}, mock_callback); + TestGetAvailability({url1_}, {ScreenAvailability::AVAILABLE}, mock_callback); +} + +TEST_F(PresentationDispatcherTest, GetAvailabilityOneUrlBecomesNotCompatible) { + auto* mock_callback = new MockPresentationAvailabilityCallbacks(); + EXPECT_CALL(*mock_callback, OnSuccess(false)); + + TestGetAvailability({url1_}, {ScreenAvailability::SOURCE_NOT_SUPPORTED}, + mock_callback); } TEST_F(PresentationDispatcherTest, GetAvailabilityOneUrlBecomesUnavailable) { auto* mock_callback = new MockPresentationAvailabilityCallbacks(); EXPECT_CALL(*mock_callback, OnSuccess(false)); - TestGetAvailability({url1_}, {URLState::Unavailable}, mock_callback); + TestGetAvailability({url1_}, {ScreenAvailability::UNAVAILABLE}, + mock_callback); } -TEST_F(PresentationDispatcherTest, GetAvailabilityOneUrlBecomesNotSupported) { +TEST_F(PresentationDispatcherTest, GetAvailabilityOneUrlBecomesUnsupported) { auto* mock_callback = new MockPresentationAvailabilityCallbacks(); EXPECT_CALL(*mock_callback, OnError(_)); - TestGetAvailability({url1_}, {URLState::Unsupported}, mock_callback); + TestGetAvailability({url1_}, {ScreenAvailability::DISABLED}, mock_callback); } TEST_F(PresentationDispatcherTest, @@ -609,9 +630,10 @@ auto* mock_callback = new MockPresentationAvailabilityCallbacks(); EXPECT_CALL(*mock_callback, OnSuccess(true)).Times(1); - TestGetAvailability({url1_, url2_}, - {URLState::Available, URLState::Available}, - mock_callback); + TestGetAvailability( + {url1_, url2_}, + {ScreenAvailability::AVAILABLE, ScreenAvailability::AVAILABLE}, + mock_callback); } TEST_F(PresentationDispatcherTest, @@ -619,8 +641,20 @@ auto* mock_callback = new MockPresentationAvailabilityCallbacks(); EXPECT_CALL(*mock_callback, OnSuccess(false)).Times(1); + TestGetAvailability( + {url1_, url2_}, + {ScreenAvailability::UNAVAILABLE, ScreenAvailability::UNAVAILABLE}, + mock_callback); +} + +TEST_F(PresentationDispatcherTest, + GetAvailabilityMultipleUrlsAllBecomesNotCompatible) { + auto* mock_callback = new MockPresentationAvailabilityCallbacks(); + EXPECT_CALL(*mock_callback, OnSuccess(false)).Times(1); + TestGetAvailability({url1_, url2_}, - {URLState::Unavailable, URLState::Unavailable}, + {ScreenAvailability::SOURCE_NOT_SUPPORTED, + ScreenAvailability::SOURCE_NOT_SUPPORTED}, mock_callback); } @@ -629,9 +663,10 @@ auto* mock_callback = new MockPresentationAvailabilityCallbacks(); EXPECT_CALL(*mock_callback, OnError(_)).Times(1); - TestGetAvailability({url1_, url2_}, - {URLState::Unsupported, URLState::Unsupported}, - mock_callback); + TestGetAvailability( + {url1_, url2_}, + {ScreenAvailability::DISABLED, ScreenAvailability::DISABLED}, + mock_callback); } TEST_F(PresentationDispatcherTest, @@ -640,8 +675,9 @@ auto* mock_callback_1 = new MockPresentationAvailabilityCallbacks(); EXPECT_CALL(*mock_callback_1, OnSuccess(false)).Times(1); - std::vector<URLState> state_seq = {URLState::Unavailable, URLState::Available, - URLState::Unavailable}; + std::vector<ScreenAvailability> state_seq = {ScreenAvailability::UNAVAILABLE, + ScreenAvailability::AVAILABLE, + ScreenAvailability::UNAVAILABLE}; TestGetAvailability({url1_, url2_, url3_}, state_seq, mock_callback_1); // Second getAvailability() call. @@ -682,9 +718,12 @@ .Times(1); } - EXPECT_CALL(mock_observer1_, AvailabilityChanged(false)); - EXPECT_CALL(mock_observer2_, AvailabilityChanged(false)); - EXPECT_CALL(mock_observer3_, AvailabilityChanged(false)); + EXPECT_CALL(mock_observer1_, + AvailabilityChanged(ScreenAvailability::UNAVAILABLE)); + EXPECT_CALL(mock_observer2_, + AvailabilityChanged(ScreenAvailability::UNAVAILABLE)); + EXPECT_CALL(mock_observer3_, + AvailabilityChanged(ScreenAvailability::UNAVAILABLE)); // Set up |availability_set_| and |listening_status_| base::RunLoop run_loop; @@ -697,7 +736,7 @@ } // Clean up callbacks. - ChangeURLState(gurl2_, URLState::Unavailable); + ChangeURLState(gurl2_, ScreenAvailability::UNAVAILABLE); for (auto* mock_observer : mock_observers_) client()->StopListening(mock_observer); @@ -729,12 +768,15 @@ for (auto* mock_observer : mock_observers_) client()->StartListening(mock_observer); - EXPECT_CALL(mock_observer1_, AvailabilityChanged(false)); - EXPECT_CALL(mock_observer2_, AvailabilityChanged(false)); - EXPECT_CALL(mock_observer3_, AvailabilityChanged(false)); + EXPECT_CALL(mock_observer1_, + AvailabilityChanged(ScreenAvailability::UNAVAILABLE)); + EXPECT_CALL(mock_observer2_, + AvailabilityChanged(ScreenAvailability::UNAVAILABLE)); + EXPECT_CALL(mock_observer3_, + AvailabilityChanged(ScreenAvailability::UNAVAILABLE)); // Clean up callbacks. - ChangeURLState(gurl2_, URLState::Unavailable); + ChangeURLState(gurl2_, ScreenAvailability::UNAVAILABLE); client()->StopListening(&mock_observer1_); run_loop.RunUntilIdle(); } @@ -745,7 +787,8 @@ EXPECT_CALL(presentation_service_, ListenForScreenAvailability(gurl)) .Times(1); } - EXPECT_CALL(mock_observer1_, AvailabilityChanged(true)); + EXPECT_CALL(mock_observer1_, + AvailabilityChanged(ScreenAvailability::AVAILABLE)); base::RunLoop run_loop; for (auto* mock_observer : mock_observers_) { @@ -755,14 +798,22 @@ client()->StartListening(mock_observer); } - ChangeURLState(gurl1_, URLState::Available); + ChangeURLState(gurl1_, ScreenAvailability::AVAILABLE); run_loop.RunUntilIdle(); - EXPECT_CALL(mock_observer1_, AvailabilityChanged(false)); + EXPECT_CALL(mock_observer1_, + AvailabilityChanged(ScreenAvailability::UNAVAILABLE)); base::RunLoop run_loop_2; - ChangeURLState(gurl1_, URLState::Unavailable); + ChangeURLState(gurl1_, ScreenAvailability::UNAVAILABLE); run_loop_2.RunUntilIdle(); + + EXPECT_CALL(mock_observer1_, + AvailabilityChanged(ScreenAvailability::SOURCE_NOT_SUPPORTED)); + + base::RunLoop run_loop_3; + ChangeURLState(gurl1_, ScreenAvailability::SOURCE_NOT_SUPPORTED); + run_loop_3.RunUntilIdle(); } TEST_F(PresentationDispatcherTest, @@ -771,8 +822,10 @@ EXPECT_CALL(presentation_service_, ListenForScreenAvailability(gurl)) .Times(1); } - for (auto* mock_observer : mock_observers_) - EXPECT_CALL(*mock_observer, AvailabilityChanged(true)); + for (auto* mock_observer : mock_observers_) { + EXPECT_CALL(*mock_observer, + AvailabilityChanged(ScreenAvailability::AVAILABLE)); + } base::RunLoop run_loop; for (auto* mock_observer : mock_observers_) { @@ -782,15 +835,26 @@ client()->StartListening(mock_observer); } - ChangeURLState(gurl2_, URLState::Available); + ChangeURLState(gurl2_, ScreenAvailability::AVAILABLE); run_loop.RunUntilIdle(); - for (auto* mock_observer : mock_observers_) - EXPECT_CALL(*mock_observer, AvailabilityChanged(false)); + for (auto* mock_observer : mock_observers_) { + EXPECT_CALL(*mock_observer, + AvailabilityChanged(ScreenAvailability::UNAVAILABLE)); + } base::RunLoop run_loop_2; - ChangeURLState(gurl2_, URLState::Unavailable); + ChangeURLState(gurl2_, ScreenAvailability::UNAVAILABLE); run_loop_2.RunUntilIdle(); + + for (auto* mock_observer : mock_observers_) { + EXPECT_CALL(*mock_observer, + AvailabilityChanged(ScreenAvailability::SOURCE_NOT_SUPPORTED)); + } + + base::RunLoop run_loop_3; + ChangeURLState(gurl2_, ScreenAvailability::SOURCE_NOT_SUPPORTED); + run_loop_3.RunUntilIdle(); } } // namespace content
diff --git a/content/renderer/renderer_v2.sb b/content/renderer/renderer_v2.sb new file mode 100644 index 0000000..cb871b0 --- /dev/null +++ b/content/renderer/renderer_v2.sb
@@ -0,0 +1,144 @@ +; 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. +(version 1) + +; The top of this will be the V2 common profile. + +; Helper function to check if a param is set to true. +(define (param-true? str) (string=? (param str) "TRUE")) + +; Helper function to determine if a parameter is defined or not. +(define (param-defined? str) (string? (param str))) + +; Define constants for all of the parameter strings passed in. +(define disable-sandbox-denial-logging "DISABLE_SANDBOX_DENIAL_LOGGING") +(define enable-logging "ENABLE_LOGGING") +(define homedir-as-literal "USER_HOMEDIR_AS_LITERAL") +(define elcap-or-later "ELCAP_OR_LATER") +(define bundle-path "BUNDLE_PATH") +(define executable-path "EXECUTABLE_PATH") +(define chromium-pid "CHROMIUM_PID") +(define log-file-path "LOG_FILE_PATH") +(define bundle-id "BUNDLE_ID") +(define component-path "COMPONENT_PATH") + +; Backwards compatibility for 10.9 +(define (path x) (literal x)) + +; --enable-sandbox-logging causes the sandbox to log failures to the syslog. +(if (param-true? disable-sandbox-denial-logging) + (deny default (with no-log)) + (deny default)) + +(if (param-true? enable-logging) (debug deny)) + +; Allow sending signals to self - https://crbug.com/20370 +(allow signal (target self)) + +; Consumes a subpath and appends it to the user's homedir path. +(define (user-homedir-path subpath) + (string-append (param homedir-as-literal) subpath)) + +; Allow logging for all processes. +(allow file-write* (path (param log-file-path))) + +; Allow component builds to work. +(if (param-defined? component-path) + (allow file-read* (subpath (param component-path)))) + +(allow process-exec* (path (param executable-path))) +(allow file-read* (path (param executable-path))) + +(allow mach-lookup (global-name (string-append (param bundle-id) + ".rohitfork." + (param chromium-pid)))) +; Allow realpath() to work. +(allow file-read-metadata (subpath "/")) + +; Allow cf prefs to work. +(allow user-preference-read) + +; All processes can read the bundle contents. +(allow file-read* (subpath (param bundle-path))) + +; End of common.sb? +(allow file-ioctl file-read-data file-write-data (path "/dev/dtracehelper")) + +; File reads. +; Reads from the home directory. +(allow file-read-data (path (user-homedir-path "/.CFUserTextEncoding"))) + +; Reads of /dev devices. +(allow file-read-data + (path "/dev/autofs_nowait") + (path "/dev/fd") + (path "/dev/null") + (path "/dev/urandom")) + +(allow file-write-data (path "/dev/null")) + +; Reads from /usr. +(allow file-read-data + (path "/usr/lib/libexpat.1.dylib") + (subpath "/usr/share/locale") + (subpath "/usr/share/zoneinfo")) + +(allow file-read* (path "/usr/share/icu/icudt57l.dat")) + +; Reads from /Library. +(allow file-read-data (subpath "/Library/Fonts")) + +; Reads from /System. +(allow file-read-data + (path "/System/Library/CoreServices/CoreTypes.bundle/Contents/Library/AppExceptions.bundle/Exceptions.plist") + (path "/System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/Exceptions.plist") + (path "/System/Library/CoreServices/SystemVersion.plist") + (path "/System/Library/Preferences/Logging/Subsystems/com.apple.SkyLight.plist") + (subpath "/System/Library/ColorSync/Profiles") + (subpath "/System/Library/CoreServices/SystemAppearance.bundle") + (subpath "/System/Library/CoreServices/SystemVersion.bundle") + (subpath "/System/Library/Fonts") + (subpath "/System/Library/Frameworks")) + +; IOKit +(allow iokit-open + (iokit-registry-entry-class "IOSurfaceRootUserClient") + (iokit-registry-entry-class "RootDomainUserClient")) + +; POSIX IPC +(allow ipc-posix-shm-read-data + (ipc-posix-name "apple.cfprefs.317580v1") + (ipc-posix-name "apple.cfprefs.daemonv1") + (ipc-posix-name "apple.shm.notification_center")) + +; mach IPC +(allow mach-lookup + (global-name "com.apple.distributed_notifications@Uv3") + (global-name "com.apple.fonts") + (global-name "com.apple.logd") + (global-name "com.apple.system.logger") + (global-name "com.apple.system.notification_center") + (global-name "com.apple.system.opendirectoryd.libinfo") + (global-name "com.apple.windowserver.active")) + +; sysctl +(allow sysctl-read + (sysctl-name "hw.activecpu") + (sysctl-name "hw.busfrequency_compat") + (sysctl-name "hw.byteorder") + (sysctl-name "hw.cachelinesize_compat") + (sysctl-name "hw.cpufrequency_compat") + (sysctl-name "hw.cputype") + (sysctl-name "hw.machine") + (sysctl-name "hw.ncpu") + (sysctl-name "hw.pagesize_compat") + (sysctl-name "hw.physicalcpu_max") + (sysctl-name "hw.tbfrequency_compat") + (sysctl-name "hw.vectorunit") + (sysctl-name "kern.hostname") + (sysctl-name "kern.maxfilesperproc") + (sysctl-name "kern.osrelease") + (sysctl-name "kern.ostype") + (sysctl-name "kern.osversion") + (sysctl-name "kern.version"))
diff --git a/content/renderer/skia_benchmarking_extension.cc b/content/renderer/skia_benchmarking_extension.cc index dfbf9afe..b034452 100644 --- a/content/renderer/skia_benchmarking_extension.cc +++ b/content/renderer/skia_benchmarking_extension.cc
@@ -21,8 +21,8 @@ #include "skia/ext/benchmarking_canvas.h" #include "third_party/WebKit/public/web/WebArrayBuffer.h" #include "third_party/WebKit/public/web/WebArrayBufferConverter.h" -#include "third_party/WebKit/public/web/WebFrame.h" #include "third_party/WebKit/public/web/WebKit.h" +#include "third_party/WebKit/public/web/WebLocalFrame.h" #include "third_party/skia/include/core/SkCanvas.h" #include "third_party/skia/include/core/SkColorPriv.h" #include "third_party/skia/include/core/SkGraphics.h" @@ -144,7 +144,7 @@ gin::WrapperInfo SkiaBenchmarking::kWrapperInfo = {gin::kEmbedderNativeGin}; // static -void SkiaBenchmarking::Install(blink::WebFrame* frame) { +void SkiaBenchmarking::Install(blink::WebLocalFrame* frame) { v8::Isolate* isolate = blink::MainThreadIsolate(); v8::HandleScope handle_scope(isolate); v8::Local<v8::Context> context = frame->MainWorldScriptContext();
diff --git a/content/renderer/skia_benchmarking_extension.h b/content/renderer/skia_benchmarking_extension.h index 8dd05dd5..43bfbfbb 100644 --- a/content/renderer/skia_benchmarking_extension.h +++ b/content/renderer/skia_benchmarking_extension.h
@@ -9,7 +9,7 @@ #include "gin/wrappable.h" namespace blink { -class WebFrame; +class WebLocalFrame; } namespace gin { @@ -21,7 +21,7 @@ class SkiaBenchmarking : public gin::Wrappable<SkiaBenchmarking> { public: static gin::WrapperInfo kWrapperInfo; - static void Install(blink::WebFrame* frame); + static void Install(blink::WebLocalFrame* frame); // Wrapper around SkGraphics::Init that can be invoked multiple times. static void Initialize();
diff --git a/content/renderer/stats_collection_controller.cc b/content/renderer/stats_collection_controller.cc index 618c6fc..16eb0f83 100644 --- a/content/renderer/stats_collection_controller.cc +++ b/content/renderer/stats_collection_controller.cc
@@ -78,7 +78,7 @@ }; // static -void StatsCollectionController::Install(blink::WebFrame* frame) { +void StatsCollectionController::Install(blink::WebLocalFrame* frame) { v8::Isolate* isolate = blink::MainThreadIsolate(); v8::HandleScope handle_scope(isolate); v8::Local<v8::Context> context = frame->MainWorldScriptContext();
diff --git a/content/renderer/stats_collection_controller.h b/content/renderer/stats_collection_controller.h index df297c1..848e102a7 100644 --- a/content/renderer/stats_collection_controller.h +++ b/content/renderer/stats_collection_controller.h
@@ -9,7 +9,7 @@ #include "gin/wrappable.h" namespace blink { -class WebFrame; +class WebLocalFrame; } namespace content { @@ -23,7 +23,7 @@ public: static gin::WrapperInfo kWrapperInfo; - static void Install(blink::WebFrame* frame); + static void Install(blink::WebLocalFrame* frame); private: StatsCollectionController();
diff --git a/content/renderer/web_ui_extension.cc b/content/renderer/web_ui_extension.cc index 2a98fa0..19593e17 100644 --- a/content/renderer/web_ui_extension.cc +++ b/content/renderer/web_ui_extension.cc
@@ -32,10 +32,9 @@ namespace { -bool ShouldRespondToRequest( - blink::WebFrame** frame_ptr, - RenderView** render_view_ptr) { - blink::WebFrame* frame = blink::WebLocalFrame::FrameForCurrentContext(); +bool ShouldRespondToRequest(blink::WebLocalFrame** frame_ptr, + RenderView** render_view_ptr) { + blink::WebLocalFrame* frame = blink::WebLocalFrame::FrameForCurrentContext(); if (!frame || !frame->View()) return false; @@ -70,7 +69,7 @@ // should be an array. // - chrome.getVariableValue: Returns value for the input variable name if such // a value was set by the browser. Else will return an empty string. -void WebUIExtension::Install(blink::WebFrame* frame) { +void WebUIExtension::Install(blink::WebLocalFrame* frame) { v8::Isolate* isolate = blink::MainThreadIsolate(); v8::HandleScope handle_scope(isolate); v8::Local<v8::Context> context = frame->MainWorldScriptContext(); @@ -92,7 +91,7 @@ // static void WebUIExtension::Send(gin::Arguments* args) { - blink::WebFrame* frame; + blink::WebLocalFrame* frame; RenderView* render_view; if (!ShouldRespondToRequest(&frame, &render_view)) return; @@ -136,7 +135,7 @@ // static std::string WebUIExtension::GetVariableValue(const std::string& name) { - blink::WebFrame* frame; + blink::WebLocalFrame* frame; RenderView* render_view; if (!ShouldRespondToRequest(&frame, &render_view)) return std::string();
diff --git a/content/renderer/web_ui_extension.h b/content/renderer/web_ui_extension.h index 8e4bfbb..9ada0aa 100644 --- a/content/renderer/web_ui_extension.h +++ b/content/renderer/web_ui_extension.h
@@ -10,7 +10,7 @@ #include "base/macros.h" namespace blink { -class WebFrame; +class WebLocalFrame; } namespace gin { @@ -21,7 +21,7 @@ class WebUIExtension { public: - static void Install(blink::WebFrame* frame); + static void Install(blink::WebLocalFrame* frame); private: static void Send(gin::Arguments* args);
diff --git a/content/shell/test_runner/accessibility_controller.cc b/content/shell/test_runner/accessibility_controller.cc index e2e26c8..233f8f0 100644 --- a/content/shell/test_runner/accessibility_controller.cc +++ b/content/shell/test_runner/accessibility_controller.cc
@@ -165,8 +165,9 @@ blink::WebFrame* frame = web_view()->MainFrame(); if (!frame || frame->IsWebRemoteFrame()) return; + blink::WebLocalFrame* local_frame = frame->ToWebLocalFrame(); - v8::Local<v8::Context> context = frame->MainWorldScriptContext(); + v8::Local<v8::Context> context = local_frame->MainWorldScriptContext(); if (context.IsEmpty()) return; @@ -180,7 +181,7 @@ WebAXObjectProxy* element; bool result = gin::ConvertFromV8(isolate, element_handle, &element); DCHECK(result); - element->NotificationReceived(frame, notification_name); + element->NotificationReceived(local_frame, notification_name); if (notification_callback_.IsEmpty()) return; @@ -191,7 +192,7 @@ v8::String::kNormalString, notification_name.size()), }; - frame->CallFunctionEvenIfScriptDisabled( + local_frame->CallFunctionEvenIfScriptDisabled( v8::Local<v8::Function>::New(isolate, notification_callback_), context->Global(), arraysize(argv), argv); }
diff --git a/content/shell/test_runner/gamepad_controller.cc b/content/shell/test_runner/gamepad_controller.cc index f58bfa4..b92eae0 100644 --- a/content/shell/test_runner/gamepad_controller.cc +++ b/content/shell/test_runner/gamepad_controller.cc
@@ -13,11 +13,10 @@ #include "gin/object_template_builder.h" #include "gin/wrappable.h" #include "third_party/WebKit/public/platform/WebGamepadListener.h" -#include "third_party/WebKit/public/web/WebFrame.h" #include "third_party/WebKit/public/web/WebKit.h" +#include "third_party/WebKit/public/web/WebLocalFrame.h" #include "v8/include/v8.h" -using blink::WebFrame; using device::Gamepad; using device::Gamepads; @@ -29,7 +28,7 @@ static gin::WrapperInfo kWrapperInfo; static void Install(base::WeakPtr<GamepadController> controller, - blink::WebFrame* frame); + blink::WebLocalFrame* frame); private: explicit GamepadControllerBindings( @@ -60,7 +59,7 @@ // static void GamepadControllerBindings::Install( base::WeakPtr<GamepadController> controller, - WebFrame* frame) { + blink::WebLocalFrame* frame) { v8::Isolate* isolate = blink::MainThreadIsolate(); v8::HandleScope handle_scope(isolate); v8::Local<v8::Context> context = frame->MainWorldScriptContext(); @@ -161,7 +160,7 @@ memset(&gamepads_, 0, sizeof(gamepads_)); } -void GamepadController::Install(WebFrame* frame) { +void GamepadController::Install(blink::WebLocalFrame* frame) { GamepadControllerBindings::Install(weak_factory_.GetWeakPtr(), frame); }
diff --git a/content/shell/test_runner/gamepad_controller.h b/content/shell/test_runner/gamepad_controller.h index 787eec5..c91d301 100644 --- a/content/shell/test_runner/gamepad_controller.h +++ b/content/shell/test_runner/gamepad_controller.h
@@ -13,8 +13,8 @@ #include "device/gamepad/public/cpp/gamepads.h" namespace blink { -class WebFrame; class WebGamepadListener; +class WebLocalFrame; } namespace test_runner { @@ -28,7 +28,7 @@ ~GamepadController(); void Reset(); - void Install(blink::WebFrame* frame); + void Install(blink::WebLocalFrame* frame); void SampleGamepads(device::Gamepads& gamepads); void SetListener(blink::WebGamepadListener* listener);
diff --git a/content/shell/test_runner/gc_controller.cc b/content/shell/test_runner/gc_controller.cc index a84ff83..93f9be6 100644 --- a/content/shell/test_runner/gc_controller.cc +++ b/content/shell/test_runner/gc_controller.cc
@@ -7,8 +7,8 @@ #include "gin/arguments.h" #include "gin/handle.h" #include "gin/object_template_builder.h" -#include "third_party/WebKit/public/web/WebFrame.h" #include "third_party/WebKit/public/web/WebKit.h" +#include "third_party/WebKit/public/web/WebLocalFrame.h" #include "v8/include/v8.h" namespace test_runner { @@ -16,7 +16,7 @@ gin::WrapperInfo GCController::kWrapperInfo = {gin::kEmbedderNativeGin}; // static -void GCController::Install(blink::WebFrame* frame) { +void GCController::Install(blink::WebLocalFrame* frame) { v8::Isolate* isolate = blink::MainThreadIsolate(); v8::HandleScope handle_scope(isolate); v8::Local<v8::Context> context = frame->MainWorldScriptContext();
diff --git a/content/shell/test_runner/gc_controller.h b/content/shell/test_runner/gc_controller.h index 49e4b06..9c34adcf 100644 --- a/content/shell/test_runner/gc_controller.h +++ b/content/shell/test_runner/gc_controller.h
@@ -9,7 +9,7 @@ #include "gin/wrappable.h" namespace blink { -class WebFrame; +class WebLocalFrame; } namespace gin { @@ -21,7 +21,7 @@ class GCController : public gin::Wrappable<GCController> { public: static gin::WrapperInfo kWrapperInfo; - static void Install(blink::WebFrame* frame); + static void Install(blink::WebLocalFrame* frame); private: GCController();
diff --git a/content/shell/test_runner/spell_check_client.cc b/content/shell/test_runner/spell_check_client.cc index 19ed128..22ef57d 100644 --- a/content/shell/test_runner/spell_check_client.cc +++ b/content/shell/test_runner/spell_check_client.cc
@@ -13,8 +13,8 @@ #include "content/shell/test_runner/mock_grammar_check.h" #include "content/shell/test_runner/test_runner.h" #include "content/shell/test_runner/web_test_delegate.h" -#include "third_party/WebKit/public/web/WebFrame.h" #include "third_party/WebKit/public/web/WebKit.h" +#include "third_party/WebKit/public/web/WebLocalFrame.h" #include "third_party/WebKit/public/web/WebTextCheckingCompletion.h" #include "third_party/WebKit/public/web/WebTextCheckingResult.h" @@ -148,14 +148,15 @@ blink::WebFrame* frame = test_runner_->mainFrame(); if (!frame || frame->IsWebRemoteFrame()) return; + blink::WebLocalFrame* local_frame = frame->ToWebLocalFrame(); - v8::Local<v8::Context> context = frame->MainWorldScriptContext(); + v8::Local<v8::Context> context = local_frame->MainWorldScriptContext(); if (context.IsEmpty()) return; v8::Context::Scope context_scope(context); - frame->CallFunctionEvenIfScriptDisabled( + local_frame->CallFunctionEvenIfScriptDisabled( v8::Local<v8::Function>::New(isolate, resolved_callback_), context->Global(), 0, nullptr); }
diff --git a/content/shell/test_runner/test_interfaces.cc b/content/shell/test_runner/test_interfaces.cc index dc6e245..0131fdb 100644 --- a/content/shell/test_runner/test_interfaces.cc +++ b/content/shell/test_runner/test_interfaces.cc
@@ -59,7 +59,7 @@ delegate_ = delegate; } -void TestInterfaces::BindTo(blink::WebFrame* frame) { +void TestInterfaces::BindTo(blink::WebLocalFrame* frame) { if (gamepad_controller_) gamepad_controller_->Install(frame); GCController::Install(frame);
diff --git a/content/shell/test_runner/test_interfaces.h b/content/shell/test_runner/test_interfaces.h index 18bf973..97789e2 100644 --- a/content/shell/test_runner/test_interfaces.h +++ b/content/shell/test_runner/test_interfaces.h
@@ -14,7 +14,7 @@ #include "third_party/WebKit/public/platform/WebNonCopyable.h" namespace blink { -class WebFrame; +class WebLocalFrame; class WebThemeEngine; class WebURL; class WebView; @@ -34,7 +34,7 @@ void SetMainView(blink::WebView* web_view); void SetDelegate(WebTestDelegate* delegate); - void BindTo(blink::WebFrame* frame); + void BindTo(blink::WebLocalFrame* frame); void ResetTestHelperControllers(); void ResetAll(); bool TestIsRunning();
diff --git a/content/shell/test_runner/test_runner_for_specific_view.cc b/content/shell/test_runner/test_runner_for_specific_view.cc index e90cbab..461646c1 100644 --- a/content/shell/test_runner/test_runner_for_specific_view.cc +++ b/content/shell/test_runner/test_runner_for_specific_view.cc
@@ -185,7 +185,7 @@ v8::Isolate* isolate = blink::MainThreadIsolate(); v8::HandleScope handle_scope(isolate); - WebFrame* frame = web_view()->MainFrame(); + blink::WebLocalFrame* frame = GetLocalMainFrame(); v8::Local<v8::Context> context = frame->MainWorldScriptContext(); if (context.IsEmpty()) return; @@ -249,7 +249,7 @@ v8::HandleScope handle_scope(isolate); v8::Local<v8::Context> context = - web_view()->MainFrame()->MainWorldScriptContext(); + GetLocalMainFrame()->MainWorldScriptContext(); if (context.IsEmpty()) return; @@ -331,7 +331,7 @@ v8::Isolate* isolate = blink::MainThreadIsolate(); v8::HandleScope handle_scope(isolate); v8::Local<v8::Context> context = - web_view()->MainFrame()->MainWorldScriptContext(); + GetLocalMainFrame()->MainWorldScriptContext(); if (context.IsEmpty()) return; v8::Context::Scope context_scope(context); @@ -408,7 +408,7 @@ v8::HandleScope handle_scope(isolate); v8::Local<v8::Context> context = - web_view()->MainFrame()->MainWorldScriptContext(); + GetLocalMainFrame()->MainWorldScriptContext(); if (context.IsEmpty()) return; @@ -572,13 +572,7 @@ } bool TestRunnerForSpecificView::CallShouldCloseOnWebView() { - if (!web_view()->MainFrame()->ToWebLocalFrame()) { - CHECK(false) << "This function cannot be called if the main frame is not a " - "local frame."; - } - - return web_view()->MainFrame()->ToWebLocalFrame()->DispatchBeforeUnloadEvent( - false); + return GetLocalMainFrame()->DispatchBeforeUnloadEvent(false); } void TestRunnerForSpecificView::SetDomainRelaxationForbiddenForURLScheme( @@ -662,7 +656,7 @@ wrap_around = true; } - WebLocalFrame* frame = web_view()->MainFrame()->ToWebLocalFrame(); + WebLocalFrame* frame = GetLocalMainFrame(); const bool find_result = frame->Find(0, WebString::FromUTF8(search_text), find_options, wrap_around, 0); frame->StopFinding(WebLocalFrame::kStopFindActionKeepSelection); @@ -670,25 +664,25 @@ } std::string TestRunnerForSpecificView::SelectionAsMarkup() { - if (!web_view()->MainFrame()->ToWebLocalFrame()) { - CHECK(false) << "This function cannot be called if the main frame is not a " - "local frame."; - } - return web_view()->MainFrame()->ToWebLocalFrame()->SelectionAsMarkup().Utf8(); + return GetLocalMainFrame()->SelectionAsMarkup().Utf8(); } void TestRunnerForSpecificView::SetViewSourceForFrame(const std::string& name, bool enabled) { + WebFrame* target_frame = + GetLocalMainFrame()->FindFrameByName(WebString::FromUTF8(name)); + if (target_frame) + target_frame->EnableViewSourceMode(enabled); +} + +blink::WebLocalFrame* TestRunnerForSpecificView::GetLocalMainFrame() { if (!web_view()->MainFrame()->IsWebLocalFrame()) { + // Hitting the check below uncovers a new scenario that requires OOPIF + // support in the layout tests harness. CHECK(false) << "This function cannot be called if the main frame is not a " "local frame."; } - - WebFrame* target_frame = - web_view()->MainFrame()->ToWebLocalFrame()->FindFrameByName( - WebString::FromUTF8(name)); - if (target_frame) - target_frame->EnableViewSourceMode(enabled); + return web_view()->MainFrame()->ToWebLocalFrame(); } blink::WebView* TestRunnerForSpecificView::web_view() {
diff --git a/content/shell/test_runner/test_runner_for_specific_view.h b/content/shell/test_runner/test_runner_for_specific_view.h index 8636461..6cb30a0 100644 --- a/content/shell/test_runner/test_runner_for_specific_view.h +++ b/content/shell/test_runner/test_runner_for_specific_view.h
@@ -215,6 +215,11 @@ std::string SelectionAsMarkup(); void SetViewSourceForFrame(const std::string& name, bool enabled); + // Many parts of the layout test harness assume that the main frame is local. + // Having all of them go through the helper below makes it easier to catch + // scenarios that require breaking this assumption. + blink::WebLocalFrame* GetLocalMainFrame(); + // Helpers for accessing pointers exposed by |web_view_test_proxy_base_|. blink::WebView* web_view(); WebTestDelegate* delegate();
diff --git a/content/shell/test_runner/web_ax_object_proxy.cc b/content/shell/test_runner/web_ax_object_proxy.cc index 5ae5dd7..65f5241 100644 --- a/content/shell/test_runner/web_ax_object_proxy.cc +++ b/content/shell/test_runner/web_ax_object_proxy.cc
@@ -13,8 +13,8 @@ #include "third_party/WebKit/public/platform/WebPoint.h" #include "third_party/WebKit/public/platform/WebRect.h" #include "third_party/WebKit/public/platform/WebString.h" -#include "third_party/WebKit/public/web/WebFrame.h" #include "third_party/WebKit/public/web/WebKit.h" +#include "third_party/WebKit/public/web/WebLocalFrame.h" #include "third_party/skia/include/core/SkMatrix44.h" #include "ui/gfx/geometry/rect_f.h" #include "ui/gfx/transform.h" @@ -742,7 +742,7 @@ } void WebAXObjectProxy::NotificationReceived( - blink::WebFrame* frame, + blink::WebLocalFrame* frame, const std::string& notification_name) { if (notification_callback_.IsEmpty()) return;
diff --git a/content/shell/test_runner/web_ax_object_proxy.h b/content/shell/test_runner/web_ax_object_proxy.h index 6c169c7..6e852499 100644 --- a/content/shell/test_runner/web_ax_object_proxy.h +++ b/content/shell/test_runner/web_ax_object_proxy.h
@@ -17,7 +17,7 @@ #include "v8/include/v8.h" namespace blink { -class WebFrame; +class WebLocalFrame; } namespace test_runner { @@ -44,7 +44,7 @@ virtual bool IsRoot() const; bool IsEqualToObject(const blink::WebAXObject& object); - void NotificationReceived(blink::WebFrame* frame, + void NotificationReceived(blink::WebLocalFrame* frame, const std::string& notification_name); void Reset();
diff --git a/content/test/data/accessibility/aria/aria-owns-list-expected-blink.txt b/content/test/data/accessibility/aria/aria-owns-list-expected-blink.txt new file mode 100644 index 0000000..624735ea --- /dev/null +++ b/content/test/data/accessibility/aria/aria-owns-list-expected-blink.txt
@@ -0,0 +1,8 @@ +rootWebArea +++list pageSize=(400, 400) +++++listItem pageSize=(400, 200) +++++++staticText name='One' +++++++++inlineTextBox name='One' +++++listItem pageSize=(400, 200) +++++++staticText name='Two' +++++++++inlineTextBox name='Two'
diff --git a/content/test/data/accessibility/aria/aria-owns-list.html b/content/test/data/accessibility/aria/aria-owns-list.html index 8112c65..b8587971 100644 --- a/content/test/data/accessibility/aria/aria-owns-list.html +++ b/content/test/data/accessibility/aria/aria-owns-list.html
@@ -1,5 +1,6 @@ <!-- @MAC-ALLOW:size=(400* +@BLINK-ALLOW:pageSize=(400* --> <html> <body>
diff --git a/docs/code_reviews.md b/docs/code_reviews.md index 6efe906..ae6bfd0f1 100644 --- a/docs/code_reviews.md +++ b/docs/code_reviews.md
@@ -43,8 +43,13 @@ Owners files are recursive, so each file also applies to its subdirectories. It's generally best to pick more specific owners. People listed in higher-level -directories may have less experience with the code in question. More detail on -the owners file format is provided in the "More information" section below. +directories may have less experience with the code in question. For example, +the reviewers in the `//chrome/browser/component_name/OWNERS` file will likely +be more familiar with code in `//chrome/browser/component_name/sub_component` +than reviewers in the higher-level `//chrome/OWNERS` file. + +More detail on the owners file format is provided in the "More information" +section below. *Tip:* The `git cl owners` command can help find owners. @@ -109,27 +114,40 @@ like normal. * Add a line "TBR=<reviewer's email>" to the bottom of the change list - description. + description. e.g. `TBR=reviewer1@chromium.org,reviewer2@chromium.org` + + * Type a message so that the owners in the TBR list can understand who is + responsible for reviewing what, as part of their post-commit review + responsibility. e.g. + ``` + TBRing reviewers: + reviewer1: Please review changes to foo/ + reviewer2: Please review changes to bar/ + ``` * Push the "send mail" button. ### TBR-ing certain types of mechanical changes Sometimes you might do something that affects many callers in different -directories. For example, adding a parameter to a common function in //base. -If the updates to the callers is mechanical, you can: +directories. For example, adding a parameter to a common function in +`//base`, with callers in `//chrome/browser/foo`, `//net/bar`, and many other +directories. If the updates to the callers is mechanical, you can: - * Get a normal owner of the lower-level directory you're changing (in this - example, `//base`) to do a proper review of those changes. + * Get a normal owner of the lower-level code you're changing (in this + example, the function in `//base`) to do a proper review of those changes. - * Get _somebody_ to review the downstream changes. This is often the same - person from the previous step but could be somebody else. + * Get _somebody_ to review the downstream changes made to the callers as a + result of the `//base` change. This is often the same person from the + previous step but could be somebody else. - * Add the owners of the affected downstream directories as TBR. + * Add the owners of the affected downstream directories as TBR. (In this + example, reviewers from `//chrome/browser/foo/OWNERS`, `//net/bar/OWNERS`, + etc.) This process ensures that all code is reviewed prior to checkin and that the concept of the change is reviewed by a qualified person, but you don't have to -track down many individual owners for trivial changes to their directories. +wait for many individual owners to review trivial changes to their directories. ### TBR-ing documentation updates @@ -155,7 +173,7 @@ ### OWNERS file details Refer to the [source code](https://chromium.googlesource.com/chromium/tools/depot_tools/+/master/owners.py) -for all details on the file format. +for all details on the file format. This example indicates that two people are owners, in addition to any owners from the parent directory. `git cl owners` will list the comment after an
diff --git a/extensions/renderer/extension_helper.cc b/extensions/renderer/extension_helper.cc index d90a34d7..eb64c4b6 100644 --- a/extensions/renderer/extension_helper.cc +++ b/extensions/renderer/extension_helper.cc
@@ -15,6 +15,7 @@ #include "extensions/renderer/dispatcher.h" #include "third_party/WebKit/public/platform/WebURLRequest.h" #include "third_party/WebKit/public/web/WebDocument.h" +#include "third_party/WebKit/public/web/WebLocalFrame.h" #include "third_party/WebKit/public/web/WebView.h" namespace extensions { @@ -66,9 +67,16 @@ } void ExtensionHelper::OnAppWindowClosed() { + // ExtensionMsg_AppWindowClosed is always sent to the current, non-swapped-out + // RenderView where the main frame is a local frame. + DCHECK(render_view()->GetWebView()->MainFrame()->IsWebLocalFrame()); + v8::HandleScope scope(v8::Isolate::GetCurrent()); - v8::Local<v8::Context> v8_context = - render_view()->GetWebView()->MainFrame()->MainWorldScriptContext(); + v8::Local<v8::Context> v8_context = render_view() + ->GetWebView() + ->MainFrame() + ->ToWebLocalFrame() + ->MainWorldScriptContext(); ScriptContext* script_context = dispatcher_->script_context_set().GetByV8Context(v8_context); if (!script_context)
diff --git a/extensions/renderer/guest_view/guest_view_internal_custom_bindings.cc b/extensions/renderer/guest_view/guest_view_internal_custom_bindings.cc index 77440ee..ddba6ea5 100644 --- a/extensions/renderer/guest_view/guest_view_internal_custom_bindings.cc +++ b/extensions/renderer/guest_view/guest_view_internal_custom_bindings.cc
@@ -342,14 +342,7 @@ return; blink::WebFrame* frame = view->GetWebView()->MainFrame(); - // TODO(lazyboy,nasko): The WebLocalFrame branch is not used when running - // on top of out-of-process iframes. Remove it once the code is converted. - v8::Local<v8::Value> window; - if (frame->IsWebLocalFrame()) { - window = frame->MainWorldScriptContext()->Global(); - } else { - window = frame->ToWebRemoteFrame()->GlobalProxy(); - } + v8::Local<v8::Value> window = frame->GlobalProxy(); args.GetReturnValue().Set(window); }
diff --git a/extensions/renderer/guest_view/mime_handler_view/mime_handler_view_container.cc b/extensions/renderer/guest_view/mime_handler_view/mime_handler_view_container.cc index c27ded7..14d599a2 100644 --- a/extensions/renderer/guest_view/mime_handler_view/mime_handler_view_container.cc +++ b/extensions/renderer/guest_view/mime_handler_view/mime_handler_view_container.cc
@@ -236,14 +236,7 @@ v8::Context::Scope context_scope( render_frame()->GetWebFrame()->MainWorldScriptContext()); - // TODO(lazyboy,nasko): The WebLocalFrame branch is not used when running - // on top of out-of-process iframes. Remove it once the code is converted. - v8::Local<v8::Object> guest_proxy_window; - if (guest_proxy_frame->IsWebLocalFrame()) { - guest_proxy_window = guest_proxy_frame->MainWorldScriptContext()->Global(); - } else { - guest_proxy_window = guest_proxy_frame->ToWebRemoteFrame()->GlobalProxy(); - } + v8::Local<v8::Object> guest_proxy_window = guest_proxy_frame->GlobalProxy(); gin::Dictionary window_object(isolate, guest_proxy_window); v8::Local<v8::Function> post_message; if (!window_object.Get(std::string(kPostMessageName), &post_message)) @@ -261,7 +254,7 @@ void MimeHandlerViewContainer::PostMessageFromValue( const base::Value& message) { - blink::WebFrame* frame = render_frame()->GetWebFrame(); + blink::WebLocalFrame* frame = render_frame()->GetWebFrame(); if (!frame) return; @@ -302,7 +295,7 @@ return; // Now that the guest has loaded, flush any unsent messages. - blink::WebFrame* frame = render_frame()->GetWebFrame(); + blink::WebLocalFrame* frame = render_frame()->GetWebFrame(); if (!frame) return;
diff --git a/extensions/renderer/runtime_custom_bindings.cc b/extensions/renderer/runtime_custom_bindings.cc index 66ed982f..fb1e4814 100644 --- a/extensions/renderer/runtime_custom_bindings.cc +++ b/extensions/renderer/runtime_custom_bindings.cc
@@ -94,7 +94,7 @@ // main views, not any subframes. (Returning subframes can cause broken // behavior by treating an app window's iframe as its main frame, and maybe // other nastiness). - blink::WebFrame* web_frame = frame->GetWebFrame(); + blink::WebLocalFrame* web_frame = frame->GetWebFrame(); if (web_frame->Top() != web_frame) continue;
diff --git a/extensions/shell/installer/BUILD.gn b/extensions/shell/installer/BUILD.gn new file mode 100644 index 0000000..091a8fc --- /dev/null +++ b/extensions/shell/installer/BUILD.gn
@@ -0,0 +1,26 @@ +# Copyright 2017 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import("//build/config/ui.gni") +import("//build/util/process_version.gni") +import("//extensions/features/features.gni") + +assert(enable_extensions) + +declare_args() { + enable_app_shell_installer = + is_desktop_linux && is_chrome_branded && current_cpu == "x64" +} + +# Meta-target that forwards to the installer of the correct type (if any). +# Named "app_shell_installer" to not conflict with Chrome's "installer" target. +group("app_shell_installer") { + # See the "app_shell_lib" definition for why testonly is needed. + testonly = true + if (enable_app_shell_installer) { + deps = [ + "//extensions/shell/installer/linux", + ] + } +}
diff --git a/extensions/shell/installer/linux/BUILD.gn b/extensions/shell/installer/linux/BUILD.gn new file mode 100644 index 0000000..8883c20 --- /dev/null +++ b/extensions/shell/installer/linux/BUILD.gn
@@ -0,0 +1,220 @@ +# 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. + +# TODO(michaelpg): Dedupe with Chrome installer. + +import("//build/config/chrome_build.gni") +import("//build/config/features.gni") +import("//build/config/sanitizers/sanitizers.gni") +import("//build/config/sysroot.gni") +import("//build/util/version.gni") +import("//chrome/process_version_rc_template.gni") # For branding_file_path. + +assert(is_desktop_linux) +assert(current_cpu == "x64") + +# The packages list the exact versions of each library used. The versions used +# on the bots are likely different than those on your workstation, so you'll +# get a stream of errors like: +# < libasound2 (>= 1.0.23) +# --- +# > libasound2 (>= 1.0.16) +# +# To avoid these warnings for testing purposes, do: +# +# export IGNORE_DEPS_CHANGES=1 +# +# before you build. +group("linux") { + # See the "app_shell_lib" definition for why testonly is needed. + testonly = true + deps = [ + # TODO(michaelpg): Add beta/stable once we verify the unstable installer is + # building and installing properly. + ":unstable", + ] +} + +branding_dir = "//chrome/app/theme/$branding_path_component" + +copy("common_packaging_files") { + visibility = [ ":*" ] + sources = [ + "//chrome/installer/linux/common/apt.include", + "//chrome/installer/linux/common/repo.cron", + "//chrome/installer/linux/common/symlinks.include", + "//chrome/installer/linux/common/variables.include", + "/usr/bin/eu-strip", + "common/installer.include", + "common/wrapper", + ] + + if (is_chrome_branded) { + sources += [ "common/google-app-shell/google-app-shell.info" ] + } else { + sources += [ "common/chromium-app-shell/chromium-app-shell.info" ] + } + + outputs = [ + "$root_out_dir/app_shell_installer/common/{{source_file_part}}", + ] +} + +copy("deb_packaging_files") { + visibility = [ ":*" ] + sources = [ + "//chrome/installer/linux/debian/changelog.template", + "//chrome/installer/linux/debian/control.template", + "debian/build.sh", + "debian/expected_deps_x64_jessie", + "debian/postinst", + "debian/postrm", + ] + outputs = [ + "$root_out_dir/app_shell_installer/debian/{{source_file_part}}", + ] +} + +copy("theme_files") { + visibility = [ ":*" ] + sources = [ + "$branding_dir/BRANDING", + ] + outputs = [ + "$root_out_dir/app_shell_installer/theme/{{source_file_part}}", + ] +} + +process_version("save_build_info") { + # Just output the default version info variables (no template). + process_only = true + sources = [ + "//build/util/LASTCHANGE", + "//chrome/VERSION", + branding_file_path, + ] + output = "$root_out_dir/app_shell_installer/version.txt" +} + +# Dependencies for all Linux installer targets. +group("installer_deps") { + testonly = true + + # Though many of these things appear in data_deps further down the + # dependency chain, they must appear here as public_deps so that they can + # be listed as inputs to the actions that depend on ":installer_deps" + # and are guaranteed to have been built before those actions run. + + public_deps = [ + ":common_packaging_files", + ":deb_packaging_files", + ":save_build_info", + ":theme_files", + "//extensions:shell_and_test_pak", + "//extensions/shell:app_shell", + ] + if (enable_nacl) { + public_deps += [ + "//components/nacl/loader:nacl_helper", + + # These are data_deps of nacl_helper, but that is not enough, + # as explained above. + "//native_client/src/trusted/service_runtime/linux:bootstrap", + "//ppapi/native_client:irt", + ] + } + if (use_custom_libcxx) { + public_deps += [ "//buildtools/third_party/libc++" ] + } +} + +# Creates .deb installer package. +# +# channel: +# Name of the channel. +template("linux_package") { + testonly = true + assert(defined(invoker.channel)) + channel = invoker.channel + + packaging_files_binaries = [ + # TODO(mmoss) Any convenient way to get all the relevant build + # files? (e.g. all locales, resources, etc.) + "$root_out_dir/app_shell", + "$root_out_dir/extensions_shell_and_test.pak", + ] + + if (enable_nacl) { + packaging_files_binaries += [ + "$root_out_dir/nacl_helper", + "$root_out_dir/nacl_helper_bootstrap", + "$root_out_dir/nacl_irt_x86_64.nexe", + ] + } + + if (use_custom_libcxx) { + packaging_files_binaries += [ "$root_out_dir/libc++.so" ] + } + + deb_target_name = "${target_name}_deb" + action(deb_target_name) { + visibility = [ ":*" ] + script = "//chrome/installer/linux/flock_make_package.py" + deb_arch = "amd64" + + inputs = packaging_files_binaries + outputs = [ + "$root_out_dir/google-app-shell-${channel}_${chrome_version_full}-1_${deb_arch}.deb", + ] + + args = [ + rebase_path("$root_out_dir/linux_package.lock", root_build_dir), + rebase_path("$root_out_dir/app_shell_installer/debian/build.sh", + root_build_dir), + "-o", + rebase_path(root_out_dir, root_build_dir), + "-b", + rebase_path(root_out_dir, root_build_dir), + "-a", + current_cpu, + "-c", + invoker.channel, + "-d", + branding_path_component, + "-s", + rebase_path(sysroot), + ] + deps = [ + ":installer_deps", + ] + } + + group(target_name) { + deps = [ + ":$deb_target_name", + ] + } +} + +# Standard packages. +linux_package("unstable") { + channel = "unstable" +} +linux_package("stable") { + channel = "stable" +} +linux_package("beta") { + channel = "beta" +} + +# Other packages that we support that aren't included in the default "linux" +# target. +linux_package("trunk") { + channel = "trunk" +} +if (is_asan) { + linux_package("asan") { + channel = "asan" + } +}
diff --git a/extensions/shell/installer/linux/common/chromium-app-shell/chromium-app-shell.info b/extensions/shell/installer/linux/common/chromium-app-shell/chromium-app-shell.info new file mode 100644 index 0000000..ee88042 --- /dev/null +++ b/extensions/shell/installer/linux/common/chromium-app-shell/chromium-app-shell.info
@@ -0,0 +1,30 @@ +# 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. +# +# This file provides common configuration information for building +# chromium-app-shell for various platforms. + +# Base name of the package. +PACKAGE="chromium-app-shell" + +# Filename of the main executable (for generating launcher scripts, etc.) +PROGNAME=app_shell + +# Base directory for package installation. +INSTALLDIR=/opt/chromium.org/app-shell + +# Display string for desktop menu/icon. +MENUNAME="Chromium App Shell" + +# Brief package description. +SHORTDESC="The app shell from Chromium.org" + +# Detailed package description. +FULLDESC="The app shell from Chromium.org" + +# Package maintainer information. +# TODO(mmoss) Setup a mailbox for this address +MAINTNAME="Chromium Linux Team" +MAINTMAIL="chromium-linux-packager@chromium.org" +PRODUCTURL="http://www.chromium.org/"
diff --git a/extensions/shell/installer/linux/common/google-app-shell/google-app-shell.info b/extensions/shell/installer/linux/common/google-app-shell/google-app-shell.info new file mode 100644 index 0000000..4086733 --- /dev/null +++ b/extensions/shell/installer/linux/common/google-app-shell/google-app-shell.info
@@ -0,0 +1,30 @@ +# 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. +# +# This file provides common configuration information for building +# app-shell packages for various platforms. + +# Base name of the package. +PACKAGE="google-app-shell" + +# Filename of the main executable (for generating launcher scripts, etc.) +PROGNAME=app_shell + +# Base directory for package installation. +INSTALLDIR=/opt/google/app-shell + +# Display string for desktop menu/icon. +MENUNAME="App Shell" + +# Brief package description. +SHORTDESC="The app shell from Google" + +# Detailed package description. +FULLDESC="The app shell from Google" + +# Package maintainer information. +# TODO(mmoss) Setup a mailbox for this address +MAINTNAME="Chrome Linux Team" +MAINTMAIL="chromium-dev@chromium.org" +PRODUCTURL="https://chrome.google.com/"
diff --git a/extensions/shell/installer/linux/common/installer.include b/extensions/shell/installer/linux/common/installer.include new file mode 100644 index 0000000..521916f --- /dev/null +++ b/extensions/shell/installer/linux/common/installer.include
@@ -0,0 +1,193 @@ +# TODO(michaelpg): Dedupe common functionality with the Chrome installer. + +# Recursively replace @@include@@ template variables with the referenced file, +# and write the resulting text to stdout. +process_template_includes() { + INCSTACK+="$1->" + # Includes are relative to the file that does the include. + INCDIR=$(dirname $1) + # Clear IFS so 'read' doesn't trim whitespace + local OLDIFS="$IFS" + IFS='' + while read -r LINE + do + INCLINE=$(sed -e '/^[[:space:]]*@@include@@/!d' <<<$LINE) + if [ -n "$INCLINE" ]; then + INCFILE=$(echo $INCLINE | sed -e "s#@@include@@\(.*\)#\1#") + # Simple filename match to detect cyclic includes. + CYCLE=$(sed -e "\#$INCFILE#"'!d' <<<$INCSTACK) + if [ "$CYCLE" ]; then + echo "ERROR: Possible cyclic include detected." 1>&2 + echo "$INCSTACK$INCFILE" 1>&2 + exit 1 + fi + if [ ! -r "$INCDIR/$INCFILE" ]; then + echo "ERROR: Couldn't read include file: $INCDIR/$INCFILE" 1>&2 + exit 1 + fi + process_template_includes "$INCDIR/$INCFILE" + else + echo "$LINE" + fi + done < "$1" + IFS="$OLDIFS" + INCSTACK=${INCSTACK%"$1->"} +} + +# Replace template variables (@@VARNAME@@) in the given template file. If a +# second argument is given, save the processed text to that filename, otherwise +# modify the template file in place. +process_template() ( + # Don't worry if some of these substitution variables aren't set. + # Note that this function is run in a sub-shell so we don't leak this + # setting, since we still want unbound variables to be an error elsewhere. + set +u + + local TMPLIN="$1" + if [ -z "$2" ]; then + local TMPLOUT="$TMPLIN" + else + local TMPLOUT="$2" + fi + # Process includes first so included text also gets substitutions. + TMPLINCL="$(process_template_includes "$TMPLIN")" + sed \ + -e "s#@@PACKAGE@@#${PACKAGE}#g" \ + -e "s#@@PACKAGE_FILENAME@@#${PACKAGE_FILENAME}#g" \ + -e "s#@@PROGNAME@@#${PROGNAME}#g" \ + -e "s#@@CHANNEL@@#${CHANNEL}#g" \ + -e "s#@@COMPANY_FULLNAME@@#${COMPANY_FULLNAME}#g" \ + -e "s#@@VERSION@@#${VERSION}#g" \ + -e "s#@@PACKAGE_RELEASE@@#${PACKAGE_RELEASE}#g" \ + -e "s#@@VERSIONFULL@@#${VERSIONFULL}#g" \ + -e "s#@@INSTALLDIR@@#${INSTALLDIR}#g" \ + -e "s#@@BUILDDIR@@#${BUILDDIR}#g" \ + -e "s#@@STAGEDIR@@#${STAGEDIR}#g" \ + -e "s#@@SCRIPTDIR@@#${SCRIPTDIR}#g" \ + -e "s#@@MENUNAME@@#${MENUNAME}#g" \ + -e "s#@@PRODUCTURL@@#${PRODUCTURL}#g" \ + -e "s#@@PREDEPENDS@@#${PREDEPENDS}#g" \ + -e "s#@@DEPENDS@@#${DEPENDS}#g" \ + -e "s#@@PROVIDES@@#${PROVIDES}#g" \ + -e "s#@@REPLACES@@#${REPLACES}#g" \ + -e "s#@@CONFLICTS@@#${CONFLICTS}#g" \ + -e "s#@@ARCHITECTURE@@#${ARCHITECTURE}#g" \ + -e "s#@@MAINTNAME@@#${MAINTNAME}#g" \ + -e "s#@@MAINTMAIL@@#${MAINTMAIL}#g" \ + -e "s#@@REPOCONFIG@@#${REPOCONFIG}#g" \ + -e "s#@@REPOCONFIGREGEX@@#${REPOCONFIGREGEX}#g" \ + -e "s#@@SHORTDESC@@#${SHORTDESC}#g" \ + -e "s#@@FULLDESC@@#${FULLDESC}#g" \ + -e "s#@@USR_BIN_SYMLINK_NAME@@#${USR_BIN_SYMLINK_NAME:-}#g" \ + > "$TMPLOUT" <<< "$TMPLINCL" +) + +# Setup the installation directory hierachy in the package staging area. +prep_staging_common() { + install -m 755 -d "${STAGEDIR}/${INSTALLDIR}" \ + "${STAGEDIR}/usr/bin" +} + +get_version_info() { + source "${BUILDDIR}/app_shell_installer/version.txt" + VERSION="${MAJOR}.${MINOR}.${BUILD}.${PATCH}" + # TODO(phajdan.jr): Provide a mechanism to pass a different package + # release number if needed. The meaning of it is to bump it for + # packaging-only changes while the underlying software has the same version. + # This corresponds to the Release field in RPM spec files and debian_revision + # component of the Version field for DEB control file. + # Generally with Chrome's fast release cycle it'd be more hassle to try + # to bump this number between releases. + PACKAGE_RELEASE="1" +} + +stage_install_common() { + echo "Staging common install files in '${STAGEDIR}'..." + + # TODO(mmoss) This assumes we built the static binaries. To support shared + # builds, we probably want an install target in scons so it can give us all + # the right files. See also: + # http://code.google.com/p/chromium/issues/detail?id=4451 + # + # app + # We need to add the debug link so gdb knows to look for the symbols. + DEBUGFILE="${BUILDDIR}/${PROGNAME}.debug" + STRIPPEDFILE="${BUILDDIR}/${PROGNAME}.stripped" + "${BUILDDIR}/app_shell_installer/common/eu-strip" -o "${STRIPPEDFILE}" -f "${DEBUGFILE}" "${BUILDDIR}/${PROGNAME}" + install -m 755 "${STRIPPEDFILE}" "${STAGEDIR}/${INSTALLDIR}/${PROGNAME}" + rm "${DEBUGFILE}" "${STRIPPEDFILE}" + + # resources + install -m 644 \ + "${BUILDDIR}/extensions_shell_and_test.pak" \ + "${STAGEDIR}/${INSTALLDIR}/" + + + # ICU data file; only necessary when icu_use_data_file_flag is set to 1 + # in build/common.gypi. + install -m 644 "${BUILDDIR}/icudtl.dat" "${STAGEDIR}/${INSTALLDIR}/" + + # V8 snapshot files; only necessary when v8_use_external_startup_data is + # set to 1 in build/common.gypi. + if [ -f "${BUILDDIR}/natives_blob.bin" ]; then + install -m 644 "${BUILDDIR}/natives_blob.bin" "${STAGEDIR}/${INSTALLDIR}/" + install -m 644 "${BUILDDIR}/snapshot_blob.bin" "${STAGEDIR}/${INSTALLDIR}/" + fi + + # ANGLE + if [ "${CHANNEL}" != "stable" ]; then + install -m 644 "${BUILDDIR}/libGLESv2.so" "${STAGEDIR}/${INSTALLDIR}/" + install -m 644 "${BUILDDIR}/libEGL.so" "${STAGEDIR}/${INSTALLDIR}/" + fi + + # SwiftShader + if [ -f "${BUILDDIR}/swiftshader/libEGL.so" ]; then + install -m 755 -d "${STAGEDIR}/${INSTALLDIR}/swiftshader/" + install -m 644 "${BUILDDIR}/swiftshader/libEGL.so" "${STAGEDIR}/${INSTALLDIR}/swiftshader/" + install -m 644 "${BUILDDIR}/swiftshader/libGLESv2.so" "${STAGEDIR}/${INSTALLDIR}/swiftshader/" + fi + + # libc++ + if [ -f "${BUILDDIR}/lib/libc++.so" ]; then + install -m 755 -d "${STAGEDIR}/${INSTALLDIR}/lib/" + + install -m 644 -s "${BUILDDIR}/lib/libc++.so" "${STAGEDIR}/${INSTALLDIR}/lib/" + fi + + + # nacl_helper and nacl_helper_bootstrap + # Don't use "-s" (strip) because this runs binutils "strip", which + # mangles the special ELF program headers of nacl_helper_bootstrap. + # Explicitly use eu-strip instead, because it doesn't have that problem. + for file in nacl_helper nacl_helper_bootstrap; do + buildfile="${BUILDDIR}/${file}" + if [ -f "${buildfile}" ]; then + strippedfile="${buildfile}.stripped" + debugfile="${buildfile}.debug" + "${BUILDDIR}/app_shell_installer/common/eu-strip" -o "${strippedfile}" -f "${debugfile}" "${buildfile}" + install -m 755 "${strippedfile}" "${STAGEDIR}/${INSTALLDIR}/${file}" + fi + done + # Don't use "-s" (strip) because this would use the Linux toolchain to + # strip the NaCl binary, which has the potential to break it. It + # certainly resets the OSABI and ABIVERSION fields to non-NaCl values, + # although the NaCl IRT loader doesn't care about these fields. In any + # case, the IRT binaries are already stripped by NaCl's build process. + for filename in ${BUILDDIR}/nacl_irt_*.nexe; do + # Re-check the filename in case globbing matched nothing. + if [ -f "$filename" ]; then + install -m 644 "$filename" "${STAGEDIR}/${INSTALLDIR}/`basename "$filename"`" + fi + done + + # launcher script and symlink + process_template "${BUILDDIR}/app_shell_installer/common/wrapper" \ + "${STAGEDIR}/${INSTALLDIR}/${PACKAGE}" + chmod 755 "${STAGEDIR}/${INSTALLDIR}/${PACKAGE}" + if [ ! -f "${STAGEDIR}/${INSTALLDIR}/app-shell" ]; then + ln -sn "${INSTALLDIR}/${PACKAGE}" \ + "${STAGEDIR}/${INSTALLDIR}/app-shell" + fi + ln -snf "${INSTALLDIR}/${PACKAGE}" \ + "${STAGEDIR}/usr/bin/${USR_BIN_SYMLINK_NAME}" +}
diff --git a/extensions/shell/installer/linux/common/wrapper b/extensions/shell/installer/linux/common/wrapper new file mode 100755 index 0000000..487e522 --- /dev/null +++ b/extensions/shell/installer/linux/common/wrapper
@@ -0,0 +1,32 @@ +#!/bin/bash +# +# 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. + +# Let the wrapped binary know that it has been run through the wrapper. +export APP_SHELL_WRAPPER="`readlink -f "$0"`" + +HERE="`dirname "$APP_SHELL_WRAPPER"`" + +# Always use our versions of ffmpeg libs. +if [[ -n "$LD_LIBRARY_PATH" ]]; then + LD_LIBRARY_PATH="$HERE:$HERE/lib:$LD_LIBRARY_PATH" +else + LD_LIBRARY_PATH="$HERE:$HERE/lib" +fi +export LD_LIBRARY_PATH + +export CHROME_VERSION_EXTRA="@@CHANNEL@@" + +# We don't want bug-buddy intercepting our crashes. http://crbug.com/24120 +export GNOME_DISABLE_CRASH_DIALOG=SET_BY_GOOGLE_CHROME + +# Sanitize std{in,out,err} because they'll be shared with untrusted child +# processes (http://crbug.com/376567). +exec < /dev/null +exec > >(exec cat) +exec 2> >(exec cat >&2) + +# Note: exec -a below is a bashism. +exec -a "$0" "$HERE/@@PROGNAME@@" "$@"
diff --git a/extensions/shell/installer/linux/debian/build.sh b/extensions/shell/installer/linux/debian/build.sh new file mode 100755 index 0000000..331d9ad4 --- /dev/null +++ b/extensions/shell/installer/linux/debian/build.sh
@@ -0,0 +1,351 @@ +#!/bin/bash +# +# 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. + +# TODO(michaelpg): Dedupe common functionality with the Chrome installer. + +# TODO(mmoss) This currently only works with official builds, since non-official +# builds don't add the "${BUILDDIR}/app_shell_installer/" files needed for +# packaging. + +set -e +set -o pipefail +if [ "$VERBOSE" ]; then + set -x +fi +set -u + +# Create the Debian changelog file needed by dpkg-gencontrol. This just adds a +# placeholder change, indicating it is the result of an automatic build. +# TODO(mmoss) Release packages should create something meaningful for a +# changelog, but simply grabbing the actual 'svn log' is way too verbose. Do we +# have any type of "significant/visible changes" log that we could use for this? +gen_changelog() { + rm -f "${DEB_CHANGELOG}" + process_template "${SCRIPTDIR}/changelog.template" "${DEB_CHANGELOG}" + debchange -a --nomultimaint -m --changelog "${DEB_CHANGELOG}" \ + "Release Notes: ${RELEASENOTES}" + GZLOG="${STAGEDIR}/usr/share/doc/${PACKAGE}-${CHANNEL}/changelog.gz" + mkdir -p "$(dirname "${GZLOG}")" + gzip -9 -c "${DEB_CHANGELOG}" > "${GZLOG}" + chmod 644 "${GZLOG}" +} + +# Create the Debian control file needed by dpkg-deb. +gen_control() { + dpkg-gencontrol -v"${VERSIONFULL}" -c"${DEB_CONTROL}" -l"${DEB_CHANGELOG}" \ + -f"${DEB_FILES}" -p"${PACKAGE}-${CHANNEL}" -P"${STAGEDIR}" \ + -O > "${STAGEDIR}/DEBIAN/control" + rm -f "${DEB_CONTROL}" +} + +# Setup the installation directory hierachy in the package staging area. +prep_staging_debian() { + prep_staging_common + install -m 755 -d "${STAGEDIR}/DEBIAN" \ + "${STAGEDIR}/etc/cron.daily" \ + "${STAGEDIR}/usr/share/doc/${USR_BIN_SYMLINK_NAME}" +} + +# Put the package contents in the staging area. +stage_install_debian() { + # Always use a different name for /usr/bin symlink depending on channel to + # avoid file collisions. + local USR_BIN_SYMLINK_NAME="${PACKAGE}-${CHANNEL}" + + if [ "$CHANNEL" != "stable" ]; then + # Avoid file collisions between channels. + local INSTALLDIR="${INSTALLDIR}-${CHANNEL}" + + local PACKAGE="${PACKAGE}-${CHANNEL}" + fi + prep_staging_debian + stage_install_common + echo "Staging Debian install files in '${STAGEDIR}'..." + install -m 755 -d "${STAGEDIR}/${INSTALLDIR}/cron" + process_template "${BUILDDIR}/app_shell_installer/common/repo.cron" \ + "${STAGEDIR}/${INSTALLDIR}/cron/${PACKAGE}" + chmod 755 "${STAGEDIR}/${INSTALLDIR}/cron/${PACKAGE}" + pushd "${STAGEDIR}/etc/cron.daily/" + ln -snf "${INSTALLDIR}/cron/${PACKAGE}" "${PACKAGE}" + popd + process_template "${BUILDDIR}/app_shell_installer/debian/postinst" \ + "${STAGEDIR}/DEBIAN/postinst" + chmod 755 "${STAGEDIR}/DEBIAN/postinst" + process_template "${BUILDDIR}/app_shell_installer/debian/postrm" \ + "${STAGEDIR}/DEBIAN/postrm" + chmod 755 "${STAGEDIR}/DEBIAN/postrm" +} + +# Actually generate the package file. +do_package() { + echo "Packaging ${ARCHITECTURE}..." + PREDEPENDS="$COMMON_PREDEPS" + DEPENDS="${COMMON_DEPS}" + REPLACES="" + CONFLICTS="" + PROVIDES="" + gen_changelog + process_template "${SCRIPTDIR}/control.template" "${DEB_CONTROL}" + export DEB_HOST_ARCH="${ARCHITECTURE}" + if [ -f "${DEB_CONTROL}" ]; then + gen_control + fi + fakeroot dpkg-deb -Zxz -z9 -b "${STAGEDIR}" . +} + +verify_package() { + DEPENDS="${COMMON_DEPS}" # This needs to match do_package() above. + echo ${DEPENDS} | sed 's/, /\n/g' | LANG=C sort > expected_deb_depends + dpkg -I "${PACKAGE}-${CHANNEL}_${VERSIONFULL}_${ARCHITECTURE}.deb" | \ + grep '^ Depends: ' | sed 's/^ Depends: //' | sed 's/, /\n/g' | \ + LANG=C sort > actual_deb_depends + BAD_DIFF=0 + diff -u expected_deb_depends actual_deb_depends || BAD_DIFF=1 + if [ $BAD_DIFF -ne 0 ] && [ -z "${IGNORE_DEPS_CHANGES:-}" ]; then + echo + echo "ERROR: bad dpkg dependencies!" + echo + exit $BAD_DIFF + fi +} + +# Remove temporary files and unwanted packaging output. +cleanup() { + echo "Cleaning..." + rm -rf "${STAGEDIR}" + rm -rf "${TMPFILEDIR}" +} + +usage() { + echo "usage: $(basename $0) [-c channel] [-a target_arch] [-o 'dir'] " + echo " [-b 'dir'] -d branding" + echo "-c channel the package channel (trunk, asan, unstable, beta, stable)" + echo "-a arch package architecture (ia32 or x64)" + echo "-o dir package output directory [${OUTPUTDIR}]" + echo "-b dir build input directory [${BUILDDIR}]" + echo "-d brand either chromium or google_chrome" + echo "-s dir /path/to/sysroot" + echo "-h this help message" +} + +# Check that the channel name is one of the allowable ones. +verify_channel() { + case $CHANNEL in + stable ) + CHANNEL=stable + RELEASENOTES="http://googlechromereleases.blogspot.com/search/label/Stable%20updates" + ;; + unstable|dev|alpha ) + CHANNEL=unstable + RELEASENOTES="http://googlechromereleases.blogspot.com/search/label/Dev%20updates" + ;; + testing|beta ) + CHANNEL=beta + RELEASENOTES="http://googlechromereleases.blogspot.com/search/label/Beta%20updates" + ;; + trunk|asan ) + # Setting this to empty will prevent it from updating any existing configs + # from release packages. + REPOCONFIG="" + RELEASENOTES="http://googlechromereleases.blogspot.com/" + ;; + * ) + echo + echo "ERROR: '$CHANNEL' is not a valid channel type." + echo + exit 1 + ;; + esac +} + +process_opts() { + while getopts ":s:o:b:c:a:d:h" OPTNAME + do + case $OPTNAME in + o ) + OUTPUTDIR=$(readlink -f "${OPTARG}") + mkdir -p "${OUTPUTDIR}" + ;; + b ) + BUILDDIR=$(readlink -f "${OPTARG}") + ;; + c ) + CHANNEL="$OPTARG" + ;; + a ) + TARGETARCH="$OPTARG" + ;; + d ) + BRANDING="$OPTARG" + ;; + s ) + SYSROOT="$OPTARG" + ;; + h ) + usage + exit 0 + ;; + \: ) + echo "'-$OPTARG' needs an argument." + usage + exit 1 + ;; + * ) + echo "invalid command-line option: $OPTARG" + usage + exit 1 + ;; + esac + done +} + +#========= +# MAIN +#========= + +SCRIPTDIR=$(readlink -f "$(dirname "$0")") +OUTPUTDIR="${PWD}" +STAGEDIR=$(mktemp -d -t deb.build.XXXXXX) || exit 1 +TMPFILEDIR=$(mktemp -d -t deb.tmp.XXXXXX) || exit 1 +DEB_CHANGELOG="${TMPFILEDIR}/changelog" +DEB_FILES="${TMPFILEDIR}/files" +DEB_CONTROL="${TMPFILEDIR}/control" +CHANNEL="trunk" +# Default target architecture to same as build host. +if [ "$(uname -m)" = "x86_64" ]; then + TARGETARCH="x64" +else + TARGETARCH="ia32" +fi + +# call cleanup() on exit +trap cleanup 0 +process_opts "$@" +BUILDDIR=${BUILDDIR:=$(readlink -f "${SCRIPTDIR}/../../../../out/Release")} + +if [[ "$(basename ${SYSROOT})" = "debian_jessie_"*"-sysroot" ]]; then + TARGET_DISTRO="jessie" +else + echo "Debian package can only be built using the jessie sysroot." + exit 1 +fi + +source ${BUILDDIR}/app_shell_installer/common/installer.include + +get_version_info +VERSIONFULL="${VERSION}-${PACKAGE_RELEASE}" + +if [ "$BRANDING" = "google_chrome" ]; then + source "${BUILDDIR}/app_shell_installer/common/google-app-shell.info" +else + source "${BUILDDIR}/app_shell_installer/common/chromium-app-shell.info" +fi +eval $(sed -e "s/^\([^=]\+\)=\(.*\)$/export \1='\2'/" \ + "${BUILDDIR}/app_shell_installer/theme/BRANDING") + +verify_channel + +# Some Debian packaging tools want these set. +export DEBFULLNAME="${MAINTNAME}" +export DEBEMAIL="${MAINTMAIL}" + +# We'd like to eliminate more of these deps by relying on the 'lsb' package, but +# that brings in tons of unnecessary stuff, like an mta and rpm. Until that full +# 'lsb' package is installed by default on DEB distros, we'll have to stick with +# the LSB sub-packages, to avoid pulling in all that stuff that's not installed +# by default. + +# Generate the dependencies, +# TODO(mmoss): This is a workaround for a problem where dpkg-shlibdeps was +# resolving deps using some of our build output shlibs (i.e. +# out/Release/lib.target/libfreetype.so.6), and was then failing with: +# dpkg-shlibdeps: error: no dependency information found for ... +# It's not clear if we ever want to look in LD_LIBRARY_PATH to resolve deps, +# but it seems that we don't currently, so this is the most expediant fix. +SAVE_LDLP=${LD_LIBRARY_PATH:-} +unset LD_LIBRARY_PATH +if [ ${TARGETARCH} = "x64" ]; then + SHLIB_ARGS="-l${SYSROOT}/usr/lib/x86_64-linux-gnu" + SHLIB_ARGS="${SHLIB_ARGS} -l${SYSROOT}/lib/x86_64-linux-gnu" +else + SHLIB_ARGS="-l${SYSROOT}/usr/lib/i386-linux-gnu" + SHLIB_ARGS="${SHLIB_ARGS} -l${SYSROOT}/lib/i386-linux-gnu" +fi +SHLIB_ARGS="${SHLIB_ARGS} -l${SYSROOT}/usr/lib" +DPKG_SHLIB_DEPS=$(cd ${SYSROOT} && dpkg-shlibdeps ${SHLIB_ARGS:-} -O \ + -e"$BUILDDIR/app_shell" | sed 's/^shlibs:Depends=//') +if [ -n "$SAVE_LDLP" ]; then + LD_LIBRARY_PATH=$SAVE_LDLP +fi + +# Format it nicely and save it for comparison. +echo "$DPKG_SHLIB_DEPS" | sed 's/, /\n/g' | LANG=C sort > actual + +# Compare the expected dependency list to the generated list. +BAD_DIFF=0 +diff -u "$SCRIPTDIR/expected_deps_${TARGETARCH}_${TARGET_DISTRO}" actual || \ + BAD_DIFF=1 +if [ $BAD_DIFF -ne 0 ] && [ -z "${IGNORE_DEPS_CHANGES:-}" ]; then + echo + echo "ERROR: Shared library dependencies changed!" + echo "If this is intentional, please update:" + echo "extensions/shell/installer/linux/debian/expected_deps_*" + echo + exit $BAD_DIFF +fi + +# Additional dependencies not in the dpkg-shlibdeps output. +# ca-certificates: Make sure users have SSL certificates. +# libnss3: Pull a more recent version of NSS than required by runtime linking, +# for security and stability updates in NSS. +# lsb-release: For lsb-release. +# wget: For uploading crash reports with Breakpad. +ADDITIONAL_DEPS="ca-certificates, libnss3 (>= 3.26), lsb-release, wget" + +# Fix-up libnspr dependency due to renaming in Ubuntu (the old package still +# exists, but it was moved to "universe" repository, which isn't installed by +# default). +DPKG_SHLIB_DEPS=$(sed \ + 's/\(libnspr4-0d ([^)]*)\), /\1 | libnspr4 (>= 4.9.5-0ubuntu0), /g' \ + <<< $DPKG_SHLIB_DEPS) + +# Remove libnss dependency so the one in $ADDITIONAL_DEPS can supercede it. +DPKG_SHLIB_DEPS=$(sed 's/\(libnss3 ([^)]*)\), //g' <<< $DPKG_SHLIB_DEPS) + +COMMON_DEPS="${DPKG_SHLIB_DEPS}, ${ADDITIONAL_DEPS}" +COMMON_PREDEPS="dpkg (>= 1.14.0)" + + +# Make everything happen in the OUTPUTDIR. +cd "${OUTPUTDIR}" + +case "$TARGETARCH" in + ia32 ) + export ARCHITECTURE="i386" + ;; + x64 ) + export ARCHITECTURE="amd64" + ;; + * ) + echo + echo "ERROR: Don't know how to build DEBs for '$TARGETARCH'." + echo + exit 1 + ;; +esac +# TODO(michaelpg): Get a working repo URL. +BASEREPOCONFIG="dl.google.com/linux/app-shell/deb/ stable main" +# Only use the default REPOCONFIG if it's unset (e.g. verify_channel might have +# set it to an empty string) +REPOCONFIG="${REPOCONFIG-deb [arch=${ARCHITECTURE}] http://${BASEREPOCONFIG}}" +# Allowed configs include optional HTTPS support and explicit multiarch +# platforms. +REPOCONFIGREGEX="deb (\\\\[arch=[^]]*\\\\b${ARCHITECTURE}\\\\b[^]]*\\\\]" +REPOCONFIGREGEX+="[[:space:]]*) https?://${BASEREPOCONFIG}" +stage_install_debian + +do_package +verify_package
diff --git a/extensions/shell/installer/linux/debian/expected_deps_x64_jessie b/extensions/shell/installer/linux/debian/expected_deps_x64_jessie new file mode 100644 index 0000000..5fc6eff --- /dev/null +++ b/extensions/shell/installer/linux/debian/expected_deps_x64_jessie
@@ -0,0 +1,28 @@ +gconf-service +libasound2 (>= 1.0.16) +libatk1.0-0 (>= 1.12.4) +libc6 (>= 2.15) +libdbus-1-3 (>= 1.1.4) +libexpat1 (>= 2.0.1) +libfontconfig1 (>= 2.11) +libgcc1 (>= 1:4.1.1) +libgconf-2-4 (>= 3.2.5) +libglib2.0-0 (>= 2.14.0) +libnspr4 (>= 2:4.9-2~) +libnss3 (>= 2:3.13.4-2~) +libpango-1.0-0 (>= 1.14.0) +libpangocairo-1.0-0 (>= 1.14.0) +libstdc++6 (>= 4.8.1) +libx11-6 (>= 2:1.4.99.1) +libx11-xcb1 +libxcb1 (>= 1.6) +libxcomposite1 (>= 1:0.3-1) +libxcursor1 (>> 1.1.2) +libxdamage1 (>= 1:1.1) +libxext6 +libxfixes3 +libxi6 (>= 2:1.2.99.4) +libxrandr2 +libxrender1 +libxss1 +libxtst6
diff --git a/extensions/shell/installer/linux/debian/postinst b/extensions/shell/installer/linux/debian/postinst new file mode 100755 index 0000000..68aa893 --- /dev/null +++ b/extensions/shell/installer/linux/debian/postinst
@@ -0,0 +1,22 @@ +#!/bin/sh +# +# 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. + +set -e + +@@include@@../common/apt.include + +@@include@@../common/symlinks.include + +remove_udev_symlinks + +## MAIN ## +if [ ! -e "$DEFAULTS_FILE" ]; then + echo 'repo_add_once="true"' > "$DEFAULTS_FILE" + echo 'repo_reenable_on_distupgrade="true"' >> "$DEFAULTS_FILE" +fi + +# Run the cron job immediately to perform repository configuration. +nohup sh /etc/cron.daily/@@PACKAGE@@ > /dev/null 2>&1 &
diff --git a/extensions/shell/installer/linux/debian/postrm b/extensions/shell/installer/linux/debian/postrm new file mode 100755 index 0000000..6d369e7 --- /dev/null +++ b/extensions/shell/installer/linux/debian/postrm
@@ -0,0 +1,33 @@ +#!/bin/sh +# +# 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. + +set -e + +action="$1" + +# Only do complete clean-up on purge. +if [ "$action" != "purge" ] ; then + exit 0 +fi + +@@include@@../common/apt.include + +@@include@@../common/symlinks.include + +remove_udev_symlinks + +# Only remove the defaults file if it is not empty. An empty file was probably +# put there by the sysadmin to disable automatic repository configuration, as +# per the instructions on the package download page. +if [ -s "$DEFAULTS_FILE" ]; then + # Make sure the package defaults are removed before the repository config, + # otherwise it could result in the repository config being removed, but the + # package defaults remain and are set to not recreate the repository config. + # In that case, future installs won't recreate it and won't get auto-updated. + rm "$DEFAULTS_FILE" || exit 1 +fi +# Remove any Google repository added by the package. +clean_sources_lists
diff --git a/gpu/command_buffer/service/scheduler.cc b/gpu/command_buffer/service/scheduler.cc index ca080e4..2b4bfc3 100644 --- a/gpu/command_buffer/service/scheduler.cc +++ b/gpu/command_buffer/service/scheduler.cc
@@ -366,9 +366,6 @@ DCHECK(thread_checker_.CalledOnValidThread()); base::AutoLock auto_lock(lock_); - if (should_yield_) - return true; - RebuildSchedulingQueue(); if (scheduling_queue_.empty()) @@ -382,9 +379,7 @@ DCHECK(next_sequence); DCHECK(next_sequence->scheduled()); - should_yield_ = running_sequence->ShouldYieldTo(next_sequence); - - return should_yield_; + return running_sequence->ShouldYieldTo(next_sequence); } void Scheduler::SyncTokenFenceReleased(const SyncToken& sync_token, @@ -456,8 +451,6 @@ DCHECK(thread_checker_.CalledOnValidThread()); base::AutoLock auto_lock(lock_); - should_yield_ = false; - RebuildSchedulingQueue(); if (scheduling_queue_.empty()) {
diff --git a/gpu/command_buffer/service/scheduler.h b/gpu/command_buffer/service/scheduler.h index c6dab1cf..4aa3c70 100644 --- a/gpu/command_buffer/service/scheduler.h +++ b/gpu/command_buffer/service/scheduler.h
@@ -118,10 +118,6 @@ // SchedulingState with highest priority (lowest order) in front. std::vector<SchedulingState> scheduling_queue_; - // If the running sequence should yield so that a higher priority sequence can - // run. - bool should_yield_ = false; - // If the scheduling queue needs to be rebuild because a sequence changed // priority. bool rebuild_scheduling_queue_ = false;
diff --git a/gpu/config/gpu_driver_bug_list.json b/gpu/config/gpu_driver_bug_list.json index 1dfa1679f..e13c91ee 100644 --- a/gpu/config/gpu_driver_bug_list.json +++ b/gpu/config/gpu_driver_bug_list.json
@@ -1,6 +1,6 @@ { "name": "gpu driver bug list", - "version": "10.12", + "version": "10.13", "entries": [ { "id": 1, @@ -2496,6 +2496,34 @@ "features": [ "multisample_renderbuffer_resize_emulation" ] + }, + { + "id": 232, + "description": "Delayed copy NV12 crashes on Intel on Windows <= 8.1.", + "cr_bugs": [727216], + "os": { + "type": "win", + "version": { + "op": "<=", + "value": "8.1" + } + }, + "vendor_id": "0x8086", + "features": [ + "disable_delayed_copy_nv12" + ] + }, + { + "id": 233, + "description": "Delayed copy NV12 displays incorrect colors on NVIDIA drivers.", + "cr_bugs": [728670], + "os": { + "type": "win" + }, + "vendor_id": "0x10de", + "features": [ + "disable_delayed_copy_nv12" + ] } ], "comment": [
diff --git a/gpu/config/gpu_driver_bug_workaround_type.h b/gpu/config/gpu_driver_bug_workaround_type.h index 5b0f4eb..f252881 100644 --- a/gpu/config/gpu_driver_bug_workaround_type.h +++ b/gpu/config/gpu_driver_bug_workaround_type.h
@@ -51,6 +51,8 @@ disable_chromium_framebuffer_multisample) \ GPU_OP(DISABLE_D3D11, \ disable_d3d11) \ + GPU_OP(DISABLE_DELAYED_COPY_NV12, \ + disable_delayed_copy_nv12) \ GPU_OP(DISABLE_DEPTH_TEXTURE, \ disable_depth_texture) \ GPU_OP(DISABLE_DIRECT_COMPOSITION, \
diff --git a/ios/OWNERS b/ios/OWNERS index 0fbae9fe..a5fae73 100644 --- a/ios/OWNERS +++ b/ios/OWNERS
@@ -4,6 +4,9 @@ rohitrao@chromium.org sdefresne@chromium.org +# US-Pacific backup owner when no one on the above list is available +pkl@chromium.org + # per-file rules: # These are for the common case of adding or renaming files. If you're doing # structural changes, please get a review from a reviewer in this file.
diff --git a/ios/chrome/browser/ui/payments/address_edit_coordinator.mm b/ios/chrome/browser/ui/payments/address_edit_coordinator.mm index 9ac3976..37e6d22 100644 --- a/ios/chrome/browser/ui/payments/address_edit_coordinator.mm +++ b/ios/chrome/browser/ui/payments/address_edit_coordinator.mm
@@ -7,11 +7,14 @@ #include "base/guid.h" #include "base/logging.h" #include "base/strings/sys_string_conversions.h" +#include "components/autofill/core/browser/autofill_country.h" #include "components/autofill/core/browser/autofill_profile.h" #include "components/autofill/core/browser/personal_data_manager.h" +#include "components/autofill/core/browser/validation.h" #include "components/autofill/core/common/autofill_constants.h" #include "components/payments/core/payments_profile_comparator.h" #include "components/strings/grit/components_strings.h" +#include "ios/chrome/browser/application_context.h" #include "ios/chrome/browser/payments/payment_request.h" #import "ios/chrome/browser/ui/autofill/autofill_ui_type_util.h" #import "ios/chrome/browser/ui/payments/address_edit_mediator.h" @@ -82,7 +85,22 @@ - (NSString*)paymentRequestEditViewController: (PaymentRequestEditViewController*)controller validateField:(EditorField*)field { - if (!field.value.length && field.isRequired) { + if (field.value.length) { + switch (field.autofillUIType) { + case AutofillUITypeProfileHomePhoneWholeNumber: { + const std::string selectedCountryCode = + base::SysNSStringToUTF8(self.mediator.selectedCountryCode); + if (!autofill::IsValidPhoneNumber(base::SysNSStringToUTF16(field.value), + selectedCountryCode)) { + return l10n_util::GetNSString( + IDS_PAYMENTS_PHONE_INVALID_VALIDATION_MESSAGE); + } + break; + } + default: + break; + } + } else if (field.isRequired) { return l10n_util::GetNSString( IDS_PAYMENTS_FIELD_REQUIRED_VALIDATION_MESSAGE); }
diff --git a/media/gpu/dxva_video_decode_accelerator_win.cc b/media/gpu/dxva_video_decode_accelerator_win.cc index 47b9343..764a7c2 100644 --- a/media/gpu/dxva_video_decode_accelerator_win.cc +++ b/media/gpu/dxva_video_decode_accelerator_win.cc
@@ -501,6 +501,9 @@ !workarounds.disable_dxgi_zero_copy_video), support_copy_nv12_textures_(gpu_preferences.enable_nv12_dxgi_video && !workarounds.disable_nv12_dxgi_video), + support_delayed_copy_nv12_textures_( + base::FeatureList::IsEnabled(kDelayCopyNV12Textures) && + !workarounds.disable_delayed_copy_nv12), use_dx11_(false), use_keyed_mutex_(false), using_angle_device_(false), @@ -3053,8 +3056,7 @@ return PictureBufferMechanism::COPY_TO_RGB; if (support_share_nv12_textures_) return PictureBufferMechanism::BIND; - if (base::FeatureList::IsEnabled(kDelayCopyNV12Textures) && - support_copy_nv12_textures_) + if (support_delayed_copy_nv12_textures_ && support_copy_nv12_textures_) return PictureBufferMechanism::DELAYED_COPY_TO_NV12; if (support_copy_nv12_textures_) return PictureBufferMechanism::COPY_TO_NV12;
diff --git a/media/gpu/dxva_video_decode_accelerator_win.h b/media/gpu/dxva_video_decode_accelerator_win.h index 69aee2a..006f188 100644 --- a/media/gpu/dxva_video_decode_accelerator_win.h +++ b/media/gpu/dxva_video_decode_accelerator_win.h
@@ -549,6 +549,9 @@ // ANGLE. bool support_copy_nv12_textures_; + // Supports copying NV12 textures on the main thread to use in ANGLE. + bool support_delayed_copy_nv12_textures_; + // Copy video to FP16 scRGB textures. bool use_fp16_ = false;
diff --git a/net/http/bidirectional_stream_unittest.cc b/net/http/bidirectional_stream_unittest.cc index 037a21e..7a7407ed 100644 --- a/net/http/bidirectional_stream_unittest.cc +++ b/net/http/bidirectional_stream_unittest.cc
@@ -1658,7 +1658,7 @@ ASSERT_EQ(1u, alternative_service_info_vector.size()); AlternativeService alternative_service(kProtoQUIC, "www.example.org", 443); EXPECT_EQ(alternative_service, - alternative_service_info_vector[0].alternative_service); + alternative_service_info_vector[0].alternative_service()); } } // namespace net
diff --git a/net/http/http_network_transaction_unittest.cc b/net/http/http_network_transaction_unittest.cc index 0056e9f..c5a32fe 100644 --- a/net/http/http_network_transaction_unittest.cc +++ b/net/http/http_network_transaction_unittest.cc
@@ -10110,7 +10110,7 @@ ASSERT_EQ(1u, alternative_service_info_vector.size()); AlternativeService alternative_service(kProtoHTTP2, "mail.example.org", 443); EXPECT_EQ(alternative_service, - alternative_service_info_vector[0].alternative_service); + alternative_service_info_vector[0].alternative_service()); } // Regression test for https://crbug.com/615497. @@ -10352,11 +10352,11 @@ AlternativeService alternative_service(kProtoHTTP2, "www.example.com", 443); EXPECT_EQ(alternative_service, - alternative_service_info_vector[0].alternative_service); + alternative_service_info_vector[0].alternative_service()); AlternativeService alternative_service_2(kProtoHTTP2, "www.example.org", 1234); EXPECT_EQ(alternative_service_2, - alternative_service_info_vector[1].alternative_service); + alternative_service_info_vector[1].alternative_service()); } TEST_F(HttpNetworkTransactionTest, IdentifyQuicBroken) { @@ -10543,7 +10543,7 @@ http_server_properties->GetAlternativeServiceInfos(server); ASSERT_EQ(1u, alternative_service_info_vector.size()); EXPECT_EQ(alternative_service, - alternative_service_info_vector[0].alternative_service); + alternative_service_info_vector[0].alternative_service()); EXPECT_TRUE( http_server_properties->IsAlternativeServiceBroken(alternative_service)); }
diff --git a/net/http/http_server_properties.cc b/net/http/http_server_properties.cc index 386a00d0..15947b2 100644 --- a/net/http/http_server_properties.cc +++ b/net/http/http_server_properties.cc
@@ -78,6 +78,25 @@ return false; } +AlternativeServiceInfo::AlternativeServiceInfo() : alternative_service_() {} + +AlternativeServiceInfo::AlternativeServiceInfo( + const AlternativeService& alternative_service, + base::Time expiration) + : alternative_service_(alternative_service), expiration_(expiration) {} + +AlternativeServiceInfo::AlternativeServiceInfo(NextProto protocol, + const std::string& host, + uint16_t port, + base::Time expiration) + : alternative_service_(protocol, host, port), expiration_(expiration) {} + +AlternativeServiceInfo::AlternativeServiceInfo( + const AlternativeServiceInfo& alternative_service_info) = default; + +AlternativeServiceInfo& AlternativeServiceInfo::operator=( + const AlternativeServiceInfo& alternative_service_info) = default; + std::string AlternativeService::ToString() const { return base::StringPrintf("%s %s:%d", NextProtoToString(protocol), host.c_str(), port); @@ -85,10 +104,10 @@ std::string AlternativeServiceInfo::ToString() const { base::Time::Exploded exploded; - expiration.LocalExplode(&exploded); + expiration_.LocalExplode(&exploded); return base::StringPrintf( "%s, expires %04d-%02d-%02d %02d:%02d:%02d", - alternative_service.ToString().c_str(), exploded.year, exploded.month, + alternative_service_.ToString().c_str(), exploded.year, exploded.month, exploded.day_of_month, exploded.hour, exploded.minute, exploded.second); }
diff --git a/net/http/http_server_properties.h b/net/http/http_server_properties.h index fc19d24..27d8b07 100644 --- a/net/http/http_server_properties.h +++ b/net/http/http_server_properties.h
@@ -114,28 +114,26 @@ std::ostream& os, const AlternativeService& alternative_service); -struct NET_EXPORT AlternativeServiceInfo { - AlternativeServiceInfo() : alternative_service() {} +class NET_EXPORT_PRIVATE AlternativeServiceInfo { + public: + AlternativeServiceInfo(); AlternativeServiceInfo(const AlternativeService& alternative_service, - base::Time expiration) - : alternative_service(alternative_service), - expiration(expiration) {} + base::Time expiration); AlternativeServiceInfo(NextProto protocol, const std::string& host, uint16_t port, - base::Time expiration) - : alternative_service(protocol, host, port), expiration(expiration) {} + base::Time expiration); AlternativeServiceInfo( - const AlternativeServiceInfo& alternative_service_info) = default; + const AlternativeServiceInfo& alternative_service_info); AlternativeServiceInfo& operator=( - const AlternativeServiceInfo& alternative_service_info) = default; + const AlternativeServiceInfo& alternative_service_info); bool operator==(const AlternativeServiceInfo& other) const { - return alternative_service == other.alternative_service && - expiration == other.expiration; + return alternative_service_ == other.alternative_service() && + expiration_ == other.expiration(); } bool operator!=(const AlternativeServiceInfo& other) const { @@ -144,8 +142,31 @@ std::string ToString() const; - AlternativeService alternative_service; - base::Time expiration; + void set_alternative_service(const AlternativeService& alternative_service) { + alternative_service_ = alternative_service; + } + + void set_protocol(const NextProto& protocol) { + alternative_service_.protocol = protocol; + } + + void set_host(const std::string& host) { alternative_service_.host = host; } + + void set_port(uint16_t port) { alternative_service_.port = port; } + + void set_expiration(const base::Time& expiration) { + expiration_ = expiration; + } + + const AlternativeService& alternative_service() const { + return alternative_service_; + } + + base::Time expiration() const { return expiration_; } + + private: + AlternativeService alternative_service_; + base::Time expiration_; }; struct NET_EXPORT SupportsQuic {
diff --git a/net/http/http_server_properties_impl.cc b/net/http/http_server_properties_impl.cc index 4220ce2d..4140e1d 100644 --- a/net/http/http_server_properties_impl.cc +++ b/net/http/http_server_properties_impl.cc
@@ -222,7 +222,7 @@ GetAlternativeServiceInfos(server); for (const AlternativeServiceInfo& alternative_service_info : alternative_service_info_vector) { - if (alternative_service_info.alternative_service.protocol == kProtoQUIC) { + if (alternative_service_info.alternative_service().protocol == kProtoQUIC) { return true; } } @@ -307,11 +307,11 @@ HostPortPair host_port_pair(origin.host(), origin.port()); for (AlternativeServiceInfoVector::iterator it = map_it->second.begin(); it != map_it->second.end();) { - if (it->expiration < now) { + if (it->expiration() < now) { it = map_it->second.erase(it); continue; } - AlternativeService alternative_service(it->alternative_service); + AlternativeService alternative_service(it->alternative_service()); if (alternative_service.host.empty()) { alternative_service.host = origin.host(); } @@ -323,7 +323,7 @@ continue; } valid_alternative_service_infos.push_back( - AlternativeServiceInfo(alternative_service, it->expiration)); + AlternativeServiceInfo(alternative_service, it->expiration())); ++it; } if (map_it->second.empty()) { @@ -342,11 +342,11 @@ } for (AlternativeServiceInfoVector::iterator it = map_it->second.begin(); it != map_it->second.end();) { - if (it->expiration < now) { + if (it->expiration() < now) { it = map_it->second.erase(it); continue; } - AlternativeService alternative_service(it->alternative_service); + AlternativeService alternative_service(it->alternative_service()); if (alternative_service.host.empty()) { alternative_service.host = canonical->second.host(); if (IsAlternativeServiceBroken(alternative_service)) { @@ -359,7 +359,7 @@ continue; } valid_alternative_service_infos.push_back( - AlternativeServiceInfo(alternative_service, it->expiration)); + AlternativeServiceInfo(alternative_service, it->expiration())); ++it; } if (map_it->second.empty()) { @@ -402,14 +402,14 @@ for (const auto& old : it->second) { // Persist to disk immediately if new entry has different scheme, host, // or port. - if (old.alternative_service != new_it->alternative_service) { + if (old.alternative_service() != new_it->alternative_service()) { changed = true; break; } // Also persist to disk if new expiration it more that twice as far or // less than half as far in the future. - base::Time old_time = old.expiration; - base::Time new_time = new_it->expiration; + base::Time old_time = old.expiration(); + base::Time new_time = new_it->expiration(); if (new_time - now > 2 * (old_time - now) || 2 * (new_time - now) < (old_time - now)) { changed = true; @@ -494,7 +494,7 @@ std::string alternative_service_string( alternative_service_info.ToString()); AlternativeService alternative_service( - alternative_service_info.alternative_service); + alternative_service_info.alternative_service()); if (alternative_service.host.empty()) { alternative_service.host = server.host(); } @@ -630,7 +630,7 @@ for (const AlternativeServiceInfo& alternative_service_info : it->second) { AlternativeService alternative_service( - alternative_service_info.alternative_service); + alternative_service_info.alternative_service()); if (alternative_service.host.empty()) { alternative_service.host = canonical_server.host(); } @@ -677,7 +677,7 @@ map_it != alternative_service_map_.end();) { for (AlternativeServiceInfoVector::iterator it = map_it->second.begin(); it != map_it->second.end();) { - AlternativeService alternative_service(it->alternative_service); + AlternativeService alternative_service(it->alternative_service()); // Empty hostname in map means hostname of key: substitute before // comparing to |expired_alternative_service|. if (alternative_service.host.empty()) {
diff --git a/net/http/http_server_properties_impl_unittest.cc b/net/http/http_server_properties_impl_unittest.cc index 46cd0df..a144e67 100644 --- a/net/http/http_server_properties_impl_unittest.cc +++ b/net/http/http_server_properties_impl_unittest.cc
@@ -379,7 +379,7 @@ impl_.GetAlternativeServiceInfos(test_server); ASSERT_EQ(1u, alternative_service_info_vector.size()); EXPECT_EQ(alternative_service, - alternative_service_info_vector[0].alternative_service); + alternative_service_info_vector[0].alternative_service()); impl_.Clear(); EXPECT_FALSE(HasAlternativeService(test_server)); @@ -475,18 +475,18 @@ EXPECT_TRUE(map_it->first.Equals(test_server2)); ASSERT_EQ(1u, map_it->second.size()); - EXPECT_EQ(alternative_service3, map_it->second[0].alternative_service); - EXPECT_EQ(expiration3, map_it->second[0].expiration); + EXPECT_EQ(alternative_service3, map_it->second[0].alternative_service()); + EXPECT_EQ(expiration3, map_it->second[0].expiration()); ++map_it; EXPECT_TRUE(map_it->first.Equals(test_server1)); ASSERT_EQ(1u, map_it->second.size()); - EXPECT_EQ(alternative_service1, map_it->second[0].alternative_service); - EXPECT_EQ(expiration1, map_it->second[0].expiration); + EXPECT_EQ(alternative_service1, map_it->second[0].alternative_service()); + EXPECT_EQ(expiration1, map_it->second[0].expiration()); ++map_it; EXPECT_TRUE(map_it->first.Equals(test_server3)); ASSERT_EQ(1u, map_it->second.size()); - EXPECT_EQ(alternative_service4, map_it->second[0].alternative_service); - EXPECT_EQ(expiration4, map_it->second[0].expiration); + EXPECT_EQ(alternative_service4, map_it->second[0].alternative_service()); + EXPECT_EQ(expiration4, map_it->second[0].expiration()); } // Regression test for https://crbug.com/504032: @@ -511,7 +511,7 @@ impl_.GetAlternativeServiceInfos(server); ASSERT_EQ(1u, alternative_service_info_vector.size()); EXPECT_EQ(alternative_service_with_foo_hostname, - alternative_service_info_vector[0].alternative_service); + alternative_service_info_vector[0].alternative_service()); } // Regression test for https://crbug.com/516486: @@ -600,8 +600,8 @@ impl_.GetAlternativeServiceInfos(server); ASSERT_EQ(1u, alternative_service_info_vector.size()); EXPECT_EQ(kProtoQUIC, - alternative_service_info_vector[0].alternative_service.protocol); - EXPECT_EQ(443, alternative_service_info_vector[0].alternative_service.port); + alternative_service_info_vector[0].alternative_service().protocol); + EXPECT_EQ(443, alternative_service_info_vector[0].alternative_service().port); // Now clear the alternatives for the other server and make sure it stays // cleared. @@ -624,19 +624,19 @@ AlternativeServiceMap::const_iterator it = map.begin(); EXPECT_TRUE(it->first.Equals(test_server2)); ASSERT_EQ(1u, it->second.size()); - EXPECT_EQ(alternative_service2, it->second[0].alternative_service); + EXPECT_EQ(alternative_service2, it->second[0].alternative_service()); const AlternativeServiceInfoVector alternative_service_info_vector = impl_.GetAlternativeServiceInfos(test_server1); ASSERT_EQ(1u, alternative_service_info_vector.size()); EXPECT_EQ(alternative_service1, - alternative_service_info_vector[0].alternative_service); + alternative_service_info_vector[0].alternative_service()); // GetAlternativeServices should reorder the AlternateProtocol map. it = map.begin(); EXPECT_TRUE(it->first.Equals(test_server1)); ASSERT_EQ(1u, it->second.size()); - EXPECT_EQ(alternative_service1, it->second[0].alternative_service); + EXPECT_EQ(alternative_service1, it->second[0].alternative_service()); } TEST_F(AlternateProtocolServerPropertiesTest, SetBroken) { @@ -647,7 +647,7 @@ impl_.GetAlternativeServiceInfos(test_server); ASSERT_EQ(1u, alternative_service_info_vector.size()); EXPECT_EQ(alternative_service1, - alternative_service_info_vector[0].alternative_service); + alternative_service_info_vector[0].alternative_service()); EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service1)); // GetAlternativeServiceInfos should return the broken alternative service. @@ -656,7 +656,7 @@ impl_.GetAlternativeServiceInfos(test_server); ASSERT_EQ(1u, alternative_service_info_vector.size()); EXPECT_EQ(alternative_service1, - alternative_service_info_vector[0].alternative_service); + alternative_service_info_vector[0].alternative_service()); EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service1)); // SetAlternativeServices should add a broken alternative service to the map. @@ -672,9 +672,9 @@ impl_.GetAlternativeServiceInfos(test_server); ASSERT_EQ(2u, alternative_service_info_vector.size()); EXPECT_EQ(alternative_service1, - alternative_service_info_vector[0].alternative_service); + alternative_service_info_vector[0].alternative_service()); EXPECT_EQ(alternative_service2, - alternative_service_info_vector[1].alternative_service); + alternative_service_info_vector[1].alternative_service()); EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service1)); EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service2)); @@ -684,7 +684,7 @@ impl_.GetAlternativeServiceInfos(test_server); ASSERT_EQ(1u, alternative_service_info_vector.size()); EXPECT_EQ(alternative_service1, - alternative_service_info_vector[0].alternative_service); + alternative_service_info_vector[0].alternative_service()); EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service1)); } @@ -712,7 +712,7 @@ impl_.GetAlternativeServiceInfos(test_server); ASSERT_EQ(1u, alternative_service_info_vector2.size()); EXPECT_EQ(alternative_service2, - alternative_service_info_vector2[0].alternative_service); + alternative_service_info_vector2[0].alternative_service()); } TEST_F(AlternateProtocolServerPropertiesTest, MaxAgeCanonical) { @@ -741,7 +741,7 @@ impl_.GetAlternativeServiceInfos(test_server); ASSERT_EQ(1u, alternative_service_info_vector2.size()); EXPECT_EQ(alternative_service2, - alternative_service_info_vector2[0].alternative_service); + alternative_service_info_vector2[0].alternative_service()); } TEST_F(AlternateProtocolServerPropertiesTest, AlternativeServiceWithScheme) { @@ -761,8 +761,8 @@ net::AlternativeServiceMap::const_iterator it = map.begin(); EXPECT_TRUE(it->first.Equals(http_server)); ASSERT_EQ(2u, it->second.size()); - EXPECT_EQ(alternative_service1, it->second[0].alternative_service); - EXPECT_EQ(alternative_service2, it->second[1].alternative_service); + EXPECT_EQ(alternative_service1, it->second[0].alternative_service()); + EXPECT_EQ(alternative_service2, it->second[1].alternative_service()); // Check Alt-Svc list should not be set for |https_server|. url::SchemeHostPort https_server("https", "foo", 80); @@ -796,8 +796,8 @@ net::AlternativeServiceMap::const_iterator it = map.begin(); EXPECT_TRUE(it->first.Equals(test_server)); ASSERT_EQ(2u, it->second.size()); - EXPECT_EQ(alternative_service1, it->second[0].alternative_service); - EXPECT_EQ(alternative_service2, it->second[1].alternative_service); + EXPECT_EQ(alternative_service1, it->second[0].alternative_service()); + EXPECT_EQ(alternative_service2, it->second[1].alternative_service()); impl_.SetAlternativeServices(test_server, AlternativeServiceInfoVector()); EXPECT_TRUE(map.empty()); @@ -817,7 +817,7 @@ impl_.GetAlternativeServiceInfos(test_server); ASSERT_EQ(1u, alternative_service_info_vector.size()); EXPECT_EQ(canonical_alternative_service, - alternative_service_info_vector[0].alternative_service); + alternative_service_info_vector[0].alternative_service()); const AlternativeService broken_alternative_service(kProtoHTTP2, "foo", 443); impl_.MarkAlternativeServiceBroken(broken_alternative_service); @@ -828,7 +828,7 @@ impl_.GetAlternativeServiceInfos(test_server); ASSERT_EQ(1u, alternative_service_info_vector.size()); EXPECT_EQ(broken_alternative_service, - alternative_service_info_vector[0].alternative_service); + alternative_service_info_vector[0].alternative_service()); EXPECT_TRUE(impl_.IsAlternativeServiceBroken(broken_alternative_service)); } @@ -887,17 +887,17 @@ impl_.GetAlternativeServiceInfos(test_server); ASSERT_EQ(2u, alternative_service_info_vector2.size()); EXPECT_EQ(canonical_alternative_service1, - alternative_service_info_vector2[0].alternative_service); + alternative_service_info_vector2[0].alternative_service()); // Since |canonical_alternative_service2| has an empty host, // GetAlternativeServiceInfos should substitute the hostname of its |origin| // argument. EXPECT_EQ(test_server.host(), - alternative_service_info_vector2[1].alternative_service.host); + alternative_service_info_vector2[1].alternative_service().host); EXPECT_EQ(canonical_alternative_service2.protocol, - alternative_service_info_vector2[1].alternative_service.protocol); + alternative_service_info_vector2[1].alternative_service().protocol); EXPECT_EQ(canonical_alternative_service2.port, - alternative_service_info_vector2[1].alternative_service.port); + alternative_service_info_vector2[1].alternative_service().port); // Verify the canonical suffix. EXPECT_EQ(".c.youtube.com", *impl_.GetCanonicalSuffix(test_server.host())); @@ -939,7 +939,7 @@ impl_.GetAlternativeServiceInfos(foo_server); ASSERT_EQ(1u, alternative_service_info_vector.size()); EXPECT_EQ(bar_alternative_service, - alternative_service_info_vector[0].alternative_service); + alternative_service_info_vector[0].alternative_service()); url::SchemeHostPort qux_server("https", "qux.c.youtube.com", 443); AlternativeService qux_alternative_service(kProtoQUIC, "qux.c.youtube.com", @@ -949,7 +949,7 @@ impl_.GetAlternativeServiceInfos(foo_server); ASSERT_EQ(1u, alternative_service_info_vector.size()); EXPECT_EQ(qux_alternative_service, - alternative_service_info_vector[0].alternative_service); + alternative_service_info_vector[0].alternative_service()); } TEST_F(AlternateProtocolServerPropertiesTest, ClearWithCanonical) {
diff --git a/net/http/http_server_properties_manager.cc b/net/http/http_server_properties_manager.cc index 95ef2f4..6a4aaaa 100644 --- a/net/http/http_server_properties_manager.cc +++ b/net/http/http_server_properties_manager.cc
@@ -587,17 +587,18 @@ << server_str; return false; } - alternative_service_info->alternative_service.protocol = protocol; + alternative_service_info->set_protocol(protocol); // Host is optional, defaults to "". - alternative_service_info->alternative_service.host.clear(); + std::string host = ""; if (alternative_service_dict.HasKey(kHostKey) && - !alternative_service_dict.GetStringWithoutPathExpansion( - kHostKey, &(alternative_service_info->alternative_service.host))) { + !alternative_service_dict.GetStringWithoutPathExpansion(kHostKey, + &host)) { DVLOG(1) << "Malformed alternative service host string for server: " << server_str; return false; } + alternative_service_info->set_host(host); // Port is mandatory. int port = 0; @@ -606,14 +607,13 @@ DVLOG(1) << "Malformed alternative service port for server: " << server_str; return false; } - alternative_service_info->alternative_service.port = - static_cast<uint32_t>(port); + alternative_service_info->set_port(static_cast<uint32_t>(port)); // Expiration is optional, defaults to one day. base::Time expiration; if (!alternative_service_dict.HasKey(kExpirationKey)) { - alternative_service_info->expiration = - base::Time::Now() + base::TimeDelta::FromDays(1); + alternative_service_info->set_expiration(base::Time::Now() + + base::TimeDelta::FromDays(1)); return true; } @@ -626,8 +626,8 @@ << server_str; return false; } - alternative_service_info->expiration = - base::Time::FromInternalValue(expiration_int64); + alternative_service_info->set_expiration( + base::Time::FromInternalValue(expiration_int64)); return true; } @@ -663,7 +663,7 @@ &alternative_service_info)) { return false; } - if (base::Time::Now() < alternative_service_info.expiration) { + if (base::Time::Now() < alternative_service_info.expiration()) { alternative_service_info_vector.push_back(alternative_service_info); } } @@ -858,11 +858,11 @@ AlternativeServiceInfoVector notbroken_alternative_service_info_vector; for (const AlternativeServiceInfo& alternative_service_info : it->second) { // Do not persist expired entries. - if (alternative_service_info.expiration < base::Time::Now()) { + if (alternative_service_info.expiration() < base::Time::Now()) { continue; } AlternativeService alternative_service( - alternative_service_info.alternative_service); + alternative_service_info.alternative_service()); if (!IsAlternateProtocolValid(alternative_service.protocol)) { continue; } @@ -1072,7 +1072,7 @@ for (const AlternativeServiceInfo& alternative_service_info : *alternative_service_info_vector) { const AlternativeService alternative_service = - alternative_service_info.alternative_service; + alternative_service_info.alternative_service(); DCHECK(IsAlternateProtocolValid(alternative_service.protocol)); std::unique_ptr<base::DictionaryValue> alternative_service_dict( new base::DictionaryValue); @@ -1086,7 +1086,7 @@ alternative_service_dict->SetString( kExpirationKey, base::Int64ToString( - alternative_service_info.expiration.ToInternalValue())); + alternative_service_info.expiration().ToInternalValue())); alternative_service_list->Append(std::move(alternative_service_dict)); } if (alternative_service_list->GetSize() == 0)
diff --git a/net/http/http_server_properties_manager_unittest.cc b/net/http/http_server_properties_manager_unittest.cc index b10b337..4460fa76 100644 --- a/net/http/http_server_properties_manager_unittest.cc +++ b/net/http/http_server_properties_manager_unittest.cc
@@ -414,18 +414,18 @@ AlternativeServiceMap::const_iterator map_it = map.begin(); EXPECT_EQ("mail.google.com", map_it->first.host()); ASSERT_EQ(1u, map_it->second.size()); - EXPECT_EQ(kProtoHTTP2, map_it->second[0].alternative_service.protocol); - EXPECT_TRUE(map_it->second[0].alternative_service.host.empty()); - EXPECT_EQ(444, map_it->second[0].alternative_service.port); + EXPECT_EQ(kProtoHTTP2, map_it->second[0].alternative_service().protocol); + EXPECT_TRUE(map_it->second[0].alternative_service().host.empty()); + EXPECT_EQ(444, map_it->second[0].alternative_service().port); ++map_it; EXPECT_EQ("www.google.com", map_it->first.host()); ASSERT_EQ(2u, map_it->second.size()); - EXPECT_EQ(kProtoHTTP2, map_it->second[0].alternative_service.protocol); - EXPECT_TRUE(map_it->second[0].alternative_service.host.empty()); - EXPECT_EQ(443, map_it->second[0].alternative_service.port); - EXPECT_EQ(kProtoQUIC, map_it->second[1].alternative_service.protocol); - EXPECT_TRUE(map_it->second[1].alternative_service.host.empty()); - EXPECT_EQ(1234, map_it->second[1].alternative_service.port); + EXPECT_EQ(kProtoHTTP2, map_it->second[0].alternative_service().protocol); + EXPECT_TRUE(map_it->second[0].alternative_service().host.empty()); + EXPECT_EQ(443, map_it->second[0].alternative_service().port); + EXPECT_EQ(kProtoQUIC, map_it->second[1].alternative_service().protocol); + EXPECT_TRUE(map_it->second[1].alternative_service().host.empty()); + EXPECT_EQ(1234, map_it->second[1].alternative_service().port); } else { const AlternativeServiceMap& map = http_server_props_manager_->alternative_service_map(); @@ -433,18 +433,18 @@ AlternativeServiceMap::const_iterator map_it = map.begin(); EXPECT_EQ("www.google.com", map_it->first.host()); ASSERT_EQ(2u, map_it->second.size()); - EXPECT_EQ(kProtoHTTP2, map_it->second[0].alternative_service.protocol); - EXPECT_TRUE(map_it->second[0].alternative_service.host.empty()); - EXPECT_EQ(443, map_it->second[0].alternative_service.port); - EXPECT_EQ(kProtoQUIC, map_it->second[1].alternative_service.protocol); - EXPECT_TRUE(map_it->second[1].alternative_service.host.empty()); - EXPECT_EQ(1234, map_it->second[1].alternative_service.port); + EXPECT_EQ(kProtoHTTP2, map_it->second[0].alternative_service().protocol); + EXPECT_TRUE(map_it->second[0].alternative_service().host.empty()); + EXPECT_EQ(443, map_it->second[0].alternative_service().port); + EXPECT_EQ(kProtoQUIC, map_it->second[1].alternative_service().protocol); + EXPECT_TRUE(map_it->second[1].alternative_service().host.empty()); + EXPECT_EQ(1234, map_it->second[1].alternative_service().port); ++map_it; EXPECT_EQ("mail.google.com", map_it->first.host()); ASSERT_EQ(1u, map_it->second.size()); - EXPECT_EQ(kProtoHTTP2, map_it->second[0].alternative_service.protocol); - EXPECT_TRUE(map_it->second[0].alternative_service.host.empty()); - EXPECT_EQ(444, map_it->second[0].alternative_service.port); + EXPECT_EQ(kProtoHTTP2, map_it->second[0].alternative_service().protocol); + EXPECT_TRUE(map_it->second[0].alternative_service().host.empty()); + EXPECT_EQ(444, map_it->second[0].alternative_service().port); } // Verify SupportsQuic. @@ -749,7 +749,7 @@ http_server_props_manager_->GetAlternativeServiceInfos(spdy_server_mail); ASSERT_EQ(1u, alternative_service_info_vector.size()); EXPECT_EQ(alternative_service, - alternative_service_info_vector[0].alternative_service); + alternative_service_info_vector[0].alternative_service()); } TEST_P(HttpServerPropertiesManagerTest, SetAlternativeServices) { @@ -788,9 +788,9 @@ http_server_props_manager_->GetAlternativeServiceInfos(spdy_server_mail); ASSERT_EQ(2u, alternative_service_info_vector2.size()); EXPECT_EQ(alternative_service1, - alternative_service_info_vector2[0].alternative_service); + alternative_service_info_vector2[0].alternative_service()); EXPECT_EQ(alternative_service2, - alternative_service_info_vector2[1].alternative_service); + alternative_service_info_vector2[1].alternative_service()); } TEST_P(HttpServerPropertiesManagerTest, SetAlternativeServicesEmpty) { @@ -1145,9 +1145,10 @@ AlternativeServiceInfoVector alternative_service_info_vector = http_server_props_manager_->GetAlternativeServiceInfos(server); ASSERT_EQ(1u, alternative_service_info_vector.size()); - EXPECT_EQ(kProtoQUIC, - alternative_service_info_vector[0].alternative_service.protocol); - EXPECT_EQ(i, alternative_service_info_vector[0].alternative_service.port); + EXPECT_EQ( + kProtoQUIC, + alternative_service_info_vector[0].alternative_service().protocol); + EXPECT_EQ(i, alternative_service_info_vector[0].alternative_service().port); } // Verify SupportsQuic. @@ -1294,31 +1295,33 @@ ASSERT_EQ(3u, alternative_service_info_vector.size()); EXPECT_EQ(kProtoHTTP2, - alternative_service_info_vector[0].alternative_service.protocol); - EXPECT_EQ("", alternative_service_info_vector[0].alternative_service.host); - EXPECT_EQ(443, alternative_service_info_vector[0].alternative_service.port); + alternative_service_info_vector[0].alternative_service().protocol); + EXPECT_EQ("", alternative_service_info_vector[0].alternative_service().host); + EXPECT_EQ(443, alternative_service_info_vector[0].alternative_service().port); // Expiration defaults to one day from now, testing with tolerance. const base::Time now = base::Time::Now(); - const base::Time expiration = alternative_service_info_vector[0].expiration; + const base::Time expiration = alternative_service_info_vector[0].expiration(); EXPECT_LE(now + base::TimeDelta::FromHours(23), expiration); EXPECT_GE(now + base::TimeDelta::FromDays(1), expiration); EXPECT_EQ(kProtoQUIC, - alternative_service_info_vector[1].alternative_service.protocol); - EXPECT_EQ("", alternative_service_info_vector[1].alternative_service.host); - EXPECT_EQ(123, alternative_service_info_vector[1].alternative_service.port); + alternative_service_info_vector[1].alternative_service().protocol); + EXPECT_EQ("", alternative_service_info_vector[1].alternative_service().host); + EXPECT_EQ(123, alternative_service_info_vector[1].alternative_service().port); // numeric_limits<int64_t>::max() represents base::Time::Max(). - EXPECT_EQ(base::Time::Max(), alternative_service_info_vector[1].expiration); + EXPECT_EQ(base::Time::Max(), alternative_service_info_vector[1].expiration()); EXPECT_EQ(kProtoHTTP2, - alternative_service_info_vector[2].alternative_service.protocol); + alternative_service_info_vector[2].alternative_service().protocol); EXPECT_EQ("example.org", - alternative_service_info_vector[2].alternative_service.host); - EXPECT_EQ(1234, alternative_service_info_vector[2].alternative_service.port); + alternative_service_info_vector[2].alternative_service().host); + EXPECT_EQ(1234, + alternative_service_info_vector[2].alternative_service().port); base::Time expected_expiration; ASSERT_TRUE( base::Time::FromUTCString("2036-12-31 10:00:00", &expected_expiration)); - EXPECT_EQ(expected_expiration, alternative_service_info_vector[2].expiration); + EXPECT_EQ(expected_expiration, + alternative_service_info_vector[2].expiration()); } // Regression test for https://crbug.com/615497. @@ -1459,11 +1462,11 @@ ASSERT_EQ(1u, alternative_service_info_vector.size()); EXPECT_EQ(kProtoHTTP2, - alternative_service_info_vector[0].alternative_service.protocol); + alternative_service_info_vector[0].alternative_service().protocol); EXPECT_EQ("valid.example.com", - alternative_service_info_vector[0].alternative_service.host); - EXPECT_EQ(443, alternative_service_info_vector[0].alternative_service.port); - EXPECT_EQ(one_day_from_now_, alternative_service_info_vector[0].expiration); + alternative_service_info_vector[0].alternative_service().host); + EXPECT_EQ(443, alternative_service_info_vector[0].alternative_service().port); + EXPECT_EQ(one_day_from_now_, alternative_service_info_vector[0].expiration()); } TEST_P(HttpServerPropertiesManagerTest, ShutdownWithPendingUpdateCache0) {
diff --git a/net/http/http_stream_factory_impl_job_controller.cc b/net/http/http_stream_factory_impl_job_controller.cc index a4575e09..69209d4 100644 --- a/net/http/http_stream_factory_impl_job_controller.cc +++ b/net/http/http_stream_factory_impl_job_controller.cc
@@ -771,7 +771,7 @@ // Create an alternative job if alternative service is set up for this domain. const AlternativeService alternative_service = GetAlternativeServiceInfoFor(request_info_, delegate_, stream_type_) - .alternative_service; + .alternative_service(); if (is_preconnect_) { // Due to how the socket pools handle priorities and idle sockets, only IDLE @@ -1031,19 +1031,20 @@ AlternativeServiceInfo alternative_service_info = GetAlternativeServiceInfoInternal(request_info, delegate, stream_type); AlternativeServiceType type; - if (alternative_service_info.alternative_service.protocol == kProtoUnknown) { + if (alternative_service_info.alternative_service().protocol == + kProtoUnknown) { type = NO_ALTERNATIVE_SERVICE; - } else if (alternative_service_info.alternative_service.protocol == + } else if (alternative_service_info.alternative_service().protocol == kProtoQUIC) { if (request_info.url.host_piece() == - alternative_service_info.alternative_service.host) { + alternative_service_info.alternative_service().host) { type = QUIC_SAME_DESTINATION; } else { type = QUIC_DIFFERENT_DESTINATION; } } else { if (request_info.url.host_piece() == - alternative_service_info.alternative_service.host) { + alternative_service_info.alternative_service().host) { type = NOT_QUIC_SAME_DESTINATION; } else { type = NOT_QUIC_DIFFERENT_DESTINATION; @@ -1081,12 +1082,12 @@ for (const AlternativeServiceInfo& alternative_service_info : alternative_service_info_vector) { DCHECK(IsAlternateProtocolValid( - alternative_service_info.alternative_service.protocol)); + alternative_service_info.alternative_service().protocol)); if (!quic_advertised && - alternative_service_info.alternative_service.protocol == kProtoQUIC) + alternative_service_info.alternative_service().protocol == kProtoQUIC) quic_advertised = true; if (http_server_properties.IsAlternativeServiceBroken( - alternative_service_info.alternative_service)) { + alternative_service_info.alternative_service())) { HistogramAlternateProtocolUsage(ALTERNATE_PROTOCOL_USAGE_BROKEN, false); continue; } @@ -1099,24 +1100,25 @@ // allow protocol upgrades to user-controllable ports. const int kUnrestrictedPort = 1024; if (!session_->params().enable_user_alternate_protocol_ports && - (alternative_service_info.alternative_service.port >= + (alternative_service_info.alternative_service().port >= kUnrestrictedPort && origin.port() < kUnrestrictedPort)) continue; - if (alternative_service_info.alternative_service.protocol == kProtoHTTP2) { + if (alternative_service_info.alternative_service().protocol == + kProtoHTTP2) { if (!session_->params().enable_http2_alternative_service) continue; // Cache this entry if we don't have a non-broken Alt-Svc yet. - if (first_alternative_service_info.alternative_service.protocol == + if (first_alternative_service_info.alternative_service().protocol == kProtoUnknown) first_alternative_service_info = alternative_service_info; continue; } DCHECK_EQ(kProtoQUIC, - alternative_service_info.alternative_service.protocol); + alternative_service_info.alternative_service().protocol); quic_all_broken = false; if (!session_->IsQuicEnabled()) continue; @@ -1135,7 +1137,7 @@ QuicServerId server_id(mapped_origin, request_info.privacy_mode); HostPortPair destination( - alternative_service_info.alternative_service.host_port_pair()); + alternative_service_info.alternative_service().host_port_pair()); ignore_result(ApplyHostMappingRules(original_url, &destination)); if (session_->quic_stream_factory()->CanUseExistingSession(server_id, @@ -1144,7 +1146,7 @@ } // Cache this entry if we don't have a non-broken Alt-Svc yet. - if (first_alternative_service_info.alternative_service.protocol == + if (first_alternative_service_info.alternative_service().protocol == kProtoUnknown) first_alternative_service_info = alternative_service_info; }
diff --git a/net/http/http_stream_factory_impl_job_controller_unittest.cc b/net/http/http_stream_factory_impl_job_controller_unittest.cc index cf7e526a5..4160bc8 100644 --- a/net/http/http_stream_factory_impl_job_controller_unittest.cc +++ b/net/http/http_stream_factory_impl_job_controller_unittest.cc
@@ -266,7 +266,7 @@ EXPECT_EQ(1u, alternative_service_info_vector.size()); EXPECT_EQ(should_mark_broken, session_->http_server_properties()->IsAlternativeServiceBroken( - alternative_service_info_vector[0].alternative_service)); + alternative_service_info_vector[0].alternative_service())); } TestJobFactory job_factory_;
diff --git a/net/quic/chromium/quic_network_transaction_unittest.cc b/net/quic/chromium/quic_network_transaction_unittest.cc index 0d56c1d4..19412bc 100644 --- a/net/quic/chromium/quic_network_transaction_unittest.cc +++ b/net/quic/chromium/quic_network_transaction_unittest.cc
@@ -633,7 +633,7 @@ http_server_properties_.GetAlternativeServiceInfos(server); EXPECT_EQ(1u, alternative_service_info_vector.size()); EXPECT_TRUE(http_server_properties_.IsAlternativeServiceBroken( - alternative_service_info_vector[0].alternative_service)); + alternative_service_info_vector[0].alternative_service())); } void ExpectQuicAlternateProtocolMapping() { @@ -641,10 +641,11 @@ const AlternativeServiceInfoVector alternative_service_info_vector = http_server_properties_.GetAlternativeServiceInfos(server); EXPECT_EQ(1u, alternative_service_info_vector.size()); - EXPECT_EQ(kProtoQUIC, - alternative_service_info_vector[0].alternative_service.protocol); + EXPECT_EQ( + kProtoQUIC, + alternative_service_info_vector[0].alternative_service().protocol); EXPECT_FALSE(http_server_properties_.IsAlternativeServiceBroken( - alternative_service_info_vector[0].alternative_service)); + alternative_service_info_vector[0].alternative_service())); } void AddHangingNonAlternateProtocolSocketData() { @@ -2997,7 +2998,7 @@ http_server_properties_.GetAlternativeServiceInfos(http_server); ASSERT_EQ(1u, alternative_service_info_vector.size()); const AlternativeService alternative_service = - alternative_service_info_vector[0].alternative_service; + alternative_service_info_vector[0].alternative_service(); EXPECT_EQ(kProtoQUIC, alternative_service.protocol); EXPECT_EQ(kDefaultServerHostName, alternative_service.host); EXPECT_EQ(137, alternative_service.port);
diff --git a/net/spdy/chromium/spdy_session_unittest.cc b/net/spdy/chromium/spdy_session_unittest.cc index ce7b9dd..7033354 100644 --- a/net/spdy/chromium/spdy_session_unittest.cc +++ b/net/spdy/chromium/spdy_session_unittest.cc
@@ -5654,7 +5654,7 @@ ASSERT_EQ(1u, altsvc_info_vector.size()); AlternativeService alternative_service(kProtoQUIC, "alternative.example.org", 443u); - EXPECT_EQ(alternative_service, altsvc_info_vector[0].alternative_service); + EXPECT_EQ(alternative_service, altsvc_info_vector[0].alternative_service()); } TEST_F(AltSvcFrameTest, DoNotProcessAltSvcFrameOnInsecureSession) { @@ -5797,10 +5797,10 @@ spdy_session_pool_->http_server_properties()->GetAlternativeServiceInfos( url::SchemeHostPort(GURL(request_origin))); ASSERT_EQ(1u, altsvc_info_vector.size()); - EXPECT_EQ(kProtoQUIC, altsvc_info_vector[0].alternative_service.protocol); + EXPECT_EQ(kProtoQUIC, altsvc_info_vector[0].alternative_service().protocol); EXPECT_EQ("alternative.example.org", - altsvc_info_vector[0].alternative_service.host); - EXPECT_EQ(443u, altsvc_info_vector[0].alternative_service.port); + altsvc_info_vector[0].alternative_service().host); + EXPECT_EQ(443u, altsvc_info_vector[0].alternative_service().port); } TEST_F(AltSvcFrameTest, DoNotProcessAltSvcFrameOnStreamWithInsecureOrigin) {
diff --git a/remoting/proto/BUILD.gn b/remoting/proto/BUILD.gn index 64e0f23..b1c520aa 100644 --- a/remoting/proto/BUILD.gn +++ b/remoting/proto/BUILD.gn
@@ -19,6 +19,7 @@ "internal.proto", "mux.proto", "process_stats.proto", + "test.proto", "video.proto", "video_stats.proto", ]
diff --git a/remoting/proto/test.proto b/remoting/proto/test.proto new file mode 100644 index 0000000..c02f408 --- /dev/null +++ b/remoting/proto/test.proto
@@ -0,0 +1,17 @@ +// 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. + +// Protocol for test only. + +syntax = "proto2"; + +option optimize_for = LITE_RUNTIME; + +package remoting.protocol; + +// The proto for DataChannelManager test cases. +// Next Id: 2 +message DataChannelManagerTestProto { + optional int32 data = 1; +}
diff --git a/remoting/protocol/BUILD.gn b/remoting/protocol/BUILD.gn index f495575..b38627d 100644 --- a/remoting/protocol/BUILD.gn +++ b/remoting/protocol/BUILD.gn
@@ -49,6 +49,8 @@ "content_description.cc", "content_description.h", "datagram_channel_factory.h", + "data_channel_manager.cc", + "data_channel_manager.h", "errors.cc", "errors.h", "frame_consumer.h", @@ -104,6 +106,8 @@ "monitored_video_stub.h", "mouse_input_filter.cc", "mouse_input_filter.h", + "named_message_pipe_handler.cc", + "named_message_pipe_handler.h", "negotiating_authenticator_base.cc", "negotiating_authenticator_base.h", "negotiating_client_authenticator.cc", @@ -266,6 +270,10 @@ "fake_connection_to_host.h", "fake_datagram_socket.cc", "fake_datagram_socket.h", + "fake_message_pipe.cc", + "fake_message_pipe.h", + "fake_message_pipe_wrapper.cc", + "fake_message_pipe_wrapper.h", "fake_session.cc", "fake_session.h", "fake_stream_socket.cc", @@ -309,6 +317,7 @@ "connection_tester.cc", "connection_tester.h", "content_description_unittest.cc", + "data_channel_manager_unittest.cc", "http_ice_config_request_unittest.cc", "ice_config_unittest.cc", "ice_transport_unittest.cc",
diff --git a/remoting/protocol/data_channel_manager.cc b/remoting/protocol/data_channel_manager.cc new file mode 100644 index 0000000..c8f0782 --- /dev/null +++ b/remoting/protocol/data_channel_manager.cc
@@ -0,0 +1,39 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "remoting/protocol/data_channel_manager.h" + +#include <utility> + +#include "base/logging.h" +#include "remoting/protocol/message_pipe.h" + +namespace remoting { +namespace protocol { + +DataChannelManager::DataChannelManager() = default; +DataChannelManager::~DataChannelManager() = default; + +void DataChannelManager::RegisterCreateHandlerCallback( + const std::string& prefix, + CreateHandlerCallback constructor) { + DCHECK(!prefix.empty()); + DCHECK(constructor); + constructors_.push_back(std::make_pair(prefix, constructor)); +} + +bool DataChannelManager::OnIncomingDataChannel( + const std::string& name, + std::unique_ptr<MessagePipe> pipe) { + for (auto& constructor : constructors_) { + if (name.find(constructor.first) == 0) { + constructor.second.Run(name, std::move(pipe)); + return true; + } + } + return false; +} + +} // namespace protocol +} // namespace remoting
diff --git a/remoting/protocol/data_channel_manager.h b/remoting/protocol/data_channel_manager.h new file mode 100644 index 0000000..32b0198 --- /dev/null +++ b/remoting/protocol/data_channel_manager.h
@@ -0,0 +1,47 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef REMOTING_PROTOCOL_DATA_CHANNEL_MANAGER_H_ +#define REMOTING_PROTOCOL_DATA_CHANNEL_MANAGER_H_ + +#include <memory> +#include <string> +#include <vector> + +#include "base/callback.h" + +namespace remoting { +namespace protocol { + +class MessagePipe; + +// DataChannelManager helps to manage optional data channels. Consumers can +// register a function to handle data from a named data channel. +class DataChannelManager final { + public: + using CreateHandlerCallback = base::Callback<void( + const std::string& name, + std::unique_ptr<MessagePipe> pipe)>; + + DataChannelManager(); + ~DataChannelManager(); + + // Registers a factory function to handle a new incoming data channel with a + // name matching |prefix|. Both |constructor| and |prefix| cannot be empty. + void RegisterCreateHandlerCallback(const std::string& prefix, + CreateHandlerCallback constructor); + + // Executes the registered callback to handle the new incoming data channel. + // Returns true if a handler of the new data channel has been executed. + bool OnIncomingDataChannel(const std::string& name, + std::unique_ptr<MessagePipe> pipe); + + private: + std::vector<std::pair<std::string, CreateHandlerCallback>> constructors_; +}; + +} // namespace protocol +} // namespace remoting + +#endif // REMOTING_PROTOCOL_DATA_CHANNEL_MANAGER_H_
diff --git a/remoting/protocol/data_channel_manager_unittest.cc b/remoting/protocol/data_channel_manager_unittest.cc new file mode 100644 index 0000000..52fdfc5f4 --- /dev/null +++ b/remoting/protocol/data_channel_manager_unittest.cc
@@ -0,0 +1,267 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "remoting/protocol/data_channel_manager.h" + +#include <map> +#include <utility> + +#include "base/bind.h" +#include "base/memory/ptr_util.h" +#include "base/message_loop/message_loop.h" +#include "base/run_loop.h" +#include "remoting/base/compound_buffer.h" +#include "remoting/proto/test.pb.h" +#include "remoting/protocol/fake_message_pipe.h" +#include "remoting/protocol/fake_message_pipe_wrapper.h" +#include "remoting/protocol/named_message_pipe_handler.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace remoting { +namespace protocol { + +namespace { + +class FakeNamedMessagePipeHandler final : public NamedMessagePipeHandler { + public: + FakeNamedMessagePipeHandler(const std::string& name, + std::unique_ptr<MessagePipe> pipe, + const std::string& expected_data) + : NamedMessagePipeHandler(name, std::move(pipe)), + expected_data_(expected_data) { + handlers_[name] = this; + } + + int received_message_count() const { return received_message_count_; } + + static FakeNamedMessagePipeHandler* Find(const std::string& name); + + static int instance_count() { return handlers_.size(); } + + // NamedMessagePipeHandler implementation. + void OnIncomingMessage(std::unique_ptr<CompoundBuffer> message) override; + + // Public functions for test cases. + void Close() { NamedMessagePipeHandler::Close(); } + + bool connected() const { return NamedMessagePipeHandler::connected(); } + + void Send(google::protobuf::MessageLite* message, + const base::Closure& done); + + protected: + ~FakeNamedMessagePipeHandler() override { + EXPECT_EQ(handlers_.erase(pipe_name()), 1U); + } + + private: + static std::map<std::string, FakeNamedMessagePipeHandler*> handlers_; + + const std::string expected_data_; + int received_message_count_ = 0; +}; + +void FakeNamedMessagePipeHandler::OnIncomingMessage( + std::unique_ptr<CompoundBuffer> message) { + ASSERT_TRUE(message != nullptr); + std::string content; + content.resize(expected_data_.size()); + message->CopyTo(&(content[0]), content.size()); + ASSERT_EQ(content, expected_data_); + received_message_count_++; +} + +// static +FakeNamedMessagePipeHandler* FakeNamedMessagePipeHandler::Find( + const std::string& name) { + auto it = handlers_.find(name); + if (it == handlers_.end()) { + return nullptr; + } + return it->second; +} + +void FakeNamedMessagePipeHandler::Send(google::protobuf::MessageLite* message, + const base::Closure& done) { + if (connected()) { + NamedMessagePipeHandler::Send(message, done); + return; + } +#if DCHECK_IS_ON() + ASSERT_DEATH_IF_SUPPORTED( + NamedMessagePipeHandler::Send(message, done), + "connected"); +#else + NamedMessagePipeHandler::Send(message, done); +#endif +} + +// static +std::map<std::string, FakeNamedMessagePipeHandler*> +FakeNamedMessagePipeHandler::handlers_; + +void TestDataChannelManagerFullMatch(bool asynchronous) { + base::MessageLoop message_loop; + DataChannelManager manager; + manager.RegisterCreateHandlerCallback("FullMatch", base::Bind( + [](const std::string& expected_data, + const std::string& name, + std::unique_ptr<MessagePipe> pipe) -> void { + new FakeNamedMessagePipeHandler(name, std::move(pipe), expected_data); + }, + "FullMatchContent")); + manager.RegisterCreateHandlerCallback("AnotherFullMatch", base::Bind( + [](const std::string& expected_data, + const std::string& name, + std::unique_ptr<MessagePipe> pipe) -> void { + new FakeNamedMessagePipeHandler(name, std::move(pipe), expected_data); + }, + "AnotherFullMatchContent")); + + FakeMessagePipe pipe1(asynchronous); + FakeMessagePipe pipe2(asynchronous); + ASSERT_TRUE(manager.OnIncomingDataChannel("FullMatch", pipe1.Wrap())); + ASSERT_TRUE(manager.OnIncomingDataChannel("AnotherFullMatch", pipe2.Wrap())); + base::RunLoop().RunUntilIdle(); + + FakeNamedMessagePipeHandler* handler1 = + FakeNamedMessagePipeHandler::Find("FullMatch"); + FakeNamedMessagePipeHandler* handler2 = + FakeNamedMessagePipeHandler::Find("AnotherFullMatch"); + ASSERT_TRUE(handler1 != nullptr); + ASSERT_TRUE(handler2 != nullptr); + + pipe1.OpenPipe(); + base::RunLoop().RunUntilIdle(); + { + DataChannelManagerTestProto message; + int sent = 0; + base::Closure sent_callback = base::Bind([](int* sent) { + (*sent)++; + }, + base::Unretained(&sent)); + ASSERT_TRUE(handler1->connected()); + handler1->Send(&message, sent_callback); + ASSERT_FALSE(handler2->connected()); + handler2->Send(&message, sent_callback); + + base::RunLoop().RunUntilIdle(); + ASSERT_EQ(sent, 1); + } + + pipe2.OpenPipe(); + base::RunLoop().RunUntilIdle(); + { + DataChannelManagerTestProto message; + int sent = 0; + base::Closure sent_callback = base::Bind([](int* sent) { + (*sent)++; + }, + base::Unretained(&sent)); + ASSERT_TRUE(handler2->connected()); + + handler1->Send(&message, sent_callback); + handler2->Send(&message, sent_callback); + + base::RunLoop().RunUntilIdle(); + ASSERT_EQ(sent, 2); + } + + { + std::string content; + auto message = base::MakeUnique<CompoundBuffer>(); + content = "FullMatchContent"; + message->AppendCopyOf(&(content[0]), content.size()); + pipe1.Receive(std::move(message)); + + message = base::MakeUnique<CompoundBuffer>(); + content = "AnotherFullMatchContent"; + message->AppendCopyOf(&(content[0]), content.size()); + pipe2.Receive(std::move(message)); + + base::RunLoop().RunUntilIdle(); + ASSERT_EQ(handler1->received_message_count(), 1); + ASSERT_EQ(handler2->received_message_count(), 1); + } + + pipe2.ClosePipe(); + if (asynchronous) { + base::RunLoop().RunUntilIdle(); + } + ASSERT_TRUE(FakeNamedMessagePipeHandler::Find("AnotherFullMatch") == nullptr); + + handler1->Close(); + ASSERT_TRUE(FakeNamedMessagePipeHandler::Find("FullMatch") == nullptr); + + ASSERT_EQ(FakeNamedMessagePipeHandler::instance_count(), 0); +} + +void TestDataChannelManagerMultipleRegistrations(bool asynchronous) { + base::MessageLoop message_loop; + DataChannelManager manager; + manager.RegisterCreateHandlerCallback("FullMatch", base::Bind( + [](const std::string& expected_data, + const std::string& name, + std::unique_ptr<MessagePipe> pipe) -> void { + new FakeNamedMessagePipeHandler(name, std::move(pipe), expected_data); + }, + "FullMatchContent")); + manager.RegisterCreateHandlerCallback("Prefix-", base::Bind( + [](const std::string& expected_data, + const std::string& name, + std::unique_ptr<MessagePipe> pipe) -> void { + new FakeNamedMessagePipeHandler(name, std::move(pipe), expected_data); + }, + "PrefixMatchContent")); + + FakeMessagePipe pipe1(asynchronous); + FakeMessagePipe pipe2(asynchronous); + FakeMessagePipe pipe3(asynchronous); + FakeMessagePipe pipe4(asynchronous); + ASSERT_TRUE(manager.OnIncomingDataChannel("Prefix-1", pipe1.Wrap())); + ASSERT_TRUE(manager.OnIncomingDataChannel("Prefix-2", pipe2.Wrap())); + ASSERT_FALSE(manager.OnIncomingDataChannel( + "PrefixShouldNotMatch", pipe3.Wrap())); + ASSERT_TRUE(manager.OnIncomingDataChannel("FullMatch", pipe4.Wrap())); + base::RunLoop().RunUntilIdle(); + + FakeNamedMessagePipeHandler* handler1 = + FakeNamedMessagePipeHandler::Find("Prefix-1"); + FakeNamedMessagePipeHandler* handler2 = + FakeNamedMessagePipeHandler::Find("Prefix-2"); + FakeNamedMessagePipeHandler* handler3 = + FakeNamedMessagePipeHandler::Find("PrefixShouldNotMatch"); + FakeNamedMessagePipeHandler* handler4 = + FakeNamedMessagePipeHandler::Find("FullMatch"); + ASSERT_TRUE(handler1 != nullptr); + ASSERT_TRUE(handler2 != nullptr); + ASSERT_TRUE(handler3 == nullptr); + ASSERT_TRUE(handler4 != nullptr); + + handler1->Close(); + handler2->Close(); + handler4->Close(); + base::RunLoop().RunUntilIdle(); +} + +} // namespace + +TEST(DataChannelManagerTest, FullMatchWithSynchronousPipe) { + TestDataChannelManagerFullMatch(false); +} + +TEST(DataChannelManagerTest, FullMatchWithAsynchronousPipe) { + TestDataChannelManagerFullMatch(true); +} + +TEST(DataChannelManagerTest, MultipleRegistrationsWithSynchronousPipe) { + TestDataChannelManagerMultipleRegistrations(false); +} + +TEST(DataChannelManagerTest, MultipleRegistrationsWithAsynchronousPipe) { + TestDataChannelManagerMultipleRegistrations(true); +} + +} // namespace protocol +} // namespace remoting
diff --git a/remoting/protocol/fake_message_pipe.cc b/remoting/protocol/fake_message_pipe.cc new file mode 100644 index 0000000..3829786 --- /dev/null +++ b/remoting/protocol/fake_message_pipe.cc
@@ -0,0 +1,124 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "remoting/protocol/fake_message_pipe.h" + +#include "base/bind.h" +#include "base/location.h" +#include "base/memory/ptr_util.h" +#include "base/threading/thread_task_runner_handle.h" +#include "remoting/base/compound_buffer.h" +#include "remoting/protocol/fake_message_pipe_wrapper.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace remoting { +namespace protocol { + +FakeMessagePipe::FakeMessagePipe(bool asynchronous) + : asynchronous_(asynchronous) {} + +FakeMessagePipe::~FakeMessagePipe() = default; + +std::unique_ptr<FakeMessagePipeWrapper> FakeMessagePipe::Wrap() { + return base::MakeUnique<FakeMessagePipeWrapper>(this); +} + +void FakeMessagePipe::Start(EventHandler* event_handler) { + ASSERT_TRUE(event_handler_ == nullptr); + ASSERT_TRUE(event_handler != nullptr); + event_handler_ = event_handler; +} + +void FakeMessagePipe::Send(google::protobuf::MessageLite* message, + const base::Closure& done) { + if (asynchronous_) { + base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, + base::Bind([](FakeMessagePipe* me, + google::protobuf::MessageLite* message, + const base::Closure& done) { + me->SendImpl(message, done); + }, + base::Unretained(this), + base::Unretained(message), + done)); + return; + } + SendImpl(message, done); +} + +void FakeMessagePipe::Receive(std::unique_ptr<CompoundBuffer> message) { + if (asynchronous_) { + base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, + base::Bind([](FakeMessagePipe* me, + std::unique_ptr<CompoundBuffer> message) { + me->ReceiveImpl(std::move(message)); + }, + base::Unretained(this), + base::Passed(std::move(message)))); + return; + } + + ReceiveImpl(std::move(message)); +} + +void FakeMessagePipe::OpenPipe() { + if (asynchronous_) { + base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, base::Bind( + [](FakeMessagePipe* me) { + me->OpenPipeImpl(); + }, + base::Unretained(this))); + return; + } + + OpenPipeImpl(); +} + +void FakeMessagePipe::ClosePipe() { + if (asynchronous_) { + base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, base::Bind( + [](FakeMessagePipe* me) { + me->ClosePipeImpl(); + }, + base::Unretained(this))); + return; + } + + ClosePipeImpl(); +} + +void FakeMessagePipe::SendImpl( + google::protobuf::MessageLite* message, + const base::Closure& done) { + ASSERT_TRUE(pipe_opened_); + if (done) { + done.Run(); + } +} + +void FakeMessagePipe::ReceiveImpl(std::unique_ptr<CompoundBuffer> message) { + ASSERT_TRUE(pipe_opened_); + ASSERT_TRUE(event_handler_ != nullptr); + if (message) { + message->Lock(); + } + event_handler_->OnMessageReceived(std::move(message)); +} + +void FakeMessagePipe::OpenPipeImpl() { + ASSERT_FALSE(pipe_opened_); + ASSERT_TRUE(event_handler_ != nullptr); + pipe_opened_ = true; + event_handler_->OnMessagePipeOpen(); +} + +void FakeMessagePipe::ClosePipeImpl() { + ASSERT_TRUE(pipe_opened_); + ASSERT_TRUE(event_handler_ != nullptr); + pipe_opened_ = false; + event_handler_->OnMessagePipeClosed(); +} + +} // namespace protocol +} // namespace remoting
diff --git a/remoting/protocol/fake_message_pipe.h b/remoting/protocol/fake_message_pipe.h new file mode 100644 index 0000000..6be457b --- /dev/null +++ b/remoting/protocol/fake_message_pipe.h
@@ -0,0 +1,66 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef REMOTING_PROTOCOL_FAKE_MESSAGE_PIPE_H_ +#define REMOTING_PROTOCOL_FAKE_MESSAGE_PIPE_H_ + +#include <memory> + +#include "remoting/protocol/message_pipe.h" + +namespace google { +namespace protobuf { +class MessageLite; +} // namespace protobuf +} // namespace google + +namespace remoting { +namespace protocol { + +class FakeMessagePipeWrapper; + +class FakeMessagePipe final : public MessagePipe { + public: + explicit FakeMessagePipe(bool asynchronous); + ~FakeMessagePipe() override; + + // Creates an std::unique_ptr<FakeMessagePipeWrapper> instance to wrap |this|. + // All operations will be forwarded to |this| except for the destructor. + // + // Most of the components take ownership of std::unique_ptr<MessagePipe>, + // which makes the test cases hard to maintain the lifetime of a + // FakeMessagePipe. So this function creates a "weak" unique_ptr of this + // instance to let the test case decide the lifetime of a FakeMessagePipe. + std::unique_ptr<FakeMessagePipeWrapper> Wrap(); + + // MessagePipe implementation. + void Start(EventHandler* event_handler) override; + void Send(google::protobuf::MessageLite* message, + const base::Closure& done) override; + + // Forwards |message| to EventHandler. + void Receive(std::unique_ptr<CompoundBuffer> message); + + // Simulates the operation to open the pipe. + void OpenPipe(); + + // Simulates the operation to close the pipe. + void ClosePipe(); + + private: + void SendImpl(google::protobuf::MessageLite* message, + const base::Closure& done); + void ReceiveImpl(std::unique_ptr<CompoundBuffer> message); + void OpenPipeImpl(); + void ClosePipeImpl(); + + const bool asynchronous_; + bool pipe_opened_ = false; + EventHandler* event_handler_ = nullptr; +}; + +} // namespace protocol +} // namespace remoting + +#endif // REMOTING_PROTOCOL_FAKE_MESSAGE_PIPE_H_
diff --git a/remoting/protocol/fake_message_pipe_wrapper.cc b/remoting/protocol/fake_message_pipe_wrapper.cc new file mode 100644 index 0000000..7e1eafa --- /dev/null +++ b/remoting/protocol/fake_message_pipe_wrapper.cc
@@ -0,0 +1,45 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "remoting/protocol/fake_message_pipe_wrapper.h" + +#include <utility> + +#include "base/logging.h" +#include "remoting/base/compound_buffer.h" +#include "remoting/protocol/fake_message_pipe.h" + +namespace remoting { +namespace protocol { + +FakeMessagePipeWrapper::FakeMessagePipeWrapper(FakeMessagePipe* pipe) + : pipe_(pipe) { + DCHECK(pipe_); +} + +FakeMessagePipeWrapper::~FakeMessagePipeWrapper() = default; + +void FakeMessagePipeWrapper::Start(EventHandler* event_handler) { + pipe_->Start(event_handler); +} + +void FakeMessagePipeWrapper::Send(google::protobuf::MessageLite* message, + const base::Closure& done) { + pipe_->Send(message, done); +} + +void FakeMessagePipeWrapper::Receive(std::unique_ptr<CompoundBuffer> message) { + pipe_->Receive(std::move(message)); +} + +void FakeMessagePipeWrapper::OpenPipe() { + pipe_->OpenPipe(); +} + +void FakeMessagePipeWrapper::ClosePipe() { + pipe_->ClosePipe(); +} + +} // namespace protocol +} // namespace remoting
diff --git a/remoting/protocol/fake_message_pipe_wrapper.h b/remoting/protocol/fake_message_pipe_wrapper.h new file mode 100644 index 0000000..0ea4589 --- /dev/null +++ b/remoting/protocol/fake_message_pipe_wrapper.h
@@ -0,0 +1,46 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef REMOTING_PROTOCOL_FAKE_MESSAGE_PIPE_WRAPPER_H_ +#define REMOTING_PROTOCOL_FAKE_MESSAGE_PIPE_WRAPPER_H_ + +#include <memory> + +#include "remoting/protocol/message_pipe.h" + +namespace google { +namespace protobuf { +class MessageLite; +} // namespace protobuf +} // namespace google + +namespace remoting { +namespace protocol { + +class FakeMessagePipe; + +// This class should not be used explicitly: use FakeMessagePipe::Wrap(). +class FakeMessagePipeWrapper final : public MessagePipe { + public: + // |pipe| must outlive this instance. + explicit FakeMessagePipeWrapper(FakeMessagePipe* pipe); + ~FakeMessagePipeWrapper() override; + + // MessagePipe implementation. + void Start(EventHandler* event_handler) override; + void Send(google::protobuf::MessageLite* message, + const base::Closure& done) override; + + void Receive(std::unique_ptr<CompoundBuffer> message); + void OpenPipe(); + void ClosePipe(); + + private: + FakeMessagePipe* const pipe_; +}; + +} // namespace protocol +} // namespace remoting + +#endif // REMOTING_PROTOCOL_FAKE_MESSAGE_PIPE_WRAPPER_H_
diff --git a/remoting/protocol/named_message_pipe_handler.cc b/remoting/protocol/named_message_pipe_handler.cc new file mode 100644 index 0000000..4741d57 --- /dev/null +++ b/remoting/protocol/named_message_pipe_handler.cc
@@ -0,0 +1,69 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "remoting/protocol/named_message_pipe_handler.h" + +#include <utility> + +#include "base/location.h" +#include "base/logging.h" +#include "base/threading/thread_task_runner_handle.h" +#include "remoting/base/compound_buffer.h" + +namespace remoting { +namespace protocol { + +NamedMessagePipeHandler::NamedMessagePipeHandler( + const std::string& name, + std::unique_ptr<MessagePipe> pipe) + : name_(name), + pipe_(std::move(pipe)) { + DCHECK(pipe_); + pipe_->Start(this); +} + +NamedMessagePipeHandler::~NamedMessagePipeHandler() = default; + +void NamedMessagePipeHandler::Close() { + DCHECK(thread_checker_.CalledOnValidThread()); + if (connected()) { + OnDisconnecting(); + is_connected_ = false; + } + delete this; +} + +void NamedMessagePipeHandler::Send(google::protobuf::MessageLite* message, + const base::Closure& done) { + DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK(connected()); + pipe_->Send(message, done); +} + +void NamedMessagePipeHandler::OnIncomingMessage( + std::unique_ptr<CompoundBuffer> message) {} + +void NamedMessagePipeHandler::OnConnected() {} + +void NamedMessagePipeHandler::OnDisconnecting() {} + +void NamedMessagePipeHandler::OnMessagePipeOpen() { + DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK(!is_connected_); + is_connected_ = true; + OnConnected(); +} + +void NamedMessagePipeHandler::OnMessageReceived( + std::unique_ptr<CompoundBuffer> message) { + DCHECK(thread_checker_.CalledOnValidThread()); + OnIncomingMessage(std::move(message)); +} + +void NamedMessagePipeHandler::OnMessagePipeClosed() { + Close(); +} + +} // namespace protocol +} // namespace remoting
diff --git a/remoting/protocol/named_message_pipe_handler.h b/remoting/protocol/named_message_pipe_handler.h new file mode 100644 index 0000000..877b033 --- /dev/null +++ b/remoting/protocol/named_message_pipe_handler.h
@@ -0,0 +1,77 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef REMOTING_PROTOCOL_NAMED_MESSAGE_PIPE_HANDLER_H_ +#define REMOTING_PROTOCOL_NAMED_MESSAGE_PIPE_HANDLER_H_ + +#include <memory> +#include <string> + +#include "base/callback.h" +#include "base/sequenced_task_runner_helpers.h" +#include "base/threading/thread_checker.h" +#include "remoting/protocol/message_pipe.h" + +namespace google { +namespace protobuf { +class MessageLite; +} // namespace protobuf +} // namespace google + +namespace remoting { + +class CompoundBuffer; + +namespace protocol { + +// A base class to handle data from a named MessagePipe. This class manages the +// lifetime itself: it deletes itself once the MessagePipe is closed or the +// derived instance actively calls Close() function. +class NamedMessagePipeHandler : public MessagePipe::EventHandler { + protected: + // The callers should create instances of derived classes instead of this + // class. So hide the constructor. + NamedMessagePipeHandler(const std::string& name, + std::unique_ptr<MessagePipe> pipe); + + ~NamedMessagePipeHandler() override; + + // Closes the channel and eventually destructs this instance. No operations + // should be performed after executing this function. + void Close(); + + const std::string& pipe_name() const { return name_; } + + // Whether |pipe_| has been connected. + bool connected() const { return is_connected_; } + + // Sends the message through the pipe. This function should only be called + // once connected() returns true. + void Send(google::protobuf::MessageLite* message, const base::Closure& done); + + // Derived classes can override these functions to receive data from the + // connection or observe the connection state. These functions will not be + // called unless |pipe_| has been opened. + virtual void OnIncomingMessage(std::unique_ptr<CompoundBuffer> message); + virtual void OnConnected(); + virtual void OnDisconnecting(); + + private: + friend class base::DeleteHelper<NamedMessagePipeHandler>; + + // MessagePipe::EventHandler implementation. + void OnMessagePipeOpen() override; + void OnMessageReceived(std::unique_ptr<CompoundBuffer> message) override; + void OnMessagePipeClosed() override; + + const std::string name_; + std::unique_ptr<MessagePipe> pipe_; + base::ThreadChecker thread_checker_; + bool is_connected_ = false; +}; + +} // namespace protocol +} // namespace remoting + +#endif // REMOTING_PROTOCOL_NAMED_MESSAGE_PIPE_HANDLER_H_
diff --git a/remoting/protocol/webrtc_data_stream_adapter.h b/remoting/protocol/webrtc_data_stream_adapter.h index bb2a227..51a7825 100644 --- a/remoting/protocol/webrtc_data_stream_adapter.h +++ b/remoting/protocol/webrtc_data_stream_adapter.h
@@ -39,10 +39,6 @@ void OnStateChange() override; void OnMessage(const webrtc::DataBuffer& buffer) override; - void OnConnected(); - - void OnClosed(); - rtc::scoped_refptr<webrtc::DataChannelInterface> channel_; EventHandler* event_handler_ = nullptr;
diff --git a/services/ui/public/cpp/input_devices/BUILD.gn b/services/ui/public/cpp/input_devices/BUILD.gn index fa8f255..43a323de 100644 --- a/services/ui/public/cpp/input_devices/BUILD.gn +++ b/services/ui/public/cpp/input_devices/BUILD.gn
@@ -19,6 +19,17 @@ public_deps = [ "//services/ui/public/interfaces/input_devices", ] + + if (is_chromeos && use_ozone) { + sources += [ + "input_device_controller_client.cc", + "input_device_controller_client.h", + ] + public_deps += [ + "//services/ui/public/interfaces:constants", + "//ui/ozone", + ] + } } if (is_chromeos && use_ozone) {
diff --git a/services/ui/public/cpp/input_devices/input_device_controller_client.cc b/services/ui/public/cpp/input_devices/input_device_controller_client.cc new file mode 100644 index 0000000..2ac09d4 --- /dev/null +++ b/services/ui/public/cpp/input_devices/input_device_controller_client.cc
@@ -0,0 +1,140 @@ +// 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 "services/ui/public/cpp/input_devices/input_device_controller_client.h" + +#include <utility> + +#include "base/bind_helpers.h" +#include "base/memory/ptr_util.h" +#include "services/service_manager/public/cpp/connector.h" +#include "services/ui/public/interfaces/constants.mojom.h" + +namespace ui { + +InputDeviceControllerClient::InputDeviceControllerClient( + service_manager::Connector* connector, + const std::string& service_name) + : binding_(this) { + connector->BindInterface( + service_name.empty() ? mojom::kServiceName : service_name, + &input_device_controller_); + mojom::KeyboardDeviceObserverPtr ptr; + binding_.Bind(mojo::MakeRequest(&ptr)); + input_device_controller_->AddKeyboardDeviceObserver(std::move(ptr)); +} + +InputDeviceControllerClient::~InputDeviceControllerClient() = default; + +void InputDeviceControllerClient::GetHasMouse(GetHasMouseCallback callback) { + input_device_controller_->GetHasMouse(std::move(callback)); +} + +void InputDeviceControllerClient::GetHasTouchpad( + GetHasTouchpadCallback callback) { + input_device_controller_->GetHasTouchpad(std::move(callback)); +} + +bool InputDeviceControllerClient::IsCapsLockEnabled() { + return keyboard_device_state_.is_caps_lock_enabled; +} + +void InputDeviceControllerClient::SetCapsLockEnabled(bool enabled) { + keyboard_device_state_.is_caps_lock_enabled = enabled; + input_device_controller_->SetCapsLockEnabled(enabled); +} + +void InputDeviceControllerClient::SetNumLockEnabled(bool enabled) { + input_device_controller_->SetNumLockEnabled(enabled); +} + +bool InputDeviceControllerClient::IsAutoRepeatEnabled() { + return keyboard_device_state_.is_auto_repeat_enabled; +} + +void InputDeviceControllerClient::SetAutoRepeatEnabled(bool enabled) { + keyboard_device_state_.is_auto_repeat_enabled = enabled; + input_device_controller_->SetAutoRepeatEnabled(enabled); +} + +void InputDeviceControllerClient::SetAutoRepeatRate(base::TimeDelta delay, + base::TimeDelta interval) { + input_device_controller_->SetAutoRepeatRate(delay, interval); +} + +void InputDeviceControllerClient::SetKeyboardLayoutByName( + const std::string& layout_name) { + input_device_controller_->SetKeyboardLayoutByName(layout_name); +} + +void InputDeviceControllerClient::SetTouchpadSensitivity(int value) { + input_device_controller_->SetTouchpadSensitivity(value); +} + +void InputDeviceControllerClient::SetTapToClick(bool enable) { + input_device_controller_->SetTapToClick(enable); +} + +void InputDeviceControllerClient::SetThreeFingerClick(bool enable) { + input_device_controller_->SetThreeFingerClick(enable); +} + +void InputDeviceControllerClient::SetTapDragging(bool enable) { + input_device_controller_->SetTapDragging(enable); +} + +void InputDeviceControllerClient::SetNaturalScroll(bool enable) { + input_device_controller_->SetNaturalScroll(enable); +} + +void InputDeviceControllerClient::SetMouseSensitivity(int value) { + input_device_controller_->SetMouseSensitivity(value); +} + +void InputDeviceControllerClient::SetPrimaryButtonRight(bool right) { + input_device_controller_->SetPrimaryButtonRight(right); +} + +void InputDeviceControllerClient::GetTouchDeviceStatus( + GetTouchDeviceStatusCallback callback) { + input_device_controller_->GetTouchDeviceStatus(std::move(callback)); +} + +void InputDeviceControllerClient::GetTouchEventLog( + const base::FilePath& out_dir, + GetTouchEventLogCallback callback) { + input_device_controller_->GetTouchEventLog(out_dir, std::move(callback)); +} + +void InputDeviceControllerClient::SetTapToClickPaused(bool state) { + input_device_controller_->SetTapToClickPaused(state); +} + +void InputDeviceControllerClient::SetTouchscreensEnabled(bool enable) { + input_device_controller_->SetTouchscreensEnabled(enable); +} + +void InputDeviceControllerClient::SetInternalKeyboardFilter( + bool enable_filter, + const std::vector<DomCode>& allowed_keys) { + std::vector<uint32_t> transport_keys(allowed_keys.size()); + for (size_t i = 0; i < allowed_keys.size(); ++i) + transport_keys[i] = static_cast<uint32_t>(allowed_keys[i]); + input_device_controller_->SetInternalKeyboardFilter(enable_filter, + transport_keys); +} + +void InputDeviceControllerClient::SetInternalTouchpadEnabled( + bool enable, + SetInternalTouchpadEnabledCallback callback) { + input_device_controller_->SetInternalTouchpadEnabled(enable, + std::move(callback)); +} + +void InputDeviceControllerClient::OnKeyboardStateChanged( + mojom::KeyboardDeviceStatePtr state) { + keyboard_device_state_ = *state; +} + +} // namespace ui
diff --git a/services/ui/public/cpp/input_devices/input_device_controller_client.h b/services/ui/public/cpp/input_devices/input_device_controller_client.h new file mode 100644 index 0000000..8e710e96 --- /dev/null +++ b/services/ui/public/cpp/input_devices/input_device_controller_client.h
@@ -0,0 +1,93 @@ +// 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 SERVICES_UI_PUBLIC_CPP_INPUT_DEVICES_INPUT_DEVICE_CONTROLLER_CLIENT_H_ +#define SERVICES_UI_PUBLIC_CPP_INPUT_DEVICES_INPUT_DEVICE_CONTROLLER_CLIENT_H_ + +#include <string> + +#include "base/callback_forward.h" +#include "base/macros.h" +#include "mojo/public/cpp/bindings/binding.h" +#include "services/ui/public/interfaces/input_devices/input_device_controller.mojom.h" + +namespace base { +class FilePath; +} + +namespace service_manager { +class Connector; +} + +namespace ui { + +enum class DomCode; + +// InputDeviceControllerClient is mostly a call through to +// mojom::InputDeviceController. It does a minimal amount of caching and is +// itself a KeyboardDeviceObserver to maintain local keyboard state. +class InputDeviceControllerClient : public mojom::KeyboardDeviceObserver { + public: + // |service_Name| is the name of the service providing mojom::KeyboardDevice, + // generally use the default, unless a specific service is needed. + explicit InputDeviceControllerClient( + service_manager::Connector* connector, + const std::string& service_name = std::string()); + ~InputDeviceControllerClient() override; + + using GetHasMouseCallback = base::OnceCallback<void(bool)>; + void GetHasMouse(GetHasMouseCallback callback); + + using GetHasTouchpadCallback = base::OnceCallback<void(bool)>; + void GetHasTouchpad(GetHasTouchpadCallback callback); + + bool IsCapsLockEnabled(); + void SetCapsLockEnabled(bool enabled); + void SetNumLockEnabled(bool enabled); + bool IsAutoRepeatEnabled(); + void SetAutoRepeatEnabled(bool enabled); + void SetAutoRepeatRate(base::TimeDelta delay, base::TimeDelta interval); + void SetKeyboardLayoutByName(const std::string& layout_name); + void SetTouchpadSensitivity(int value); + void SetTapToClick(bool enabled); + void SetThreeFingerClick(bool enabled); + void SetTapDragging(bool enabled); + void SetNaturalScroll(bool enabled); + void SetMouseSensitivity(int value); + void SetPrimaryButtonRight(bool right); + + using GetTouchDeviceStatusCallback = + base::OnceCallback<void(const std::string&)>; + void GetTouchDeviceStatus(GetTouchDeviceStatusCallback callback); + + using GetTouchEventLogCallback = + base::OnceCallback<void(const std::vector<base::FilePath>&)>; + void GetTouchEventLog(const base::FilePath& out_dir, + GetTouchEventLogCallback callback); + void SetTapToClickPaused(bool state); + + void SetTouchscreensEnabled(bool enabled); + void SetInternalKeyboardFilter(bool enable_filter, + const std::vector<DomCode>& allowed_keys); + + // Sets whether the internal touch pad. Returns true if there is an internal + // touchpad. + using SetInternalTouchpadEnabledCallback = base::OnceCallback<void(bool)>; + void SetInternalTouchpadEnabled(bool enable, + SetInternalTouchpadEnabledCallback callback); + + private: + // mojom::KeyboardDeviceObserver: + void OnKeyboardStateChanged(mojom::KeyboardDeviceStatePtr state) override; + + mojom::InputDeviceControllerPtr input_device_controller_; + mojom::KeyboardDeviceState keyboard_device_state_; + mojo::Binding<mojom::KeyboardDeviceObserver> binding_; + + DISALLOW_COPY_AND_ASSIGN(InputDeviceControllerClient); +}; + +} // namespace ui + +#endif // SERVICES_UI_PUBLIC_CPP_INPUT_DEVICES_INPUT_DEVICE_CONTROLLER_CLIENT_H_
diff --git a/testing/buildbot/chromium.android.json b/testing/buildbot/chromium.android.json index e3ce448..dc1788a9 100644 --- a/testing/buildbot/chromium.android.json +++ b/testing/buildbot/chromium.android.json
@@ -2709,7 +2709,7 @@ } ], "expiration": 10800, - "hard_timeout": 600, + "hard_timeout": 1200, "output_links": [ { "link": [ @@ -7673,7 +7673,7 @@ } ], "expiration": 10800, - "hard_timeout": 60, + "hard_timeout": 120, "output_links": [ { "link": [ @@ -7714,7 +7714,7 @@ } ], "expiration": 10800, - "hard_timeout": 180, + "hard_timeout": 360, "output_links": [ { "link": [ @@ -7919,7 +7919,7 @@ } ], "expiration": 10800, - "hard_timeout": 60, + "hard_timeout": 120, "output_links": [ { "link": [
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index 5cd21e8..149ffb46 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -3085,7 +3085,7 @@ ], "experiments": [ { - "name": "Query", + "name": "QueryExperiment2", "params": { "translate-ranker-model-url": "https://www.gstatic.com/chrome/intelligence/assist/ranker/models/translate/2017/03/translate_ranker_model_20170329.pb.bin" }, @@ -3097,7 +3097,7 @@ ] }, { - "name": "Enforcement", + "name": "EnforcementExperiment2", "params": { "translate-ranker-model-url": "https://www.gstatic.com/chrome/intelligence/assist/ranker/models/translate/2017/03/translate_ranker_model_20170329.pb.bin" },
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-browser-side-navigation b/third_party/WebKit/LayoutTests/FlagExpectations/enable-browser-side-navigation index 3027b09..1517a8e 100644 --- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-browser-side-navigation +++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-browser-side-navigation
@@ -45,10 +45,6 @@ Bug(726178) virtual/mojo-loading/http/tests/security/mixedContent/redirect-http-to-https-iframe-in-main-frame.html [ Failure ] Bug(726178) virtual/mojo-loading/http/tests/security/mixedContent/redirect-https-to-http-iframe-in-main-frame.html [ Failure ] -# PlzNavigate: Navigation requests upgraded via upgrade-insecure-requests will not get reported -# See https://crbug.com/713388 -Bug(713388) external/wpt/content-security-policy/securitypolicyviolation/upgrade-insecure-requests-reporting.https.html [ Timeout ] - # ------------------------------------------------------------ # These tests are correct with PlzNavigate but not without it # ------------------------------------------------------------
diff --git a/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/securitypolicyviolation/upgrade-insecure-requests-reporting.https.html b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/securitypolicyviolation/upgrade-insecure-requests-reporting.https.html index 5a0bc7c8..692db02 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/securitypolicyviolation/upgrade-insecure-requests-reporting.https.html +++ b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/securitypolicyviolation/upgrade-insecure-requests-reporting.https.html
@@ -56,5 +56,37 @@ i.src = url; document.body.appendChild(i); }, "Upgraded iframe is reported"); + + async_test(t => { + // Load an HTTPS iframe, then navigate it to an HTTP URL and check that the HTTP URL is both upgraded and reported. + var url = generateURL(Host.SAME_ORIGIN, Protocol.SECURE, ResourceType.FRAME).url; + var navigate_to = generateURL(Host.CROSS_ORIGIN, Protocol.INSECURE, ResourceType.FRAME).url; + var upgraded = new URL(navigate_to); + upgraded.protocol = "https"; + + var i = document.createElement('iframe'); + var loaded = false; + var reported = false; + + window.addEventListener("message", t.step_func(e => { + if (e.source == i.contentWindow) { + if (e.data == (new URL(url)).origin) { + waitForViolation(window, "frame-src") + .then(t.step_func(e => { + reported = true; + if (loaded) + t.done(); + })); + i.contentWindow.location.href = navigate_to; + } else if (e.data == (new URL(upgraded)).origin) { + loaded = true; + if (reported) + t.done(); + } + } + })); + i.src = url; + document.body.appendChild(i); + }, "Navigated iframe is upgraded and reported"); </script> </html>
diff --git a/third_party/WebKit/Source/core/exported/WebRemoteFrameImpl.cpp b/third_party/WebKit/Source/core/exported/WebRemoteFrameImpl.cpp index 1748b82d..0892a9d 100644 --- a/third_party/WebKit/Source/core/exported/WebRemoteFrameImpl.cpp +++ b/third_party/WebKit/Source/core/exported/WebRemoteFrameImpl.cpp
@@ -147,57 +147,6 @@ NOTREACHED(); } -void WebRemoteFrameImpl::ExecuteScriptInIsolatedWorld( - int world_id, - const WebScriptSource* sources, - unsigned num_sources) { - NOTREACHED(); -} - -void WebRemoteFrameImpl::SetIsolatedWorldSecurityOrigin( - int world_id, - const WebSecurityOrigin&) { - NOTREACHED(); -} - -void WebRemoteFrameImpl::SetIsolatedWorldContentSecurityPolicy( - int world_id, - const WebString&) { - NOTREACHED(); -} - -void WebRemoteFrameImpl::CollectGarbage() { - NOTREACHED(); -} - -v8::Local<v8::Value> WebRemoteFrameImpl::ExecuteScriptAndReturnValue( - const WebScriptSource&) { - NOTREACHED(); - return v8::Local<v8::Value>(); -} - -void WebRemoteFrameImpl::ExecuteScriptInIsolatedWorld( - int world_id, - const WebScriptSource* sources_in, - unsigned num_sources, - WebVector<v8::Local<v8::Value>>* results) { - NOTREACHED(); -} - -v8::Local<v8::Value> WebRemoteFrameImpl::CallFunctionEvenIfScriptDisabled( - v8::Local<v8::Function>, - v8::Local<v8::Value>, - int argc, - v8::Local<v8::Value> argv[]) { - NOTREACHED(); - return v8::Local<v8::Value>(); -} - -v8::Local<v8::Context> WebRemoteFrameImpl::MainWorldScriptContext() const { - NOTREACHED(); - return v8::Local<v8::Context>(); -} - void WebRemoteFrameImpl::Reload(WebFrameLoadType) { NOTREACHED(); }
diff --git a/third_party/WebKit/Source/core/exported/WebRemoteFrameImpl.h b/third_party/WebKit/Source/core/exported/WebRemoteFrameImpl.h index 0792d9a..879f7d8 100644 --- a/third_party/WebKit/Source/core/exported/WebRemoteFrameImpl.h +++ b/third_party/WebKit/Source/core/exported/WebRemoteFrameImpl.h
@@ -45,27 +45,6 @@ WebDocument GetDocument() const override; WebPerformance Performance() const override; void DispatchUnloadEvent() override; - void ExecuteScriptInIsolatedWorld(int world_id, - const WebScriptSource* sources, - unsigned num_sources) override; - void SetIsolatedWorldSecurityOrigin(int world_id, - const WebSecurityOrigin&) override; - void SetIsolatedWorldContentSecurityPolicy(int world_id, - const WebString&) override; - void CollectGarbage() override; - v8::Local<v8::Value> ExecuteScriptAndReturnValue( - const WebScriptSource&) override; - void ExecuteScriptInIsolatedWorld( - int world_id, - const WebScriptSource* sources_in, - unsigned num_sources, - WebVector<v8::Local<v8::Value>>* results) override; - v8::Local<v8::Value> CallFunctionEvenIfScriptDisabled( - v8::Local<v8::Function>, - v8::Local<v8::Value>, - int argc, - v8::Local<v8::Value> argv[]) override; - v8::Local<v8::Context> MainWorldScriptContext() const override; void Reload(WebFrameLoadType) override; void ReloadWithOverrideURL(const WebURL& override_url, WebFrameLoadType) override;
diff --git a/third_party/WebKit/Source/core/frame/csp/CSPDirectiveList.cpp b/third_party/WebKit/Source/core/frame/csp/CSPDirectiveList.cpp index 281ca456..ed713dc3 100644 --- a/third_party/WebKit/Source/core/frame/csp/CSPDirectiveList.cpp +++ b/third_party/WebKit/Source/core/frame/csp/CSPDirectiveList.cpp
@@ -1395,6 +1395,11 @@ directive->ExposeForNavigationalChecks()}); } } + if (upgrade_insecure_requests_) { + directives.push_back(WebContentSecurityPolicyDirective{ + blink::WebString("upgrade-insecure-requests"), + WebContentSecurityPolicySourceList()}); + } policy.directives = directives; policy.report_endpoints = ReportEndpoints(); policy.header = Header();
diff --git a/third_party/WebKit/Source/core/frame/csp/CSPDirectiveList.h b/third_party/WebKit/Source/core/frame/csp/CSPDirectiveList.h index 667724a..ed3d0cd 100644 --- a/third_party/WebKit/Source/core/frame/csp/CSPDirectiveList.h +++ b/third_party/WebKit/Source/core/frame/csp/CSPDirectiveList.h
@@ -175,6 +175,7 @@ // * child-src // * frame-src // * form-action + // * upgrade-insecure-requests // The exported directives only contains sources that affect navigation. For // instance it doesn't contains 'unsafe-inline' or 'unsafe-eval' WebContentSecurityPolicy ExposeForNavigationalChecks() const;
diff --git a/third_party/WebKit/Source/core/inspector/InspectorWorkerAgent.cpp b/third_party/WebKit/Source/core/inspector/InspectorWorkerAgent.cpp index f1bb437..9c5c332 100644 --- a/third_party/WebKit/Source/core/inspector/InspectorWorkerAgent.cpp +++ b/third_party/WebKit/Source/core/inspector/InspectorWorkerAgent.cpp
@@ -91,6 +91,10 @@ return Response::OK(); } +Response InspectorWorkerAgent::setAttachToFrames(bool attach) { + return Response::OK(); +} + bool InspectorWorkerAgent::AutoAttachEnabled() { return state_->booleanProperty(WorkerAgentState::kAutoAttach, false); }
diff --git a/third_party/WebKit/Source/core/inspector/InspectorWorkerAgent.h b/third_party/WebKit/Source/core/inspector/InspectorWorkerAgent.h index 61fce17..28d0109c 100644 --- a/third_party/WebKit/Source/core/inspector/InspectorWorkerAgent.h +++ b/third_party/WebKit/Source/core/inspector/InspectorWorkerAgent.h
@@ -64,6 +64,7 @@ // Called from Dispatcher protocol::Response setAutoAttach(bool auto_attach, bool wait_for_debugger_on_start) override; + protocol::Response setAttachToFrames(bool attach) override; protocol::Response sendMessageToTarget(const String& target_id, const String& message) override;
diff --git a/third_party/WebKit/Source/core/inspector/inspector_protocol_config.json b/third_party/WebKit/Source/core/inspector/inspector_protocol_config.json index 4d8f70bb..84ae2db 100644 --- a/third_party/WebKit/Source/core/inspector/inspector_protocol_config.json +++ b/third_party/WebKit/Source/core/inspector/inspector_protocol_config.json
@@ -95,7 +95,7 @@ }, { "domain": "Target", - "include": ["setAutoAttach", "sendMessageToTarget"], + "include": ["setAutoAttach", "sendMessageToTarget", "setAttachToFrames"], "include_events": ["attachedToTarget", "detachedFromTarget", "receivedMessageFromTarget"] } ]
diff --git a/third_party/WebKit/Source/core/layout/LayoutGeometryMap.cpp b/third_party/WebKit/Source/core/layout/LayoutGeometryMap.cpp index bc3df43e..a134c04 100644 --- a/third_party/WebKit/Source/core/layout/LayoutGeometryMap.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutGeometryMap.cpp
@@ -68,7 +68,8 @@ !ancestor || (mapping_.size() && mapping_[0].layout_object_ == ancestor); #endif - for (int i = mapping_.size() - 1; i >= 0; --i) { + int i = mapping_.size() - 1; + for (; i >= 0; --i) { const LayoutGeometryMapStep& current_step = mapping_[i]; // If container is the root LayoutView (step 0) we want to apply its fixed @@ -111,9 +112,24 @@ current_step.offset_.Height(), accumulate); } - if (in_fixed && !current_step.offset_for_fixed_position_.IsZero()) { - DCHECK(current_step.layout_object_->IsLayoutView()); + if (in_fixed && current_step.layout_object_->IsLayoutView()) { transform_state.Move(current_step.offset_for_fixed_position_); + in_fixed = false; + } + } + + if (in_fixed) { + // In case we've not reached top ('ancestor' isn't top level view) either + // assure that 'ancestor' and object both fixed or apply fixed offset of + // the nearest containing view. + for (; i >= 0; --i) { + const LayoutGeometryMapStep& current_step = mapping_[i]; + if (current_step.flags_ & (kContainsFixedPosition | kIsFixedPosition)) + break; + if (current_step.layout_object_->IsLayoutView()) { + transform_state.Move(current_step.offset_for_fixed_position_); + break; + } } }
diff --git a/third_party/WebKit/Source/core/loader/FrameLoader.cpp b/third_party/WebKit/Source/core/loader/FrameLoader.cpp index add4ac6..d0bfe59 100644 --- a/third_party/WebKit/Source/core/loader/FrameLoader.cpp +++ b/third_party/WebKit/Source/core/loader/FrameLoader.cpp
@@ -66,7 +66,6 @@ #include "core/loader/FormSubmission.h" #include "core/loader/FrameLoadRequest.h" #include "core/loader/LinkLoader.h" -#include "core/loader/MixedContentChecker.h" #include "core/loader/NavigationScheduler.h" #include "core/loader/NetworkHintsInterface.h" #include "core/loader/ProgressTracker.h" @@ -1353,11 +1352,6 @@ RecordLatestRequiredCSP(); // Before modifying the request, check report-only CSP headers to give the // site owner a chance to learn about requests that need to be modified. - // - // TODO(estark): this doesn't work with --enable-browser-side-navigation, - // wherein 'frame-src' is checked in the browser process. Figure out what to - // do; maybe with browser-side navigation the upgrade should be happening in - // the browser process too. See also https://crbug.com/692595 Settings* settings = frame_->GetSettings(); MaybeCheckCSP( resource_request, navigation_type, frame_, navigation_policy, @@ -1599,6 +1593,12 @@ "1"); } + // PlzNavigate: Upgrading subframe requests is handled by the browser process. + Settings* settings = frame_->GetSettings(); + if (resource_request.GetFrameType() == WebURLRequest::kFrameTypeNested && + settings && settings->GetBrowserSideNavigationEnabled()) { + return; + } UpgradeInsecureRequest(resource_request, document); }
diff --git a/third_party/WebKit/Source/core/page/scrolling/ScrollingCoordinator.cpp b/third_party/WebKit/Source/core/page/scrolling/ScrollingCoordinator.cpp index 2e4683b..4c74d84 100644 --- a/third_party/WebKit/Source/core/page/scrolling/ScrollingCoordinator.cpp +++ b/third_party/WebKit/Source/core/page/scrolling/ScrollingCoordinator.cpp
@@ -598,10 +598,6 @@ LayoutGeometryMap& geometry_map, HashSet<const PaintLayer*>& layers_with_rects, LayerFrameMap& layer_child_frame_map) { - // If this layer is throttled, ignore it. - if (cur_layer->GetLayoutObject().GetFrameView() && - cur_layer->GetLayoutObject().GetFrameView()->ShouldThrottleRendering()) - return; // Project any rects for the current layer LayerHitTestRects::const_iterator layer_iter = layer_rects.find(cur_layer); if (layer_iter != layer_rects.end()) { @@ -664,6 +660,9 @@ if (map_iter != layer_child_frame_map.end()) { for (size_t i = 0; i < map_iter->value.size(); i++) { const LocalFrame* child_frame = map_iter->value[i]; + if (child_frame->ShouldThrottleRendering()) + continue; + const PaintLayer* child_layer = child_frame->View()->GetLayoutViewItem().Layer(); if (layers_with_rects.Contains(child_layer)) { @@ -685,6 +684,10 @@ GraphicsLayerHitTestRects& graphics_rects) { TRACE_EVENT0("input", "ScrollingCoordinator::projectRectsToGraphicsLayerSpace"); + + if (main_frame->ShouldThrottleRendering()) + return; + bool touch_handler_in_child_frame = false; // We have a set of rects per Layer, we need to map them to their bounding
diff --git a/third_party/WebKit/Source/devtools/front_end/sdk/TargetManager.js b/third_party/WebKit/Source/devtools/front_end/sdk/TargetManager.js index cc8ee55f..f7105c38 100644 --- a/third_party/WebKit/Source/devtools/front_end/sdk/TargetManager.js +++ b/third_party/WebKit/Source/devtools/front_end/sdk/TargetManager.js
@@ -522,7 +522,6 @@ var target = this._targetManager.createTarget( targetInfo.targetId, targetName, this._capabilitiesForType(targetInfo.type), this._createChildConnection.bind(this, this._targetAgent, targetInfo.targetId), this._parentTarget); - target[SDK.TargetManager._isWorkerSymbol] = targetInfo.type === 'worker'; // Only pause the new worker if debugging SW - we are going through the pause on start checkbox. if (!this._parentTarget.parentTarget() && Runtime.queryParam('isSharedWorker') && waitingForDebugger) { @@ -610,8 +609,6 @@ AvailableNodeTargetsChanged: Symbol('AvailableNodeTargetsChanged') }; -SDK.TargetManager._isWorkerSymbol = Symbol('SDK.TargetManager.IsWorker'); - /** * @interface */
diff --git a/third_party/WebKit/Source/devtools/front_end/ui/TextPrompt.js b/third_party/WebKit/Source/devtools/front_end/ui/TextPrompt.js index fc8404cb..8de1500d 100644 --- a/third_party/WebKit/Source/devtools/front_end/ui/TextPrompt.js +++ b/third_party/WebKit/Source/devtools/front_end/ui/TextPrompt.js
@@ -583,6 +583,9 @@ if (!node.isSelfOrDescendant(this._element)) return false; + if (this._ghostTextElement.isAncestor(node)) + return true; + if (node.nodeType === Node.TEXT_NODE && selectionRange.startOffset < node.nodeValue.length) return false;
diff --git a/third_party/WebKit/Source/devtools/front_end/ui/treeoutline.js b/third_party/WebKit/Source/devtools/front_end/ui/treeoutline.js index 4fafc44..43e5444f 100644 --- a/third_party/WebKit/Source/devtools/front_end/ui/treeoutline.js +++ b/third_party/WebKit/Source/devtools/front_end/ui/treeoutline.js
@@ -1008,13 +1008,15 @@ select(omitFocus, selectedByUser) { if (!this.treeOutline || !this.selectable || this.selected) return false; - - if (this.treeOutline.selectedTreeElement) - this.treeOutline.selectedTreeElement.deselect(); + // Wait to deselect this element so that focus only changes once + var lastSelected = this.treeOutline.selectedTreeElement; this.treeOutline.selectedTreeElement = null; - if (this.treeOutline._rootElement === this) + if (this.treeOutline._rootElement === this) { + if (lastSelected) + lastSelected.deselect(); return false; + } this.selected = true; @@ -1026,6 +1028,8 @@ this._listItemNode.classList.add('selected'); this.treeOutline.dispatchEventToListeners(UI.TreeOutline.Events.ElementSelected, this); + if (lastSelected) + lastSelected.deselect(); return this.onselect(selectedByUser); }
diff --git a/third_party/WebKit/Source/modules/indexeddb/IDBObjectStore.cpp b/third_party/WebKit/Source/modules/indexeddb/IDBObjectStore.cpp index ae56bd5..7b5031a 100644 --- a/third_party/WebKit/Source/modules/indexeddb/IDBObjectStore.cpp +++ b/third_party/WebKit/Source/modules/indexeddb/IDBObjectStore.cpp
@@ -516,7 +516,8 @@ index_ids.push_back(it.key); index_keys.push_back(keys); } - UMA_HISTOGRAM_MEMORY_KB("WebCore.IndexedDB.PutValueSize", + // Records 1KB to 1GB. + UMA_HISTOGRAM_COUNTS_1M("WebCore.IndexedDB.PutValueSize2", value_wrapper.DataLengthBeforeWrapInBytes() / 1024); IDBRequest* request = IDBRequest::Create(
diff --git a/third_party/WebKit/Source/modules/presentation/PresentationAvailability.cpp b/third_party/WebKit/Source/modules/presentation/PresentationAvailability.cpp index 81e0c28..8de53d79e 100644 --- a/third_party/WebKit/Source/modules/presentation/PresentationAvailability.cpp +++ b/third_party/WebKit/Source/modules/presentation/PresentationAvailability.cpp
@@ -67,7 +67,9 @@ } } -void PresentationAvailability::AvailabilityChanged(bool value) { +void PresentationAvailability::AvailabilityChanged( + blink::mojom::ScreenAvailability availability) { + bool value = availability == blink::mojom::ScreenAvailability::AVAILABLE; if (value_ == value) return;
diff --git a/third_party/WebKit/Source/modules/presentation/PresentationAvailability.h b/third_party/WebKit/Source/modules/presentation/PresentationAvailability.h index fed9aa6..28ba75d 100644 --- a/third_party/WebKit/Source/modules/presentation/PresentationAvailability.h +++ b/third_party/WebKit/Source/modules/presentation/PresentationAvailability.h
@@ -45,7 +45,7 @@ ExecutionContext* GetExecutionContext() const override; // WebPresentationAvailabilityObserver implementation. - void AvailabilityChanged(bool) override; + void AvailabilityChanged(blink::mojom::ScreenAvailability) override; const WebVector<WebURL>& Urls() const override; // ScriptWrappable implementation.
diff --git a/third_party/WebKit/Source/modules/remoteplayback/RemotePlayback.cpp b/third_party/WebKit/Source/modules/remoteplayback/RemotePlayback.cpp index 7b38671..55d99ad 100644 --- a/third_party/WebKit/Source/modules/remoteplayback/RemotePlayback.cpp +++ b/third_party/WebKit/Source/modules/remoteplayback/RemotePlayback.cpp
@@ -21,6 +21,7 @@ #include "platform/MemoryCoordinator.h" #include "platform/json/JSONValues.h" #include "platform/wtf/text/Base64.h" +#include "public/platform/modules/presentation/WebPresentationClient.h" namespace blink { @@ -202,7 +203,6 @@ return promise; } - // TODO(avayvod): this state is not propagated with the new pipeline. if (availability_ == WebRemotePlaybackAvailability::kSourceNotCompatible) { resolver->Reject(DOMException::Create( kNotSupportedError, @@ -394,12 +394,35 @@ media_element_->RequestRemotePlaybackStop(); } -void RemotePlayback::AvailabilityChanged(bool availability) { +void RemotePlayback::AvailabilityChanged( + mojom::ScreenAvailability availability) { DCHECK(RuntimeEnabledFeatures::NewRemotePlaybackPipelineEnabled()); DCHECK(is_listening_); - AvailabilityChanged(availability - ? WebRemotePlaybackAvailability::kDeviceAvailable - : WebRemotePlaybackAvailability::kDeviceNotAvailable); + + // TODO(avayvod): Use mojom::ScreenAvailability directly once + // WebRemotePlaybackAvailability is gone with the old pipeline. + WebRemotePlaybackAvailability remote_playback_availability = + WebRemotePlaybackAvailability::kUnknown; + switch (availability) { + case mojom::ScreenAvailability::UNKNOWN: + case mojom::ScreenAvailability::DISABLED: + NOTREACHED(); + remote_playback_availability = WebRemotePlaybackAvailability::kUnknown; + break; + case mojom::ScreenAvailability::UNAVAILABLE: + remote_playback_availability = + WebRemotePlaybackAvailability::kDeviceNotAvailable; + break; + case mojom::ScreenAvailability::SOURCE_NOT_SUPPORTED: + remote_playback_availability = + WebRemotePlaybackAvailability::kSourceNotCompatible; + break; + case mojom::ScreenAvailability::AVAILABLE: + remote_playback_availability = + WebRemotePlaybackAvailability::kDeviceAvailable; + break; + } + AvailabilityChanged(remote_playback_availability); } const WebVector<WebURL>& RemotePlayback::Urls() const {
diff --git a/third_party/WebKit/Source/modules/remoteplayback/RemotePlayback.h b/third_party/WebKit/Source/modules/remoteplayback/RemotePlayback.h index c18c729..70ac0b39 100644 --- a/third_party/WebKit/Source/modules/remoteplayback/RemotePlayback.h +++ b/third_party/WebKit/Source/modules/remoteplayback/RemotePlayback.h
@@ -78,7 +78,7 @@ WebRemotePlaybackState GetState() const { return state_; } // WebPresentationAvailabilityObserver implementation. - void AvailabilityChanged(bool) override; + void AvailabilityChanged(mojom::ScreenAvailability) override; const WebVector<WebURL>& Urls() const override; // WebRemotePlaybackClient implementation.
diff --git a/third_party/WebKit/Source/modules/remoteplayback/RemotePlaybackTest.cpp b/third_party/WebKit/Source/modules/remoteplayback/RemotePlaybackTest.cpp index 096411d..837461e 100644 --- a/third_party/WebKit/Source/modules/remoteplayback/RemotePlaybackTest.cpp +++ b/third_party/WebKit/Source/modules/remoteplayback/RemotePlaybackTest.cpp
@@ -419,7 +419,7 @@ WebURL(KURL(kParsedURLString, "http://www.example.com"))); ASSERT_EQ((size_t)1, remote_playback->Urls().size()); ASSERT_TRUE(IsListening(remote_playback)); - remote_playback->AvailabilityChanged(true); + remote_playback->AvailabilityChanged(mojom::ScreenAvailability::AVAILABLE); remote_playback->cancelWatchAvailability(scope.GetScriptState()); ASSERT_EQ((size_t)1, remote_playback->Urls().size()); @@ -429,7 +429,7 @@ availability_callback); ASSERT_EQ((size_t)1, remote_playback->Urls().size()); ASSERT_TRUE(IsListening(remote_playback)); - remote_playback->AvailabilityChanged(true); + remote_playback->AvailabilityChanged(mojom::ScreenAvailability::AVAILABLE); remote_playback->SourceChanged(WebURL()); ASSERT_TRUE(remote_playback->Urls().empty());
diff --git a/third_party/WebKit/Source/web/WebLocalFrameImpl.cpp b/third_party/WebKit/Source/web/WebLocalFrameImpl.cpp index aae2a40..9ed6926 100644 --- a/third_party/WebKit/Source/web/WebLocalFrameImpl.cpp +++ b/third_party/WebKit/Source/web/WebLocalFrameImpl.cpp
@@ -843,6 +843,10 @@ return script_state->GetContext(); } +v8::Local<v8::Object> WebLocalFrameImpl::GlobalProxy() const { + return MainWorldScriptContext()->Global(); +} + bool WebFrame::ScriptCanAccess(WebFrame* target) { return BindingSecurity::ShouldAllowAccessToFrame( CurrentDOMWindow(MainThreadIsolate()), ToCoreFrame(*target),
diff --git a/third_party/WebKit/Source/web/WebLocalFrameImpl.h b/third_party/WebKit/Source/web/WebLocalFrameImpl.h index e807e41..554e446 100644 --- a/third_party/WebKit/Source/web/WebLocalFrameImpl.h +++ b/third_party/WebKit/Source/web/WebLocalFrameImpl.h
@@ -146,6 +146,7 @@ int argc, v8::Local<v8::Value> argv[]) override; v8::Local<v8::Context> MainWorldScriptContext() const override; + v8::Local<v8::Object> GlobalProxy() const override; void Reload(WebFrameLoadType) override; void ReloadWithOverrideURL(const WebURL& override_url, WebFrameLoadType) override;
diff --git a/third_party/WebKit/Source/web/tests/LayoutGeometryMapTest.cpp b/third_party/WebKit/Source/web/tests/LayoutGeometryMapTest.cpp index 1e0d49cf..dd588373 100644 --- a/third_party/WebKit/Source/web/tests/LayoutGeometryMapTest.cpp +++ b/third_party/WebKit/Source/web/tests/LayoutGeometryMapTest.cpp
@@ -335,6 +335,9 @@ GetLayoutBox(web_view, "simple-container")); EXPECT_EQ(FloatRect(8.0f, 50.0f, 100.0f, 100.0f), AdjustForFrameScroll(web_view, rgm.AbsoluteRect(rect))); + EXPECT_EQ( + FloatQuad(FloatRect(0.0f, -50.0f, 100.0f, 100.0f)), + rgm.MapToAncestor(rect, GetLayoutBox(web_view, "simple-container"))); rgm.PopMappingsToAncestor(static_cast<PaintLayer*>(nullptr)); // Transforms contain fixed position descendants.
diff --git a/third_party/WebKit/Source/web/tests/PrerenderingTest.cpp b/third_party/WebKit/Source/web/tests/PrerenderingTest.cpp index 8eaf3cb..5c0338a 100644 --- a/third_party/WebKit/Source/web/tests/PrerenderingTest.cpp +++ b/third_party/WebKit/Source/web/tests/PrerenderingTest.cpp
@@ -182,7 +182,7 @@ } void Close() { - web_view_helper_.WebView()->MainFrame()->CollectGarbage(); + web_view_helper_.WebView()->MainFrameImpl()->CollectGarbage(); web_view_helper_.Reset(); WebCache::Clear();
diff --git a/third_party/WebKit/Source/web/tests/WebFrameTest.cpp b/third_party/WebKit/Source/web/tests/WebFrameTest.cpp index 9171bd5c..ba09ca08 100644 --- a/third_party/WebKit/Source/web/tests/WebFrameTest.cpp +++ b/third_party/WebKit/Source/web/tests/WebFrameTest.cpp
@@ -403,14 +403,15 @@ web_view_helper.InitializeAndLoad(base_url_ + "iframes_test.html", true); v8::HandleScope scope(v8::Isolate::GetCurrent()); - EXPECT_EQ( - web_view_helper.WebView()->MainFrame(), - WebLocalFrame::FrameForContext( - web_view_helper.WebView()->MainFrame()->MainWorldScriptContext())); + EXPECT_EQ(web_view_helper.WebView()->MainFrame(), + WebLocalFrame::FrameForContext(web_view_helper.WebView() + ->MainFrameImpl() + ->MainWorldScriptContext())); EXPECT_EQ(web_view_helper.WebView()->MainFrame()->FirstChild(), WebLocalFrame::FrameForContext(web_view_helper.WebView() ->MainFrame() ->FirstChild() + ->ToWebLocalFrame() ->MainWorldScriptContext())); } @@ -451,7 +452,7 @@ v8::HandleScope scope(v8::Isolate::GetCurrent()); ScriptExecutionCallbackHelper callback_helper( - web_view_helper.WebView()->MainFrame()->MainWorldScriptContext()); + web_view_helper.WebView()->MainFrameImpl()->MainWorldScriptContext()); web_view_helper.WebView() ->MainFrameImpl() ->RequestExecuteScriptAndReturnValue( @@ -470,7 +471,7 @@ v8::HandleScope scope(v8::Isolate::GetCurrent()); ScriptExecutionCallbackHelper callback_helper( - web_view_helper.WebView()->MainFrame()->MainWorldScriptContext()); + web_view_helper.WebView()->MainFrameImpl()->MainWorldScriptContext()); // Suspend scheduled tasks so the script doesn't run. web_view_helper.WebView() @@ -505,7 +506,7 @@ v8::HandleScope scope(v8::Isolate::GetCurrent()); v8::Local<v8::Context> context = - web_view_helper.WebView()->MainFrame()->MainWorldScriptContext(); + web_view_helper.WebView()->MainFrameImpl()->MainWorldScriptContext(); ScriptExecutionCallbackHelper callback_helper(context); v8::Local<v8::Function> function = v8::Function::New(context, callback).ToLocalChecked(); @@ -532,7 +533,7 @@ v8::HandleScope scope(v8::Isolate::GetCurrent()); v8::Local<v8::Context> context = - web_view_helper.WebView()->MainFrame()->MainWorldScriptContext(); + web_view_helper.WebView()->MainFrameImpl()->MainWorldScriptContext(); // Suspend scheduled tasks so the script doesn't run. WebLocalFrameBase* main_frame = web_view_helper.WebView()->MainFrameImpl(); @@ -572,7 +573,7 @@ v8::HandleScope scope(v8::Isolate::GetCurrent()); v8::Local<v8::Context> context = - web_view_helper.WebView()->MainFrame()->MainWorldScriptContext(); + web_view_helper.WebView()->MainFrameImpl()->MainWorldScriptContext(); std::unique_ptr<UserGestureIndicator> indicator = WTF::WrapUnique(new UserGestureIndicator( @@ -602,7 +603,7 @@ v8::HandleScope scope(v8::Isolate::GetCurrent()); ScriptExecutionCallbackHelper callback_helper( - web_view_helper.WebView()->MainFrame()->MainWorldScriptContext()); + web_view_helper.WebView()->MainFrameImpl()->MainWorldScriptContext()); web_view_helper.WebView() ->MainFrame() ->FirstChild() @@ -4574,7 +4575,7 @@ web_view_helper.InitializeAndLoad( base_url_ + "context_notifications_test.html", true, &web_frame_client); - WebFrame* main_frame = web_view_helper.WebView()->MainFrame(); + WebLocalFrameBase* main_frame = web_view_helper.WebView()->MainFrameImpl(); WebFrame* child_frame = main_frame->FirstChild(); ASSERT_EQ(2u, create_notifications.size()); @@ -4589,7 +4590,7 @@ EXPECT_EQ(0, first_create_notification->world_id); EXPECT_EQ(child_frame, second_create_notification->frame); - EXPECT_EQ(child_frame->MainWorldScriptContext(), + EXPECT_EQ(child_frame->ToWebLocalFrame()->MainWorldScriptContext(), second_create_notification->context); EXPECT_EQ(0, second_create_notification->world_id); @@ -4638,7 +4639,7 @@ // The last two create notifications should be for the current frames and // context. - WebFrame* main_frame = web_view_helper.WebView()->MainFrame(); + WebLocalFrameBase* main_frame = web_view_helper.WebView()->MainFrameImpl(); WebFrame* child_frame = main_frame->FirstChild(); auto& first_refresh_notification = create_notifications[2]; auto& second_refresh_notification = create_notifications[3]; @@ -4649,7 +4650,7 @@ EXPECT_EQ(0, first_refresh_notification->world_id); EXPECT_EQ(child_frame, second_refresh_notification->frame); - EXPECT_EQ(child_frame->MainWorldScriptContext(), + EXPECT_EQ(child_frame->ToWebLocalFrame()->MainWorldScriptContext(), second_refresh_notification->context); EXPECT_EQ(0, second_refresh_notification->world_id); } @@ -4688,8 +4689,9 @@ // We don't have an API to enumarate isolated worlds for a frame, but we can // at least assert that the context we got is *not* the main world's context. - ASSERT_NE(web_view_helper.WebView()->MainFrame()->MainWorldScriptContext(), - v8::Local<v8::Context>::New(isolate, notification->context)); + ASSERT_NE( + web_view_helper.WebView()->MainFrameImpl()->MainWorldScriptContext(), + v8::Local<v8::Context>::New(isolate, notification->context)); web_view_helper.Reset(); @@ -9942,7 +9944,7 @@ String code = "dumpSize('" + id + "')"; v8::HandleScope scope(v8::Isolate::GetCurrent()); ScriptExecutionCallbackHelper callback_helper( - web_view_helper_.WebView()->MainFrame()->MainWorldScriptContext()); + web_view_helper_.WebView()->MainFrameImpl()->MainWorldScriptContext()); web_view_helper_.WebView() ->MainFrameImpl() ->RequestExecuteScriptAndReturnValue(WebScriptSource(WebString(code)),
diff --git a/third_party/WebKit/Source/web/tests/WebViewTest.cpp b/third_party/WebKit/Source/web/tests/WebViewTest.cpp index 0d012e0c..685aaba 100644 --- a/third_party/WebKit/Source/web/tests/WebViewTest.cpp +++ b/third_party/WebKit/Source/web/tests/WebViewTest.cpp
@@ -3809,7 +3809,7 @@ FrameTestHelpers::WebViewHelper main_web_view; main_web_view.InitializeAndLoad("about:blank", true, 0, &client); - WebFrame* frame = main_web_view.WebView()->MainFrame(); + WebLocalFrame* frame = main_web_view.WebView()->MainFrameImpl(); v8::HandleScope scope(v8::Isolate::GetCurrent()); v8::Local<v8::Value> v8_value = frame->ExecuteScriptAndReturnValue(WebScriptSource(
diff --git a/third_party/WebKit/public/platform/modules/presentation/OWNERS b/third_party/WebKit/public/platform/modules/presentation/OWNERS index b372098..cc1e3e9 100644 --- a/third_party/WebKit/public/platform/modules/presentation/OWNERS +++ b/third_party/WebKit/public/platform/modules/presentation/OWNERS
@@ -1,2 +1,4 @@ file://third_party/WebKit/Source/modules/presentation/OWNERS +per-file *.mojom=set noparent +per-file *.mojom=file://ipc/SECURITY_OWNERS
diff --git a/third_party/WebKit/public/platform/modules/presentation/WebPresentationAvailabilityObserver.h b/third_party/WebKit/public/platform/modules/presentation/WebPresentationAvailabilityObserver.h index a32cec6..eea4ed1 100644 --- a/third_party/WebKit/public/platform/modules/presentation/WebPresentationAvailabilityObserver.h +++ b/third_party/WebKit/public/platform/modules/presentation/WebPresentationAvailabilityObserver.h
@@ -7,6 +7,7 @@ #include "public/platform/WebCommon.h" #include "public/platform/WebURL.h" +#include "public/platform/modules/presentation/presentation.mojom-blink.h" namespace blink { @@ -21,7 +22,7 @@ public: virtual ~WebPresentationAvailabilityObserver() = default; - virtual void AvailabilityChanged(bool) = 0; + virtual void AvailabilityChanged(blink::mojom::ScreenAvailability) = 0; virtual const WebVector<WebURL>& Urls() const = 0; };
diff --git a/third_party/WebKit/public/platform/modules/presentation/presentation.mojom b/third_party/WebKit/public/platform/modules/presentation/presentation.mojom index a511c07..f68bc43a 100644 --- a/third_party/WebKit/public/platform/modules/presentation/presentation.mojom +++ b/third_party/WebKit/public/platform/modules/presentation/presentation.mojom
@@ -11,6 +11,14 @@ string id; }; +enum ScreenAvailability { + UNKNOWN, + UNAVAILABLE, + SOURCE_NOT_SUPPORTED, + DISABLED, + AVAILABLE +}; + enum PresentationConnectionState { CONNECTING, CONNECTED, @@ -111,7 +119,7 @@ // This is called after a connection has been established to the presentation // from the frame. ListenForConnectionMessages(PresentationInfo presentation_info); -}; +}; interface PresentationServiceClient { ////////// This API is implemented by a controlling frame. ///////////////// @@ -126,7 +134,8 @@ // presentation of |url| and the state changes. When the client starts to // listen for screen availability, this method will always be called to give // the current known state. It will then be called to notify of state updates. - OnScreenAvailabilityUpdated(url.mojom.Url url, bool available); + OnScreenAvailabilityUpdated(url.mojom.Url url, + ScreenAvailability availability); // See PresentationService::SetDefaultPresentationURL. OnDefaultPresentationStarted(PresentationInfo presentation_info); @@ -156,6 +165,4 @@ // See PresentationService::ListenForConnectionMessages. OnConnectionMessagesReceived(PresentationInfo presentation_info, array<PresentationConnectionMessage> messages); - - };
diff --git a/third_party/WebKit/public/web/WebFrame.h b/third_party/WebKit/public/web/WebFrame.h index 4b95fb4..ea7abf1 100644 --- a/third_party/WebKit/public/web/WebFrame.h +++ b/third_party/WebKit/public/web/WebFrame.h
@@ -40,14 +40,7 @@ #include "public/platform/WebInsecureRequestPolicy.h" #include "public/web/WebFrameLoadType.h" #include "public/web/WebTreeScopeType.h" - -namespace v8 { -class Context; -class Function; -class Value; -template <class T> -class Local; -} +#include "v8/include/v8.h" namespace blink { @@ -71,12 +64,8 @@ struct WebFrameOwnerProperties; struct WebPrintParams; struct WebRect; -struct WebScriptSource; struct WebSize; -template <typename T> -class WebVector; - // Frames may be rendered in process ('local') or out of process ('remote'). // A remote frame is always cross-site; a local frame may be either same-site or // cross-site. @@ -219,65 +208,8 @@ // Scripting ---------------------------------------------------------- - // Executes JavaScript in a new world associated with the web frame. - // The script gets its own global scope and its own prototypes for - // intrinsic JavaScript objects (String, Array, and so-on). It also - // gets its own wrappers for all DOM nodes and DOM constructors. - // - // worldID must be > 0 (as 0 represents the main world). - // worldID must be < EmbedderWorldIdLimit, high number used internally. - virtual void ExecuteScriptInIsolatedWorld(int world_id, - const WebScriptSource* sources, - unsigned num_sources) = 0; - - // Associates an isolated world (see above for description) with a security - // origin. XMLHttpRequest instances used in that world will be considered - // to come from that origin, not the frame's. - virtual void SetIsolatedWorldSecurityOrigin(int world_id, - const WebSecurityOrigin&) = 0; - - // Associates a content security policy with an isolated world. This policy - // should be used when evaluating script in the isolated world, and should - // also replace a protected resource's CSP when evaluating resources - // injected into the DOM. - // - // FIXME: Setting this simply bypasses the protected resource's CSP. It - // doesn't yet restrict the isolated world to the provided policy. - virtual void SetIsolatedWorldContentSecurityPolicy(int world_id, - const WebString&) = 0; - - // Calls window.gc() if it is defined. - virtual void CollectGarbage() = 0; - - // Executes script in the context of the current page and returns the value - // that the script evaluated to. - // DEPRECATED: Use WebLocalFrame::requestExecuteScriptAndReturnValue. - virtual v8::Local<v8::Value> ExecuteScriptAndReturnValue( - const WebScriptSource&) = 0; - - // worldID must be > 0 (as 0 represents the main world). - // worldID must be < EmbedderWorldIdLimit, high number used internally. - // DEPRECATED: Use WebLocalFrame::requestExecuteScriptInIsolatedWorld. - virtual void ExecuteScriptInIsolatedWorld( - int world_id, - const WebScriptSource* sources_in, - unsigned num_sources, - WebVector<v8::Local<v8::Value>>* results) = 0; - - // Call the function with the given receiver and arguments, bypassing - // canExecute(). - virtual v8::Local<v8::Value> CallFunctionEvenIfScriptDisabled( - v8::Local<v8::Function>, - v8::Local<v8::Value>, - int argc, - v8::Local<v8::Value> argv[]) = 0; - - // Returns the V8 context for associated with the main world and this - // frame. There can be many V8 contexts associated with this frame, one for - // each isolated world and one for the main world. If you don't know what - // the "main world" or an "isolated world" is, then you probably shouldn't - // be calling this API. - virtual v8::Local<v8::Context> MainWorldScriptContext() const = 0; + // Returns the global proxy object. + virtual v8::Local<v8::Object> GlobalProxy() const = 0; // Returns true if the WebFrame currently executing JavaScript has access // to the given WebFrame, or false otherwise.
diff --git a/third_party/WebKit/public/web/WebLocalFrame.h b/third_party/WebKit/public/web/WebLocalFrame.h index 0196d82..7b2ecf30 100644 --- a/third_party/WebKit/public/web/WebLocalFrame.h +++ b/third_party/WebKit/public/web/WebLocalFrame.h
@@ -14,6 +14,7 @@ #include "public/platform/WebURLError.h" #include "public/platform/WebURLRequest.h" #include "public/platform/site_engagement.mojom-shared.h" +#include "v8/include/v8.h" namespace base { class SingleThreadTaskRunner; @@ -49,6 +50,7 @@ struct WebFindOptions; struct WebFloatRect; struct WebPrintPresetOptions; +struct WebScriptSource; struct WebSourceLocation; // Interface for interacting with in process frames. This contains methods that @@ -296,6 +298,66 @@ // Executes script in the context of the current page. virtual void ExecuteScript(const WebScriptSource&) = 0; + // Executes JavaScript in a new world associated with the web frame. + // The script gets its own global scope and its own prototypes for + // intrinsic JavaScript objects (String, Array, and so-on). It also + // gets its own wrappers for all DOM nodes and DOM constructors. + // + // worldID must be > 0 (as 0 represents the main world). + // worldID must be < EmbedderWorldIdLimit, high number used internally. + virtual void ExecuteScriptInIsolatedWorld(int world_id, + const WebScriptSource* sources, + unsigned num_sources) = 0; + + // worldID must be > 0 (as 0 represents the main world). + // worldID must be < EmbedderWorldIdLimit, high number used internally. + // DEPRECATED: Use WebLocalFrame::requestExecuteScriptInIsolatedWorld. + virtual void ExecuteScriptInIsolatedWorld( + int world_id, + const WebScriptSource* sources_in, + unsigned num_sources, + WebVector<v8::Local<v8::Value>>* results) = 0; + + // Associates an isolated world (see above for description) with a security + // origin. XMLHttpRequest instances used in that world will be considered + // to come from that origin, not the frame's. + virtual void SetIsolatedWorldSecurityOrigin(int world_id, + const WebSecurityOrigin&) = 0; + + // Associates a content security policy with an isolated world. This policy + // should be used when evaluating script in the isolated world, and should + // also replace a protected resource's CSP when evaluating resources + // injected into the DOM. + // + // FIXME: Setting this simply bypasses the protected resource's CSP. It + // doesn't yet restrict the isolated world to the provided policy. + virtual void SetIsolatedWorldContentSecurityPolicy(int world_id, + const WebString&) = 0; + + // Calls window.gc() if it is defined. + virtual void CollectGarbage() = 0; + + // Executes script in the context of the current page and returns the value + // that the script evaluated to. + // DEPRECATED: Use WebLocalFrame::requestExecuteScriptAndReturnValue. + virtual v8::Local<v8::Value> ExecuteScriptAndReturnValue( + const WebScriptSource&) = 0; + + // Call the function with the given receiver and arguments, bypassing + // canExecute(). + virtual v8::Local<v8::Value> CallFunctionEvenIfScriptDisabled( + v8::Local<v8::Function>, + v8::Local<v8::Value>, + int argc, + v8::Local<v8::Value> argv[]) = 0; + + // Returns the V8 context for associated with the main world and this + // frame. There can be many V8 contexts associated with this frame, one for + // each isolated world and one for the main world. If you don't know what + // the "main world" or an "isolated world" is, then you probably shouldn't + // be calling this API. + virtual v8::Local<v8::Context> MainWorldScriptContext() const = 0; + // Executes script in the context of the current page and returns the value // that the script evaluated to with callback. Script execution can be // suspend.
diff --git a/third_party/WebKit/public/web/WebRemoteFrame.h b/third_party/WebKit/public/web/WebRemoteFrame.h index 52039dc..5c23c51 100644 --- a/third_party/WebKit/public/web/WebRemoteFrame.h +++ b/third_party/WebKit/public/web/WebRemoteFrame.h
@@ -100,8 +100,6 @@ virtual void SetHasReceivedUserGesture() = 0; - virtual v8::Local<v8::Object> GlobalProxy() const = 0; - protected: explicit WebRemoteFrame(WebTreeScopeType scope) : WebFrame(scope) {}
diff --git a/third_party/closure_compiler/compile2.py b/third_party/closure_compiler/compile2.py index 224856d7..260c57e7 100755 --- a/third_party/closure_compiler/compile2.py +++ b/third_party/closure_compiler/compile2.py
@@ -243,7 +243,7 @@ self._log_debug("Args: %s" % " ".join(args)) - _, stderr = self.run_jar(self._compiler_jar, args) + return_code, stderr = self.run_jar(self._compiler_jar, args) errors = stderr.strip().split("\n\n") maybe_summary = errors.pop() @@ -262,7 +262,7 @@ os.remove(out_file) if os.path.exists(self._MAP_FILE_FORMAT % out_file): os.remove(self._MAP_FILE_FORMAT % out_file) - elif checks_only: + elif checks_only and return_code == 0: # Compile succeeded but --checks_only disables --js_output_file from # actually writing a file. Write a file ourselves so incremental builds # still work. @@ -280,7 +280,7 @@ self._log_debug("Output: %s" % output) self._nuke_temp_files() - return bool(errors), stderr + return bool(errors) or return_code > 0, stderr if __name__ == "__main__":
diff --git a/tools/json_schema_compiler/idl_schema.py b/tools/json_schema_compiler/idl_schema.py index fcad49b..7bbe842 100755 --- a/tools/json_schema_compiler/idl_schema.py +++ b/tools/json_schema_compiler/idl_schema.py
@@ -182,12 +182,15 @@ name = self.node.GetName() if self.node.GetProperty('deprecated'): properties['deprecated'] = self.node.GetProperty('deprecated') - if self.node.GetProperty('allowAmbiguousOptionalArguments'): - properties['allowAmbiguousOptionalArguments'] = True - for property_name in ('OPTIONAL', 'nodoc', 'nocompile', 'nodart', - 'nodefine'): + + for property_name in ['allowAmbiguousOptionalArguments', 'forIOThread', + 'nodoc', 'nocompile', 'nodart', 'nodefine']: if self.node.GetProperty(property_name): - properties[property_name.lower()] = True + properties[property_name] = True + + if self.node.GetProperty('OPTIONAL'): + properties['optional'] = True + for option_name, sanitizer in [ ('maxListeners', int), ('supportsFilters', lambda s: s == 'true'),
diff --git a/tools/json_schema_compiler/idl_schema_test.py b/tools/json_schema_compiler/idl_schema_test.py index f9a4d87..4b47b44f 100755 --- a/tools/json_schema_compiler/idl_schema_test.py +++ b/tools/json_schema_compiler/idl_schema_test.py
@@ -79,6 +79,17 @@ 'c': {'name': 'c', 'type': 'string'}}, getType(self.idl_basics, 'MyType1')['properties']) + def testIOThreadFunc(self): + schema = self.idl_basics + + func = getFunction(schema, 'function32') + self.assertTrue(func is not None) + self.assertTrue(func['forIOThread']) + + func = getFunction(schema, 'function1') + self.assertTrue(func is not None) + self.assertTrue('forIOThread' not in func) + def testMemberOrdering(self): self.assertEquals( ['x', 'y', 'z', 'a', 'b', 'c'],
diff --git a/tools/json_schema_compiler/test/idl_basics.idl b/tools/json_schema_compiler/test/idl_basics.idl index bfa49dce..c4fb5aa 100644 --- a/tools/json_schema_compiler/test/idl_basics.idl +++ b/tools/json_schema_compiler/test/idl_basics.idl
@@ -102,6 +102,8 @@ static idl_other_namespace.SomeType[] function30(); [nodefine] static void function31(long switch); + + [forIOThread] static void function32(); }; interface Events {
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index 099d7ca..fbcbaa7 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -5636,6 +5636,7 @@ <int value="31" label="Permission autoblocker data setting"/> <int value="32" label="Subresource filter setting"/> <int value="33" label="Subresource filter metadata"/> + <int value="34" label="Password protection setting"/> </enum> <enum name="ContentTypeParseableResult" type="int">
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index f3310ae..3616616 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -51480,8 +51480,8 @@ </summary> </histogram> -<histogram name="PasswordProtection.NumberOfCachedVerdictBeforeShutdown" - units="count"> +<histogram base="true" + name="PasswordProtection.NumberOfCachedVerdictBeforeShutdown" units="count"> <owner>jialiul@chromium.org</owner> <owner>nparker@chromium.org</owner> <summary> @@ -82504,6 +82504,17 @@ </histogram> <histogram name="WebCore.IndexedDB.PutValueSize" units="KB"> + <obsolete> + Replaced with WebCore.IndexedDB.PutValueSize2 on 6/2017 + </obsolete> + <owner>dmurph@chromium.org</owner> + <summary> + The size of the IndexedDB value used in an IndexedDB object store 'put' + operation. Recorded for every 'put' operation. + </summary> +</histogram> + +<histogram name="WebCore.IndexedDB.PutValueSize2" units="KB"> <owner>dmurph@chromium.org</owner> <summary> The size of the IndexedDB value used in an IndexedDB object store 'put' @@ -82556,6 +82567,19 @@ <histogram name="WebCore.IndexedDB.Transaction.ReadOnly.SizeOnCommit" units="KB"> + <obsolete> + Replaced with WebCore.IndexedDB.Transaction.ReadOnly.SizeOnCommit2 on 6/2017 + </obsolete> + <owner>dmurph@chromium.org</owner> + <summary> + The total temporary size of an IndexedDB ReadOnly Transaction. Since this is + a readonly transaction, the size should only be >0 when the transaction + is removing tombstone index keys. Recorded on transaction commit. + </summary> +</histogram> + +<histogram name="WebCore.IndexedDB.Transaction.ReadOnly.SizeOnCommit2" + units="KB"> <owner>dmurph@chromium.org</owner> <summary> The total temporary size of an IndexedDB ReadOnly Transaction. Since this is @@ -82575,6 +82599,20 @@ <histogram name="WebCore.IndexedDB.Transaction.ReadWrite.SizeOnCommit" units="KB"> + <obsolete> + Replaced with WebCore.IndexedDB.Transaction.ReadWrite.SizeOnCommit2 on + 6/2017 + </obsolete> + <owner>dmurph@chromium.org</owner> + <summary> + The total temporary size of an IndexedDB ReadWrite Transaction. This is the + memory that is temporarily stored before writing to disk. Recorded on + transaction commit. + </summary> +</histogram> + +<histogram name="WebCore.IndexedDB.Transaction.ReadWrite.SizeOnCommit2" + units="KB"> <owner>dmurph@chromium.org</owner> <summary> The total temporary size of an IndexedDB ReadWrite Transaction. This is the @@ -82594,6 +82632,21 @@ <histogram name="WebCore.IndexedDB.Transaction.VersionChange.SizeOnCommit" units="KB"> + <obsolete> + Replaced with WebCore.IndexedDB.Transaction.VersionChange.SizeOnCommit2 on + 6/2017 + </obsolete> + <owner>dmurph@chromium.org</owner> + <summary> + The total temporary size of an IndexedDB VersionChange Transaction. This is + the memory that is temporarily stored before writing to disk. Version change + transactions happen when creating a database or updating a current database + schema. Recorded on transaction commit. + </summary> +</histogram> + +<histogram name="WebCore.IndexedDB.Transaction.VersionChange.SizeOnCommit2" + units="KB"> <owner>dmurph@chromium.org</owner> <summary> The total temporary size of an IndexedDB VersionChange Transaction. This is @@ -92765,6 +92818,8 @@ </histogram_suffixes> <histogram_suffixes name="PasswordProtectionTrigger" separator="."> + <affected-histogram + name="PasswordProtection.NumberOfCachedVerdictBeforeShutdown"/> <suffix name="PasswordFieldOnFocus" label="Password protection triggered by password field on focus event."/> <suffix name="ProtectedPasswordEntry"
diff --git a/ui/accessibility/ax_tree.cc b/ui/accessibility/ax_tree.cc index 03b6aeb8..43e635af 100644 --- a/ui/accessibility/ax_tree.cc +++ b/ui/accessibility/ax_tree.cc
@@ -11,6 +11,7 @@ #include "base/logging.h" #include "base/strings/stringprintf.h" #include "ui/accessibility/ax_node.h" +#include "ui/gfx/transform.h" namespace ui { @@ -164,6 +165,60 @@ delegate_->OnTreeDataChanged(this, old_data, new_data); } +gfx::RectF AXTree::RelativeToTreeBounds(const AXNode* node, + gfx::RectF bounds) const { + // If |bounds| is uninitialized, which is not the same as empty, + // start with the node bounds. + if (bounds.width() == 0 && bounds.height() == 0) { + bounds = node->data().location; + + // If the node bounds is empty (either width or height is zero), + // try to compute good bounds from the children. + if (bounds.IsEmpty()) { + for (size_t i = 0; i < node->children().size(); i++) { + ui::AXNode* child = node->children()[i]; + bounds.Union(GetTreeBounds(child)); + } + if (bounds.width() > 0 && bounds.height() > 0) + return bounds; + } + } else { + bounds.Offset(node->data().location.x(), node->data().location.y()); + } + + while (node != nullptr) { + if (node->data().transform) + node->data().transform->TransformRect(&bounds); + auto* container = GetFromId(node->data().offset_container_id); + if (!container) { + if (node == root()) + container = node->parent(); + else + container = root(); + } + if (!container || container == node) + break; + + gfx::RectF container_bounds = container->data().location; + bounds.Offset(container_bounds.x(), container_bounds.y()); + + int scroll_x = 0; + int scroll_y = 0; + if (container->data().GetIntAttribute(ui::AX_ATTR_SCROLL_X, &scroll_x) && + container->data().GetIntAttribute(ui::AX_ATTR_SCROLL_Y, &scroll_y)) { + bounds.Offset(-scroll_x, -scroll_y); + } + + node = container; + } + + return bounds; +} + +gfx::RectF AXTree::GetTreeBounds(const AXNode* node) const { + return RelativeToTreeBounds(node, gfx::RectF()); +} + bool AXTree::Unserialize(const AXTreeUpdate& update) { AXTreeUpdateState update_state; int32_t old_root_id = root_ ? root_->id() : 0;
diff --git a/ui/accessibility/ax_tree.h b/ui/accessibility/ax_tree.h index 1448838..36fe655 100644 --- a/ui/accessibility/ax_tree.h +++ b/ui/accessibility/ax_tree.h
@@ -172,6 +172,14 @@ virtual void UpdateData(const AXTreeData& data); + // Convert any rectangle from the local coordinate space of one node in + // the tree, to bounds in the coordinate space of the tree. + gfx::RectF RelativeToTreeBounds(const AXNode* node, + gfx::RectF node_bounds) const; + + // Get the bounds of a node in the coordinate space of the tree. + gfx::RectF GetTreeBounds(const AXNode* node) const; + // Return a multi-line indented string representation, for logging. std::string ToString() const;
diff --git a/ui/accessibility/ax_tree_unittest.cc b/ui/accessibility/ax_tree_unittest.cc index 3618332..c915a5f3 100644 --- a/ui/accessibility/ax_tree_unittest.cc +++ b/ui/accessibility/ax_tree_unittest.cc
@@ -9,12 +9,14 @@ #include <memory> +#include "base/memory/ptr_util.h" #include "base/strings/string_number_conversions.h" #include "base/strings/stringprintf.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/accessibility/ax_node.h" #include "ui/accessibility/ax_serializable_tree.h" #include "ui/accessibility/ax_tree_serializer.h" +#include "ui/gfx/transform.h" using base::DoubleToString; using base::IntToString; @@ -34,6 +36,13 @@ return str; } +std::string GetBoundsAsString(const AXTree& tree, int32_t id) { + AXNode* node = tree.GetFromId(id); + gfx::RectF bounds = tree.GetTreeBounds(node); + return base::StringPrintf("(%.0f, %.0f) size (%.0f x %.0f)", bounds.x(), + bounds.y(), bounds.width(), bounds.height()); +} + class FakeAXTreeDelegate : public AXTreeDelegate { public: FakeAXTreeDelegate() @@ -784,4 +793,113 @@ tree.SetDelegate(NULL); } +// Create a very simple tree and make sure that we can get the bounds of +// any node. +TEST(AXTreeTest, GetBoundsBasic) { + AXTreeUpdate tree_update; + tree_update.root_id = 1; + tree_update.nodes.resize(2); + tree_update.nodes[0].id = 1; + tree_update.nodes[0].location = gfx::RectF(0, 0, 800, 600); + tree_update.nodes[0].child_ids.push_back(2); + tree_update.nodes[1].id = 2; + tree_update.nodes[1].location = gfx::RectF(100, 10, 400, 300); + AXTree tree(tree_update); + + EXPECT_EQ("(0, 0) size (800 x 600)", GetBoundsAsString(tree, 1)); + EXPECT_EQ("(100, 10) size (400 x 300)", GetBoundsAsString(tree, 2)); +} + +// If a node doesn't specify its location but at least one child does have +// a location, its computed bounds should be the union of all child bounds. +TEST(AXTreeTest, EmptyNodeBoundsIsUnionOfChildren) { + AXTreeUpdate tree_update; + tree_update.root_id = 1; + tree_update.nodes.resize(4); + tree_update.nodes[0].id = 1; + tree_update.nodes[0].location = gfx::RectF(0, 0, 800, 600); + tree_update.nodes[0].child_ids.push_back(2); + tree_update.nodes[1].id = 2; + tree_update.nodes[1].location = gfx::RectF(); // Deliberately empty. + tree_update.nodes[1].child_ids.push_back(3); + tree_update.nodes[1].child_ids.push_back(4); + tree_update.nodes[2].id = 3; + tree_update.nodes[2].location = gfx::RectF(100, 10, 400, 20); + tree_update.nodes[3].id = 4; + tree_update.nodes[3].location = gfx::RectF(200, 30, 400, 20); + + AXTree tree(tree_update); + EXPECT_EQ("(100, 10) size (500 x 40)", GetBoundsAsString(tree, 2)); +} + +// Test that getting the bounds of a node works when there's a transform. +TEST(AXTreeTest, GetBoundsWithTransform) { + AXTreeUpdate tree_update; + tree_update.root_id = 1; + tree_update.nodes.resize(3); + tree_update.nodes[0].id = 1; + tree_update.nodes[0].location = gfx::RectF(0, 0, 400, 300); + tree_update.nodes[0].transform.reset(new gfx::Transform()); + tree_update.nodes[0].transform->Scale(2.0, 2.0); + tree_update.nodes[0].child_ids.push_back(2); + tree_update.nodes[0].child_ids.push_back(3); + tree_update.nodes[1].id = 2; + tree_update.nodes[1].location = gfx::RectF(20, 10, 50, 5); + tree_update.nodes[2].id = 3; + tree_update.nodes[2].location = gfx::RectF(20, 30, 50, 5); + tree_update.nodes[2].transform.reset(new gfx::Transform()); + tree_update.nodes[2].transform->Scale(2.0, 2.0); + + AXTree tree(tree_update); + EXPECT_EQ("(0, 0) size (800 x 600)", GetBoundsAsString(tree, 1)); + EXPECT_EQ("(40, 20) size (100 x 10)", GetBoundsAsString(tree, 2)); + EXPECT_EQ("(80, 120) size (200 x 20)", GetBoundsAsString(tree, 3)); +} + +// Test that getting the bounds of a node that's inside a container +// works correctly. +TEST(AXTreeTest, GetBoundsWithContainerId) { + AXTreeUpdate tree_update; + tree_update.root_id = 1; + tree_update.nodes.resize(4); + tree_update.nodes[0].id = 1; + tree_update.nodes[0].location = gfx::RectF(0, 0, 800, 600); + tree_update.nodes[0].child_ids.push_back(2); + tree_update.nodes[1].id = 2; + tree_update.nodes[1].location = gfx::RectF(100, 50, 600, 500); + tree_update.nodes[1].child_ids.push_back(3); + tree_update.nodes[1].child_ids.push_back(4); + tree_update.nodes[2].id = 3; + tree_update.nodes[2].offset_container_id = 2; + tree_update.nodes[2].location = gfx::RectF(20, 30, 50, 5); + tree_update.nodes[3].id = 4; + tree_update.nodes[3].location = gfx::RectF(20, 30, 50, 5); + + AXTree tree(tree_update); + EXPECT_EQ("(120, 80) size (50 x 5)", GetBoundsAsString(tree, 3)); + EXPECT_EQ("(20, 30) size (50 x 5)", GetBoundsAsString(tree, 4)); +} + +// Test that getting the bounds of a node that's inside a scrolling container +// works correctly. +TEST(AXTreeTest, GetBoundsWithScrolling) { + AXTreeUpdate tree_update; + tree_update.root_id = 1; + tree_update.nodes.resize(3); + tree_update.nodes[0].id = 1; + tree_update.nodes[0].location = gfx::RectF(0, 0, 800, 600); + tree_update.nodes[0].child_ids.push_back(2); + tree_update.nodes[1].id = 2; + tree_update.nodes[1].location = gfx::RectF(100, 50, 600, 500); + tree_update.nodes[1].AddIntAttribute(ui::AX_ATTR_SCROLL_X, 5); + tree_update.nodes[1].AddIntAttribute(ui::AX_ATTR_SCROLL_Y, 10); + tree_update.nodes[1].child_ids.push_back(3); + tree_update.nodes[2].id = 3; + tree_update.nodes[2].offset_container_id = 2; + tree_update.nodes[2].location = gfx::RectF(20, 30, 50, 5); + + AXTree tree(tree_update); + EXPECT_EQ("(115, 70) size (50 x 5)", GetBoundsAsString(tree, 3)); +} + } // namespace ui
diff --git a/ui/accessibility/platform/ax_snapshot_node_android_platform.cc b/ui/accessibility/platform/ax_snapshot_node_android_platform.cc index af21bbdc..852090a 100644 --- a/ui/accessibility/platform/ax_snapshot_node_android_platform.cc +++ b/ui/accessibility/platform/ax_snapshot_node_android_platform.cc
@@ -30,55 +30,6 @@ return false; } -gfx::Rect RelativeToAbsoluteBounds(const AXNode* node, - gfx::RectF bounds, - const AXTree* tree) { - const AXNode* current = node; - while (current != nullptr) { - if (current->data().transform) - current->data().transform->TransformRect(&bounds); - auto* container = tree->GetFromId(current->data().offset_container_id); - if (!container) { - if (current == tree->root()) - container = current->parent(); - else - container = tree->root(); - } - if (!container || container == current) - break; - - gfx::RectF container_bounds = container->data().location; - bounds.Offset(container_bounds.x(), container_bounds.y()); - current = container; - } - return gfx::ToEnclosingRect(bounds); -} - -void FixEmptyBounds(const AXNode* node, gfx::RectF* bounds, const AXTree* tree); - -gfx::Rect GetPageBoundsRect(const AXNode* node, const AXTree* tree) { - gfx::RectF bounds = node->data().location; - FixEmptyBounds(node, &bounds, tree); - return RelativeToAbsoluteBounds(node, bounds, tree); -} - -void FixEmptyBounds(const AXNode* node, - gfx::RectF* bounds, - const AXTree* tree) { - if (bounds->width() > 0 && bounds->height() > 0) - return; - for (auto* child : node->children()) { - gfx::Rect child_bounds = GetPageBoundsRect(child, tree); - if (child_bounds.width() == 0 || child_bounds.height() == 0) - continue; - if (bounds->width() == 0 || bounds->height() == 0) { - *bounds = gfx::RectF(child_bounds); - continue; - } - bounds->Union(gfx::RectF(child_bounds)); - } -} - bool HasOnlyTextChildren(const AXNode* node) { for (auto* child : node->children()) { if (!child->IsTextNode()) @@ -397,7 +348,7 @@ gfx::RectF text_size_rect( 0, 0, 1, node->data().GetFloatAttribute(ui::AX_ATTR_FONT_SIZE)); gfx::Rect scaled_text_size_rect = - RelativeToAbsoluteBounds(node, text_size_rect, tree); + gfx::ToEnclosingRect(tree->RelativeToTreeBounds(node, text_size_rect)); result->text_size = scaled_text_size_rect.height(); const int text_style = node->data().GetIntAttribute(ui::AX_ATTR_TEXT_STYLE); @@ -410,7 +361,8 @@ result->underline = (text_style & ui::AX_TEXT_STYLE_UNDERLINE) != 0; } - const gfx::Rect& absolute_rect = GetPageBoundsRect(node, tree); + const gfx::Rect& absolute_rect = + gfx::ToEnclosingRect(tree->GetTreeBounds(node)); gfx::Rect parent_relative_rect = absolute_rect; bool is_root = node->parent() == nullptr; if (!is_root) {
diff --git a/ui/app_list/app_list_constants.cc b/ui/app_list/app_list_constants.cc index 4241f46..9633deea 100644 --- a/ui/app_list/app_list_constants.cc +++ b/ui/app_list/app_list_constants.cc
@@ -91,7 +91,6 @@ // The number of apps shown in the start page app grid. const size_t kNumStartPageTiles = 9; -const size_t kNumStartPageTilesFullscreen = 5; // Maximum number of results to show in the launcher Search UI. const size_t kMaxSearchResults = 6;
diff --git a/ui/app_list/app_list_constants.h b/ui/app_list/app_list_constants.h index a3927e9..7e6cb28 100644 --- a/ui/app_list/app_list_constants.h +++ b/ui/app_list/app_list_constants.h
@@ -71,7 +71,6 @@ APP_LIST_EXPORT extern const SkColor kIconColor; APP_LIST_EXPORT extern const size_t kNumStartPageTiles; -APP_LIST_EXPORT extern const size_t kNumStartPageTilesFullscreen; APP_LIST_EXPORT extern const size_t kMaxSearchResults; APP_LIST_EXPORT extern const int kReorderDroppingCircleRadius;
diff --git a/ui/app_list/presenter/app_list_presenter_impl.cc b/ui/app_list/presenter/app_list_presenter_impl.cc index c4ef3092..9fa5613f 100644 --- a/ui/app_list/presenter/app_list_presenter_impl.cc +++ b/ui/app_list/presenter/app_list_presenter_impl.cc
@@ -59,10 +59,8 @@ return; is_visible_ = true; - if (app_list_) { + if (app_list_) app_list_->OnTargetVisibilityChanged(GetTargetVisibility()); - app_list_->OnVisibilityChanged(GetTargetVisibility(), display_id); - } if (view_) { ScheduleAnimation(); @@ -88,10 +86,9 @@ DCHECK(view_); is_visible_ = false; - if (app_list_) { + if (app_list_) app_list_->OnTargetVisibilityChanged(GetTargetVisibility()); - app_list_->OnVisibilityChanged(GetTargetVisibility(), GetDisplayId()); - } + // The dismissal may have occurred in response to the app list losing // activation. Otherwise, our widget is currently active. When the animation // completes we'll hide the widget, changing activation. If a menu is shown
diff --git a/ui/app_list/views/all_apps_tile_item_view.cc b/ui/app_list/views/all_apps_tile_item_view.cc index fd21536..a2bfb8a 100644 --- a/ui/app_list/views/all_apps_tile_item_view.cc +++ b/ui/app_list/views/all_apps_tile_item_view.cc
@@ -6,9 +6,7 @@ #include "base/metrics/histogram_macros.h" #include "ui/app_list/app_list_constants.h" -#include "ui/app_list/app_list_features.h" #include "ui/app_list/resources/grit/app_list_resources.h" -#include "ui/app_list/views/app_list_view.h" #include "ui/app_list/views/contents_view.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/resource/resource_bundle.h" @@ -40,9 +38,8 @@ } // namespace -AllAppsTileItemView::AllAppsTileItemView(ContentsView* contents_view, - AppListView* app_list_view) - : contents_view_(contents_view), app_list_view_(app_list_view) { +AllAppsTileItemView::AllAppsTileItemView(ContentsView* contents_view) + : contents_view_(contents_view) { SetTitle(l10n_util::GetStringUTF16(IDS_APP_LIST_ALL_APPS)); SetHoverStyle(TileItemView::HOVER_STYLE_ANIMATE_SHADOW); UpdateIcon(); @@ -67,8 +64,6 @@ AppListModel::STATE_LAST); contents_view_->SetActiveState(AppListModel::STATE_APPS); - if (features::IsFullscreenAppListEnabled()) - app_list_view_->SetState(AppListView::FULLSCREEN); } } // namespace app_list
diff --git a/ui/app_list/views/all_apps_tile_item_view.h b/ui/app_list/views/all_apps_tile_item_view.h index aa52351..a3cf94b 100644 --- a/ui/app_list/views/all_apps_tile_item_view.h +++ b/ui/app_list/views/all_apps_tile_item_view.h
@@ -11,13 +11,12 @@ namespace app_list { -class AppListView; class ContentsView; // A tile item for the "All apps" button on the start page. class AllAppsTileItemView : public TileItemView { public: - AllAppsTileItemView(ContentsView* contents_view, AppListView* app_list_view); + explicit AllAppsTileItemView(ContentsView* contents_view); ~AllAppsTileItemView() override; @@ -28,7 +27,6 @@ private: ContentsView* contents_view_; - AppListView* const app_list_view_; // Owned by the views hierarchy. DISALLOW_COPY_AND_ASSIGN(AllAppsTileItemView); };
diff --git a/ui/app_list/views/app_list_main_view.cc b/ui/app_list/views/app_list_main_view.cc index eb060ac0..f913e11 100644 --- a/ui/app_list/views/app_list_main_view.cc +++ b/ui/app_list/views/app_list_main_view.cc
@@ -44,13 +44,11 @@ //////////////////////////////////////////////////////////////////////////////// // AppListMainView: -AppListMainView::AppListMainView(AppListViewDelegate* delegate, - AppListView* app_list_view) +AppListMainView::AppListMainView(AppListViewDelegate* delegate) : delegate_(delegate), model_(delegate->GetModel()), search_box_view_(nullptr), - contents_view_(nullptr), - app_list_view_(app_list_view) { + contents_view_(nullptr) { SetLayoutManager( features::IsAnswerCardEnabled() ? static_cast<views::LayoutManager*>(new views::FillLayout) @@ -79,7 +77,8 @@ void AppListMainView::AddContentsViews() { DCHECK(search_box_view_); - contents_view_ = new ContentsView(this, app_list_view_); + + contents_view_ = new ContentsView(this); contents_view_->Init(model_); AddChildView(contents_view_);
diff --git a/ui/app_list/views/app_list_main_view.h b/ui/app_list/views/app_list_main_view.h index 7d06cab3..937a5dd 100644 --- a/ui/app_list/views/app_list_main_view.h +++ b/ui/app_list/views/app_list_main_view.h
@@ -21,7 +21,6 @@ class AppListItem; class AppListModel; -class AppListView; class AppListViewDelegate; class ApplicationDragAndDropHost; class ContentsView; @@ -36,7 +35,7 @@ public SearchBoxViewDelegate, public SearchResultListViewDelegate { public: - AppListMainView(AppListViewDelegate* delegate, AppListView* app_list_view); + explicit AppListMainView(AppListViewDelegate* delegate); ~AppListMainView() override; void Init(gfx::NativeView parent, @@ -100,7 +99,6 @@ // Created by AppListView. Owned by views hierarchy. SearchBoxView* search_box_view_; ContentsView* contents_view_; // Owned by views hierarchy. - AppListView* const app_list_view_; // Owned by views hierarchy. DISALLOW_COPY_AND_ASSIGN(AppListMainView); };
diff --git a/ui/app_list/views/app_list_main_view_unittest.cc b/ui/app_list/views/app_list_main_view_unittest.cc index b365a44..5cfa290 100644 --- a/ui/app_list/views/app_list_main_view_unittest.cc +++ b/ui/app_list/views/app_list_main_view_unittest.cc
@@ -82,7 +82,10 @@ views::ViewsTestBase::SetUp(); delegate_.reset(new AppListTestViewDelegate); - main_view_ = new AppListMainView(delegate_.get(), nullptr); + // In Ash, the third argument is a container aura::Window, but it is always + // NULL on Windows, and not needed for tests. It is only used to determine + // the scale factor for preloading icons. + main_view_ = new AppListMainView(delegate_.get()); main_view_->SetPaintToLayer(); main_view_->model()->SetFoldersEnabled(true); search_box_view_ = new SearchBoxView(main_view_, delegate_.get());
diff --git a/ui/app_list/views/app_list_view.cc b/ui/app_list/views/app_list_view.cc index a38c609..060e7d7 100644 --- a/ui/app_list/views/app_list_view.cc +++ b/ui/app_list/views/app_list_view.cc
@@ -53,33 +53,10 @@ namespace { // The margin from the edge to the speech UI. -constexpr int kSpeechUIMargin = 12; - -// The height/width of the shelf. -constexpr int kShelfSize = 48; - -// The height of the peeking app list. -constexpr int kPeekingAppListHeight = 320; - -// The fraction of app list height that the app list must be released at in -// order to transition to the next state. -constexpr int kAppListThresholdDenominator = 3; - -// The velocity the app list must be dragged in order to transition to the next -// state, measured in DIPs/event. -constexpr int kAppListDragVelocityThreshold = 25; - -// The opacity of the app list background. -constexpr float kAppListOpacity = 0.8; +const int kSpeechUIMargin = 12; // The vertical position for the appearing animation of the speech UI. -constexpr float kSpeechUIAppearingPosition = 12; - -bool IsFullscreenAppListEnabled() { - // Cache this value to avoid repeated lookup. - static bool cached_value = features::IsFullscreenAppListEnabled(); - return cached_value; -} +const float kSpeechUIAppearingPosition = 12; // This view forwards the focus to the search box widget by providing it as a // FocusTraversable when a focus search is provided. @@ -197,16 +174,11 @@ search_box_focus_host_(nullptr), search_box_widget_(nullptr), search_box_view_(nullptr), - app_list_state_(PEEKING), - display_observer_(this), overlay_view_(nullptr), animation_observer_(new HideViewAnimationObserver()) { CHECK(delegate); delegate_->GetSpeechUI()->AddObserver(this); - - if (IsFullscreenAppListEnabled()) - display_observer_.Add(display::Screen::GetScreen()); } AppListView::~AppListView() { @@ -223,20 +195,15 @@ set_color(kContentsBackgroundColor); set_parent_window(parent); - if (IsFullscreenAppListEnabled()) + if (features::IsFullscreenAppListEnabled()) InitializeFullscreen(parent, initial_apps_page); else InitializeBubble(parent, initial_apps_page); InitChildWidgets(); AddChildView(overlay_view_); - - if (IsFullscreenAppListEnabled()) - SetState(app_list_state_); - if (delegate_) delegate_->ViewInitialized(); - UMA_HISTOGRAM_TIMES("Apps.AppListCreationTime", base::Time::Now() - start_time); } @@ -249,7 +216,7 @@ void AppListView::MaybeSetAnchorPoint(const gfx::Point& anchor_point) { // if the AppListView is a bubble - if (!IsFullscreenAppListEnabled()) + if (!features::IsFullscreenAppListEnabled()) SetAnchorRect(gfx::Rect(anchor_point, gfx::Size())); } @@ -262,9 +229,14 @@ app_list_main_view_->ShowAppListWhenReady(); } +void AppListView::CloseAppList() { + app_list_main_view_->Close(); + delegate_->Dismiss(); +} + void AppListView::UpdateBounds() { // if the AppListView is a bubble - if (!IsFullscreenAppListEnabled()) + if (!features::IsFullscreenAppListEnabled()) SizeToContents(); } @@ -357,23 +329,14 @@ FROM_HERE_WITH_EXPLICIT_FUNCTION( "440224, 441028 AppListView::InitContents")); - if (IsFullscreenAppListEnabled()) { - // The shield view that colors the background of the app list and makes it - // transparent. - app_list_background_shield_ = new views::View; - app_list_background_shield_->SetPaintToLayer(ui::LAYER_SOLID_COLOR); - app_list_background_shield_->layer()->SetColor(SK_ColorBLACK); - app_list_background_shield_->layer()->SetOpacity(kAppListOpacity); - AddChildView(app_list_background_shield_); - } - app_list_main_view_ = new AppListMainView(delegate_, this); + app_list_main_view_ = new AppListMainView(delegate_); AddChildView(app_list_main_view_); app_list_main_view_->SetPaintToLayer(); app_list_main_view_->layer()->SetFillsBoundsOpaquely(false); app_list_main_view_->layer()->SetMasksToBounds(true); // This will be added to the |search_box_widget_| after the app list widget is // initialized. - search_box_view_ = new SearchBoxView(app_list_main_view_, delegate_, this); + search_box_view_ = new SearchBoxView(app_list_main_view_, delegate_); search_box_view_->SetPaintToLayer(); search_box_view_->layer()->SetFillsBoundsOpaquely(false); search_box_view_->layer()->SetMasksToBounds(true); @@ -440,29 +403,19 @@ void AppListView::InitializeFullscreen(gfx::NativeView parent, int initial_apps_page) { - gfx::Rect display_work_area_bounds = - display::Screen::GetScreen() - ->GetDisplayNearestView(parent_window()) - .work_area(); - - gfx::Rect app_list_overlay_view_bounds( - display_work_area_bounds.x(), - display_work_area_bounds.height() + kShelfSize - kPeekingAppListHeight, - display_work_area_bounds.width(), - display_work_area_bounds.height() + kShelfSize); - - fullscreen_widget_ = new views::Widget; + views::Widget* widget = new views::Widget; views::Widget::InitParams app_list_overlay_view_params( views::Widget::InitParams::TYPE_WINDOW_FRAMELESS); - app_list_overlay_view_params.name = "AppList"; app_list_overlay_view_params.parent = parent; app_list_overlay_view_params.delegate = this; app_list_overlay_view_params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; - app_list_overlay_view_params.bounds = app_list_overlay_view_bounds; - app_list_overlay_view_params.layer_type = ui::LAYER_SOLID_COLOR; - fullscreen_widget_->Init(app_list_overlay_view_params); + app_list_overlay_view_params.bounds = + display::Screen::GetScreen()-> + GetDisplayNearestView(parent).work_area(); + widget->Init(app_list_overlay_view_params); + widget->GetLayer()->SetBackgroundBlur(10); overlay_view_ = new AppListOverlayView(0 /* no corners */); } @@ -473,8 +426,8 @@ set_close_on_deactivate(false); set_shadow(views::BubbleBorder::NO_ASSETS); - // This creates the app list widget (Before this, child widgets cannot be - // created). + // This creates the app list widget. (Before this, child widgets cannot be + // created.) views::BubbleDialogDelegateView::CreateBubble(this); SetBubbleArrow(views::BubbleBorder::FLOAT); @@ -489,79 +442,6 @@ overlay_view_->SetBoundsRect(GetContentsBounds()); } -void AppListView::StartDrag(const gfx::Point& location) { - initial_drag_point_ = location; -} - -void AppListView::UpdateDrag(const gfx::Point& location) { - // Update the bounds of the widget while maintaining the - // relative position of the top of the widget and the mouse/gesture. - // Block drags north of 0 and recalculate the initial_drag_point_. - int const new_y_position = location.y() - initial_drag_point_.y() + - fullscreen_widget_->GetWindowBoundsInScreen().y(); - gfx::Rect new_widget_bounds = fullscreen_widget_->GetWindowBoundsInScreen(); - if (new_y_position < 0) { - new_widget_bounds.set_y(0); - initial_drag_point_ = location; - } else { - new_widget_bounds.set_y(new_y_position); - } - fullscreen_widget_->SetBounds(new_widget_bounds); -} - -void AppListView::EndDrag(const gfx::Point& location) { - // Change the app list state based on where the drag ended. If fling velocity - // was over the threshold, snap to the next state in the direction of the - // fling. - int const new_y_position = location.y() - initial_drag_point_.y() + - fullscreen_widget_->GetWindowBoundsInScreen().y(); - if (std::abs(last_fling_velocity_) > kAppListDragVelocityThreshold) { - // If the user releases drag with velocity over the threshold, snap to - // the next state, ignoring the drag release position. - if (app_list_state_ == FULLSCREEN) { - if (last_fling_velocity_ > 0) - SetState(PEEKING); - - } else { - SetState(last_fling_velocity_ > 0 ? CLOSED : FULLSCREEN); - } - last_fling_velocity_ = 0; - } else { - int display_height = display::Screen::GetScreen() - ->GetDisplayNearestView(parent_window()) - .work_area() - .height(); - int default_peeking_y = display_height + kShelfSize - kPeekingAppListHeight; - // The drag release velocity was too low, so use the release point. - int app_list_snap_y = - (app_list_state_ == FULLSCREEN) ? 0 : default_peeking_y; - // The DIP delta that must be exceeded for the app list to snap to the next - // state. - int app_list_threshold = - (fullscreen_widget_->GetWindowBoundsInScreen().height() + kShelfSize) / - kAppListThresholdDenominator; - app_list_threshold -= - (app_list_state_ == FULLSCREEN ? 0 : kPeekingAppListHeight) / - kAppListThresholdDenominator; - - // If the user releases +/- 1/3 of |app_list_threshold|, snap to the - // next state. - if (std::abs(app_list_snap_y - new_y_position) < app_list_threshold) { - // The drag was not far enough so set the app list bounds to the target - // bounds for the current state. - SetState(app_list_state_); - } else if ((app_list_snap_y + app_list_threshold) < new_y_position) { - // The drag was far enough to change states and was a downward drag, so - // set the app list bounds to the next state. - SetState(app_list_state_ == FULLSCREEN ? PEEKING : CLOSED); - } else { - // The drag was far enough to change states and was an upward drag, so - // set the app list bounds to the next state. - SetState(FULLSCREEN); - } - } -} - void AppListView::OnBeforeBubbleWidgetInit(views::Widget::InitParams* params, views::Widget* widget) const { if (!params->native_widget) { @@ -595,64 +475,14 @@ mask->addRect(gfx::RectToSkRect(GetBubbleFrameView()->GetContentsBounds())); } -void AppListView::OnMouseEvent(ui::MouseEvent* event) { - if (!IsFullscreenAppListEnabled()) - return; - - switch (event->type()) { - case ui::ET_MOUSE_PRESSED: - StartDrag(event->location()); - event->SetHandled(); - break; - case ui::ET_MOUSE_DRAGGED: - UpdateDrag(event->location()); - event->SetHandled(); - break; - case ui::ET_MOUSE_RELEASED: - EndDrag(event->location()); - event->SetHandled(); - break; - default: - break; - } -} - -void AppListView::OnGestureEvent(ui::GestureEvent* event) { - if (!IsFullscreenAppListEnabled()) - return; - - switch (event->type()) { - case ui::ET_GESTURE_SCROLL_BEGIN: - StartDrag(event->location()); - event->SetHandled(); - break; - case ui::ET_GESTURE_SCROLL_UPDATE: - last_fling_velocity_ = event->details().velocity_y(); - UpdateDrag(event->location()); - event->SetHandled(); - break; - case ui::ET_GESTURE_END: - EndDrag(event->location()); - event->SetHandled(); - break; - default: - break; - } -} - bool AppListView::AcceleratorPressed(const ui::Accelerator& accelerator) { DCHECK_EQ(ui::VKEY_ESCAPE, accelerator.key_code()); // If the ContentsView does not handle the back action, then this is the // top level, so we close the app list. if (!app_list_main_view_->contents_view()->Back()) { - if (IsFullscreenAppListEnabled()) { - SetState(CLOSED); - } else { - app_list_main_view_->Close(); - delegate_->Dismiss(); - } GetWidget()->Deactivate(); + CloseAppList(); } // Don't let DialogClientView handle the accelerator. @@ -680,11 +510,6 @@ speech_bounds.Inset(-speech_view_->GetInsets()); speech_view_->SetBoundsRect(speech_bounds); } - - if (IsFullscreenAppListEnabled()) { - app_list_main_view_->contents_view()->Layout(); - app_list_background_shield_->SetBoundsRect(contents_bounds); - } } void AppListView::SchedulePaintInRect(const gfx::Rect& rect) { @@ -693,31 +518,6 @@ GetBubbleFrameView()->SchedulePaint(); } -void AppListView::SetState(AppListState new_state) { - gfx::Rect new_widget_bounds = fullscreen_widget_->GetWindowBoundsInScreen(); - switch (new_state) { - case PEEKING: { - int display_height = display::Screen::GetScreen() - ->GetDisplayNearestView(parent_window()) - .work_area() - .bottom(); - int default_peeking_y = - display_height + kShelfSize - kPeekingAppListHeight; - new_widget_bounds.set_y(default_peeking_y); - break; - } - case FULLSCREEN: - new_widget_bounds.set_y(0); - break; - case CLOSED: - app_list_main_view_->Close(); - delegate_->Dismiss(); - break; - } - fullscreen_widget_->SetBounds(new_widget_bounds); - app_list_state_ = new_state; -} - void AppListView::OnWidgetDestroying(views::Widget* widget) { BubbleDialogDelegateView::OnWidgetDestroying(widget); if (delegate_ && widget == GetWidget()) @@ -802,21 +602,4 @@ } } -void AppListView::OnDisplayMetricsChanged(const display::Display& display, - uint32_t changed_metrics) { - if (!IsFullscreenAppListEnabled()) - return; - - // Set the |fullscreen_widget_| size to fit the new display metrics. - gfx::Size size = display::Screen::GetScreen() - ->GetDisplayNearestView(parent_window()) - .work_area() - .size(); - size.Enlarge(0, kShelfSize); - fullscreen_widget_->SetSize(size); - - // Update the |fullscreen_widget_| bounds to accomodate the new work area. - SetState(app_list_state_); -} - } // namespace app_list
diff --git a/ui/app_list/views/app_list_view.h b/ui/app_list/views/app_list_view.h index 84b0ead..3b657141 100644 --- a/ui/app_list/views/app_list_view.h +++ b/ui/app_list/views/app_list_view.h
@@ -9,18 +9,12 @@ #include "base/callback.h" #include "base/macros.h" -#include "base/scoped_observer.h" #include "build/build_config.h" #include "ui/app_list/app_list_export.h" #include "ui/app_list/speech_ui_model_observer.h" -#include "ui/display/display_observer.h" #include "ui/views/bubble/bubble_dialog_delegate.h" #include "ui/views/widget/widget.h" -namespace display { -class Screen; -} - namespace app_list { class ApplicationDragAndDropHost; class AppListMainView; @@ -38,28 +32,15 @@ // AppListView is the top-level view and controller of app list UI. It creates // and hosts a AppsGridView and passes AppListModel to it for display. class APP_LIST_EXPORT AppListView : public views::BubbleDialogDelegateView, - public SpeechUIModelObserver, - public display::DisplayObserver { + public SpeechUIModelObserver { public: - enum AppListState { - // If set, closes |app_list_main_view_| and dismisses the delegate. - CLOSED = 0, - - // The initial state for the app list. If set, the widget will peek over - // the shelf by kPeekingAppListHeight DIPs. - PEEKING, - - // If set, the widget will be repositioned to take up the whole screen. - FULLSCREEN, - }; - // Does not take ownership of |delegate|. explicit AppListView(AppListViewDelegate* delegate); ~AppListView() override; - // Initializes the widget as a bubble or fullscreen view depending on if the - // fullscreen app list feature is set. |parent| and |initial_apps_page| are - // used for both the bubble and fullscreen initialization. + // Initializes the widget as a bubble or fullscreen view depending on the + // presence of a cmd line switch. parent and initial_apps_page are used for + // both the bubble and fullscreen initialization. void Initialize(gfx::NativeView parent, int initial_apps_page); void SetBubbleArrow(views::BubbleBorder::Arrow arrow); @@ -77,6 +58,8 @@ // timer to show the UI when a maximum allowed wait time has expired. void ShowWhenReady(); + void CloseAppList(); + void UpdateBounds(); // Enables/disables a semi-transparent overlay over the app list (good for @@ -106,12 +89,6 @@ void Layout() override; void SchedulePaintInRect(const gfx::Rect& rect) override; - // Changes the app list state. - void SetState(AppListState new_state); - - bool is_fullscreen() const { return app_list_state_ == FULLSCREEN; } - AppListState app_list_state() const { return app_list_state_; } - private: friend class test::AppListViewTestApi; @@ -125,17 +102,6 @@ // Initializes the widget as a bubble. void InitializeBubble(gfx::NativeView parent, int initial_apps_page); - // Initializes |initial_drag_point_|. - void StartDrag(const gfx::Point& location); - - // Updates the bounds of the widget while maintaining the relative position - // of the top of the widget and the gesture. - void UpdateDrag(const gfx::Point& location); - - // Handles app list state transfers. If the drag was fast enough, ignore the - // release position and snap to the next state. - void EndDrag(const gfx::Point& location); - // Overridden from views::BubbleDialogDelegateView: void OnBeforeBubbleWidgetInit(views::Widget::InitParams* params, views::Widget* widget) const override; @@ -146,10 +112,6 @@ bool WidgetHasHitTestMask() const override; void GetWidgetHitTestMask(gfx::Path* mask) const override; - // Overridden from ui::EventHandler: - void OnMouseEvent(ui::MouseEvent* event) override; - void OnGestureEvent(ui::GestureEvent* event) override; - // Overridden from views::WidgetObserver: void OnWidgetDestroying(views::Widget* widget) override; void OnWidgetVisibilityChanged(views::Widget* widget, bool visible) override; @@ -158,31 +120,14 @@ void OnSpeechRecognitionStateChanged( SpeechRecognitionState new_state) override; - // Overridden from DisplayObserver: - void OnDisplayMetricsChanged(const display::Display& display, - uint32_t changed_metrics) override; - AppListViewDelegate* delegate_; // Weak. Owned by AppListService. AppListMainView* app_list_main_view_; SpeechView* speech_view_; - views::Widget* fullscreen_widget_ = nullptr; // Owned by AppListView. views::View* search_box_focus_host_; // Owned by the views hierarchy. views::Widget* search_box_widget_; // Owned by the app list's widget. SearchBoxView* search_box_view_; // Owned by |search_box_widget_|. - // Owned by the app list's widget. Null if the fullscreen app list is not - // enabled. - views::View* app_list_background_shield_ = nullptr; - // The gap between the initial gesture event and the top of the window. - gfx::Point initial_drag_point_; - // The velocity of the gesture event. - float last_fling_velocity_ = 0; - // The state of the app list, controlled via SetState(). - AppListState app_list_state_; - - // An observer that notifies AppListView when the display has changed. - ScopedObserver<display::Screen, display::DisplayObserver> display_observer_; // A semi-transparent white overlay that covers the app list while dialogs are // open.
diff --git a/ui/app_list/views/contents_view.cc b/ui/app_list/views/contents_view.cc index ff96d24..9a3a73b7 100644 --- a/ui/app_list/views/contents_view.cc +++ b/ui/app_list/views/contents_view.cc
@@ -29,15 +29,13 @@ namespace app_list { -ContentsView::ContentsView(AppListMainView* app_list_main_view, - AppListView* app_list_view) +ContentsView::ContentsView(AppListMainView* app_list_main_view) : model_(nullptr), apps_container_view_(nullptr), search_results_page_view_(nullptr), start_page_view_(nullptr), custom_page_view_(nullptr), app_list_main_view_(app_list_main_view), - app_list_view_(app_list_view), page_before_search_(0) { pagination_model_.SetTransitionDurations(kPageTransitionDurationInMs, kOverscrollPageTransitionDurationMs); @@ -66,8 +64,7 @@ } // Start page. - start_page_view_ = - new StartPageView(app_list_main_view_, view_delegate, app_list_view_); + start_page_view_ = new StartPageView(app_list_main_view_, view_delegate); AddLauncherPage(start_page_view_, AppListModel::STATE_START); // Search results UI.
diff --git a/ui/app_list/views/contents_view.h b/ui/app_list/views/contents_view.h index a27300fe..62a52cd2 100644 --- a/ui/app_list/views/contents_view.h +++ b/ui/app_list/views/contents_view.h
@@ -26,7 +26,6 @@ class AppsGridView; class AppListPage; -class AppListView; class ApplicationDragAndDropHost; class AppListFolderItem; class AppListMainView; @@ -45,7 +44,7 @@ class APP_LIST_EXPORT ContentsView : public views::View, public PaginationModelObserver { public: - ContentsView(AppListMainView* app_list_main_view, AppListView* app_list_view); + explicit ContentsView(AppListMainView* app_list_main_view); ~ContentsView() override; // Initialize the pages of the launcher. Should be called after @@ -192,9 +191,6 @@ // Parent view. Owned by the views hierarchy. AppListMainView* app_list_main_view_; - // Owned by the views hierarchy. - AppListView* const app_list_view_; - // Maps State onto |view_model_| indices. std::map<AppListModel::State, int> state_to_view_;
diff --git a/ui/app_list/views/search_box_view.cc b/ui/app_list/views/search_box_view.cc index 599f298e8..0d8aec2 100644 --- a/ui/app_list/views/search_box_view.cc +++ b/ui/app_list/views/search_box_view.cc
@@ -10,14 +10,12 @@ #include "base/memory/ptr_util.h" #include "build/build_config.h" #include "ui/app_list/app_list_constants.h" -#include "ui/app_list/app_list_features.h" #include "ui/app_list/app_list_model.h" #include "ui/app_list/app_list_switches.h" #include "ui/app_list/app_list_view_delegate.h" #include "ui/app_list/resources/grit/app_list_resources.h" #include "ui/app_list/search_box_model.h" #include "ui/app_list/speech_ui_model.h" -#include "ui/app_list/views/app_list_view.h" #include "ui/app_list/views/contents_view.h" #include "ui/app_list/views/search_box_view_delegate.h" #include "ui/base/ime/text_input_flags.h" @@ -36,7 +34,6 @@ #include "ui/views/layout/box_layout.h" #include "ui/views/layout/fill_layout.h" #include "ui/views/shadow_border.h" -#include "ui/views/widget/widget.h" namespace app_list { @@ -45,28 +42,16 @@ const int kPadding = 16; const int kInnerPadding = 24; const int kPreferredWidth = 360; -const int kPreferredWidthFullscreen = 544; const int kPreferredHeight = 48; const SkColor kHintTextColor = SkColorSetRGB(0xA0, 0xA0, 0xA0); const int kBackgroundBorderCornerRadius = 2; -const int kBackgroundBorderCornerRadiusFullscreen = 20; - -bool IsFullscreenAppListEnabled() { - // Cache this value to avoid repeated lookup. - static bool cached_value = features::IsFullscreenAppListEnabled(); - return cached_value; -} // A background that paints a solid white rounded rect with a thin grey border. class SearchBoxBackground : public views::Background { public: - SearchBoxBackground() - : background_border_corner_radius_( - IsFullscreenAppListEnabled() - ? kBackgroundBorderCornerRadiusFullscreen - : kBackgroundBorderCornerRadius) {} + SearchBoxBackground() {} ~SearchBoxBackground() override {} private: @@ -77,11 +62,9 @@ cc::PaintFlags flags; flags.setAntiAlias(true); flags.setColor(kSearchBoxBackground); - canvas->DrawRoundRect(bounds, background_border_corner_radius_, flags); + canvas->DrawRoundRect(bounds, kBackgroundBorderCornerRadius, flags); } - const int background_border_corner_radius_; - DISALLOW_COPY_AND_ASSIGN(SearchBoxBackground); }; @@ -131,8 +114,7 @@ }; SearchBoxView::SearchBoxView(SearchBoxViewDelegate* delegate, - AppListViewDelegate* view_delegate, - AppListView* app_list_view) + AppListViewDelegate* view_delegate) : delegate_(delegate), view_delegate_(view_delegate), model_(NULL), @@ -141,13 +123,9 @@ speech_button_(NULL), search_box_(new views::Textfield), contents_view_(NULL), - app_list_view_(app_list_view), focused_view_(FOCUS_SEARCH_BOX) { SetLayoutManager(new views::FillLayout); - SetPreferredSize(gfx::Size(IsFullscreenAppListEnabled() - ? kPreferredWidthFullscreen - : kPreferredWidth, - kPreferredHeight)); + SetPreferredSize(gfx::Size(kPreferredWidth, kPreferredHeight)); AddChildView(content_container_); SetShadow(GetShadowForZHeight(2)); @@ -345,11 +323,6 @@ UpdateModel(); view_delegate_->AutoLaunchCanceled(); NotifyQueryChanged(); - - if (IsFullscreenAppListEnabled() && !app_list_view_->is_fullscreen()) { - // If the app list is in the peeking state, switch it to fullscreen. - app_list_view_->SetState(AppListView::FULLSCREEN); - } } bool SearchBoxView::HandleKeyEvent(views::Textfield* sender,
diff --git a/ui/app_list/views/search_box_view.h b/ui/app_list/views/search_box_view.h index db647e9..8b5790bc 100644 --- a/ui/app_list/views/search_box_view.h +++ b/ui/app_list/views/search_box_view.h
@@ -31,7 +31,6 @@ }; class AppListModel; -class AppListView; class AppListViewDelegate; class SearchBoxModel; class SearchBoxViewDelegate; @@ -48,8 +47,7 @@ public SpeechUIModelObserver { public: SearchBoxView(SearchBoxViewDelegate* delegate, - AppListViewDelegate* view_delegate, - AppListView* app_list_view = nullptr); + AppListViewDelegate* view_delegate); ~SearchBoxView() override; void ModelChanged(); @@ -120,7 +118,6 @@ SearchBoxImageButton* speech_button_; // Owned by views hierarchy. views::Textfield* search_box_; // Owned by views hierarchy. views::View* contents_view_; // Owned by views hierarchy. - app_list::AppListView* app_list_view_; // Owned by views hierarchy. SearchBoxFocus focused_view_; // Which element has TAB'd focus.
diff --git a/ui/app_list/views/start_page_view.cc b/ui/app_list/views/start_page_view.cc index c9166f3..27dce46 100644 --- a/ui/app_list/views/start_page_view.cc +++ b/ui/app_list/views/start_page_view.cc
@@ -13,10 +13,8 @@ #include "base/strings/utf_string_conversions.h" #include "ui/accessibility/ax_node_data.h" #include "ui/app_list/app_list_constants.h" -#include "ui/app_list/app_list_features.h" #include "ui/app_list/app_list_item.h" #include "ui/app_list/app_list_model.h" -#include "ui/app_list/app_list_switches.h" #include "ui/app_list/app_list_view_delegate.h" #include "ui/app_list/search_result.h" #include "ui/app_list/views/all_apps_tile_item_view.h" @@ -54,7 +52,6 @@ constexpr int kTileSpacing = 7; constexpr int kNumStartPageTilesCols = 5; constexpr int kTilesHorizontalMarginLeft = 145; -constexpr int kCenterColumnOfStartPageAppGrid = 3; constexpr int kLauncherPageBackgroundWidth = 400; @@ -140,10 +137,7 @@ SetBackground(views::CreateSolidBackground(kLabelBackgroundColor)); all_apps_button_->SetHoverStyle(TileItemView::HOVER_STYLE_ANIMATE_SHADOW); all_apps_button_->SetParentBackgroundColor(kLabelBackgroundColor); - - CreateAppsGrid(features::IsFullscreenAppListEnabled() - ? kNumStartPageTilesFullscreen - : kNumStartPageTiles); + CreateAppsGrid(kNumStartPageTiles); } StartPageView::StartPageTilesContainer::~StartPageTilesContainer() { @@ -177,10 +171,7 @@ delete search_result_tile_views_[i]; search_result_tile_views_.clear(); RemoveChildView(all_apps_button_); - - CreateAppsGrid(features::IsFullscreenAppListEnabled() - ? kNumStartPageTilesFullscreen - : std::min(kNumStartPageTiles, display_results.size())); + CreateAppsGrid(std::min(kNumStartPageTiles, display_results.size())); } // Update the tile item results. @@ -251,19 +242,10 @@ search_result_tile_views_.emplace_back(tile_item); } + // Also add a special "all apps" button to the end of the container. all_apps_button_->UpdateIcon(); - if (features::IsFullscreenAppListEnabled()) { - // Also add a special "all apps" button to the middle of the next row of the - // container. + if (i % kNumStartPageTilesCols == 0) tiles_layout_manager->StartRow(0, 0); - tiles_layout_manager->SkipColumns(kCenterColumnOfStartPageAppGrid); - } else { - // Also add a special "all apps" button to the end of the next row of the - // container. - if (i % kNumStartPageTilesCols == 0) - tiles_layout_manager->StartRow(0, 0); - } - tiles_layout_manager->AddView(all_apps_button_); AddChildView(all_apps_button_); } @@ -271,8 +253,7 @@ //////////////////////////////////////////////////////////////////////////////// // StartPageView implementation: StartPageView::StartPageView(AppListMainView* app_list_main_view, - AppListViewDelegate* view_delegate, - AppListView* app_list_view) + AppListViewDelegate* view_delegate) : app_list_main_view_(app_list_main_view), view_delegate_(view_delegate), search_box_spacer_view_(new View()), @@ -281,8 +262,7 @@ view_delegate_->GetModel()->custom_launcher_page_name())), tiles_container_(new StartPageTilesContainer( app_list_main_view->contents_view(), - new AllAppsTileItemView(app_list_main_view_->contents_view(), - app_list_view), + new AllAppsTileItemView(app_list_main_view_->contents_view()), view_delegate)) { search_box_spacer_view_->SetPreferredSize(gfx::Size( kStartPageSearchBoxWidth, @@ -294,6 +274,7 @@ // The view containing the start page tiles. AddChildView(tiles_container_); + AddChildView(custom_launcher_page_background_); tiles_container_->SetResults(view_delegate_->GetModel()->results()); @@ -313,16 +294,11 @@ views::BoxLayout::CROSS_AXIS_ALIGNMENT_CENTER); instant_container_->SetLayoutManager(instant_layout_manager); - // Create the view for the Google Doodle if the fullscreen launcher is not - // enabled. - if (!features::IsFullscreenAppListEnabled()) { - views::View* web_view = view_delegate_->CreateStartPageWebView( - gfx::Size(kWebViewWidth, kWebViewHeight)); - - if (web_view) { - web_view->SetFocusBehavior(FocusBehavior::NEVER); - instant_container_->AddChildView(web_view); - } + views::View* web_view = view_delegate_->CreateStartPageWebView( + gfx::Size(kWebViewWidth, kWebViewHeight)); + if (web_view) { + web_view->SetFocusBehavior(FocusBehavior::NEVER); + instant_container_->AddChildView(web_view); } instant_container_->AddChildView(search_box_spacer_view_);
diff --git a/ui/app_list/views/start_page_view.h b/ui/app_list/views/start_page_view.h index ef68aa0d..28f9c2e 100644 --- a/ui/app_list/views/start_page_view.h +++ b/ui/app_list/views/start_page_view.h
@@ -16,7 +16,6 @@ namespace app_list { class AppListMainView; -class AppListView; class AppListViewDelegate; class CustomLauncherPageBackgroundView; class SearchResultTileItemView; @@ -26,8 +25,7 @@ class APP_LIST_EXPORT StartPageView : public AppListPage { public: StartPageView(AppListMainView* app_list_main_view, - AppListViewDelegate* view_delegate, - AppListView* app_list_view); + AppListViewDelegate* view_delegate); ~StartPageView() override; void Reset(); @@ -52,11 +50,11 @@ void OnGestureEvent(ui::GestureEvent* event) override; void OnScrollEvent(ui::ScrollEvent* event) override; + private: class StartPageTilesContainer; void InitInstantContainer(); - void MaybeOpenCustomLauncherPage(); void SetCustomLauncherPageSelected(bool selected);