diff --git a/BUILD.gn b/BUILD.gn index f9c6907..a310f481 100644 --- a/BUILD.gn +++ b/BUILD.gn
@@ -257,6 +257,10 @@ ] } + if (is_mac) { + deps += [ "//chrome/installer/gcapi_mac:gcapi_example" ] + } + if (is_android) { deps += [ "//base:base_junit_tests",
diff --git a/DEPS b/DEPS index c536aab3..86df34d 100644 --- a/DEPS +++ b/DEPS
@@ -40,7 +40,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. - 'skia_revision': '20b82524e7a7959803edd80cb0e6737629029ef2', + 'skia_revision': 'ec6ae52168ae4803c2312c362280f7f79e0d380e', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. @@ -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': '49f8dc5b1afc4f92110bf40b7639ee1138aa7240', + 'pdfium_revision': '00ab92f4c6cd045904a0f26d7e2c227217758f02', # 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': '13344fafc8814638210ca360d8ae8cf99cf1639b', + 'catapult_revision': 'b2c22b39ba7df300abaa789fb7ea0292d62044d3', # 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/browser/aw_safe_browsing_ui_manager.cc b/android_webview/browser/aw_safe_browsing_ui_manager.cc index c2ac657..fdcc6d3 100644 --- a/android_webview/browser/aw_safe_browsing_ui_manager.cc +++ b/android_webview/browser/aw_safe_browsing_ui_manager.cc
@@ -24,7 +24,7 @@ WebContents* web_contents = resource.web_contents_getter.Run(); // Check the size of the view UIManagerClient* client = UIManagerClient::FromWebContents(web_contents); - if (!client || !client->CanShowInterstitial()) { + if (!client || !client->CanShowBigInterstitial()) { LOG(WARNING) << "The view is not suitable to show the SB interstitial"; OnBlockingPageDone(std::vector<UnsafeResource>{resource}, false, web_contents, resource.url.GetWithEmptyPath());
diff --git a/android_webview/browser/aw_safe_browsing_ui_manager.h b/android_webview/browser/aw_safe_browsing_ui_manager.h index f09bdf68..2dd07b8 100644 --- a/android_webview/browser/aw_safe_browsing_ui_manager.h +++ b/android_webview/browser/aw_safe_browsing_ui_manager.h
@@ -21,7 +21,7 @@ static UIManagerClient* FromWebContents(content::WebContents* web_contents); // Whether this web contents can show an interstitial - virtual bool CanShowInterstitial() = 0; + virtual bool CanShowBigInterstitial() = 0; }; // Construction needs to happen on the UI thread.
diff --git a/android_webview/java/src/org/chromium/android_webview/AwContents.java b/android_webview/java/src/org/chromium/android_webview/AwContents.java index 9ebbb5b..95ef94d1 100644 --- a/android_webview/java/src/org/chromium/android_webview/AwContents.java +++ b/android_webview/java/src/org/chromium/android_webview/AwContents.java
@@ -80,6 +80,7 @@ import org.chromium.ui.base.PageTransition; import org.chromium.ui.base.ViewAndroidDelegate; import org.chromium.ui.base.WindowAndroid; +import org.chromium.ui.display.DisplayAndroid; import org.chromium.ui.display.DisplayAndroid.DisplayAndroidObserver; import java.io.File; @@ -119,6 +120,8 @@ private static final boolean FORCE_AUXILIARY_BITMAP_RENDERING = "goldfish".equals(Build.HARDWARE) || "ranchu".equals(Build.HARDWARE); + private static final double MIN_SCREEN_PERCENTAGE_FOR_INTERSTITIAL = 0.7; + /** * WebKit hit test related data structure. These are used to implement * getHitTestResult, requestFocusNodeHref, requestImageRef methods in WebView. @@ -2913,20 +2916,52 @@ } } - @CalledByNative - private boolean canShowInterstitial() { + /** + * Determine if at least one edge of the WebView extends over the edge of the device screen. + */ + private boolean extendsOffDeviceScreen() { int loc[] = new int[2]; mContainerView.getLocationOnScreen(loc); - // TODO(sgurun) implement a better strategy here. - if (mContainerView.getWidth() < 500 || mContainerView.getHeight() < 500) { - return false; + int x = loc[0]; + int y = loc[1]; + DisplayAndroid displayAndroid = mWindowAndroid.getWindowAndroid().getDisplay(); + if (x < 0 || y < 0 || x + mContainerView.getWidth() > displayAndroid.getDisplayWidth() + || y + mContainerView.getHeight() > displayAndroid.getDisplayHeight()) { + return true; } - if (mContainerView.getVisibility() != View.VISIBLE) { - return false; - } - // TODO(timvolodine) other potential improvements mentioned: - // consider content, not attached webviews, giant webviews, .. - return true; + return false; + } + + /** + * Determine if it's reasonable to show any sort of interstitial. If the WebView is not visible, + * the user may not be able to interact with the UI. + * @return true if the WebView is visible + */ + @VisibleForTesting + protected boolean canShowInterstitial() { + return mIsAttachedToWindow && mIsViewVisible; + } + + /** + * Determine if it's suitable to show the interstitial for browsers and main UIs. If the WebView + * is close to full-screen, we assume the app is using it as the main UI, so we show the same + * interstital Chrome uses. Otherwise, we assume the WebView is part of a larger composed page, + * and will show a different interstitial. + * @return true if the WebView should display the large interstitial + */ + @VisibleForTesting + @CalledByNative + protected boolean canShowBigInterstitial() { + if (!canShowInterstitial()) return false; + if (extendsOffDeviceScreen()) return false; + + DisplayAndroid displayAndroid = mWindowAndroid.getWindowAndroid().getDisplay(); + double percentOfScreenHeight = + (double) mContainerView.getHeight() / displayAndroid.getDisplayHeight(); + + // If the WebView is full width and most of the height, it's probably the main UI. + return mContainerView.getWidth() == displayAndroid.getDisplayWidth() + && percentOfScreenHeight >= MIN_SCREEN_PERCENTAGE_FOR_INTERSTITIAL; } @VisibleForTesting
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/SafeBrowsingTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/SafeBrowsingTest.java index fc4b69a..4672eaa3 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/SafeBrowsingTest.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/SafeBrowsingTest.java
@@ -9,9 +9,15 @@ import android.graphics.Bitmap; import android.graphics.Color; import android.support.test.filters.SmallTest; +import android.view.ViewGroup; import org.chromium.android_webview.AwBrowserContext; import org.chromium.android_webview.AwContents; +import org.chromium.android_webview.AwContents.DependencyFactory; +import org.chromium.android_webview.AwContents.InternalAccessDelegate; +import org.chromium.android_webview.AwContents.NativeDrawGLFunctorFactory; +import org.chromium.android_webview.AwContentsClient; +import org.chromium.android_webview.AwSettings; import org.chromium.android_webview.AwSwitches; import org.chromium.android_webview.AwWebContentsObserver; import org.chromium.android_webview.ErrorCodeConversionHelper; @@ -35,7 +41,7 @@ public class SafeBrowsingTest extends AwTestBase { private TestAwContentsClient mContentsClient; private AwTestContainerView mContainerView; - private AwContents mAwContents; + private MockAwContents mAwContents; private TestAwWebContentsObserver mWebContentsObserver; private EmbeddedTestServer mTestServer; @@ -122,12 +128,59 @@ } } + private static class MockAwContents extends AwContents { + private boolean mCanShowInterstitial; + private boolean mCanShowBigInterstitial; + + public MockAwContents(AwBrowserContext browserContext, ViewGroup containerView, + Context context, InternalAccessDelegate internalAccessAdapter, + NativeDrawGLFunctorFactory nativeDrawGLFunctorFactory, + AwContentsClient contentsClient, AwSettings settings, + DependencyFactory dependencyFactory) { + super(browserContext, containerView, context, internalAccessAdapter, + nativeDrawGLFunctorFactory, contentsClient, settings, dependencyFactory); + mCanShowInterstitial = true; + mCanShowBigInterstitial = true; + } + + public void setCanShowInterstitial(boolean able) { + mCanShowInterstitial = able; + } + + public void setCanShowBigInterstitial(boolean able) { + mCanShowBigInterstitial = able; + } + + @Override + protected boolean canShowInterstitial() { + return mCanShowInterstitial; + } + + @Override + protected boolean canShowBigInterstitial() { + return mCanShowBigInterstitial; + } + } + + private static class SafeBrowsingDependencyFactory extends AwTestBase.TestDependencyFactory { + @Override + public AwContents createAwContents(AwBrowserContext browserContext, ViewGroup containerView, + Context context, InternalAccessDelegate internalAccessAdapter, + NativeDrawGLFunctorFactory nativeDrawGLFunctorFactory, + AwContentsClient contentsClient, AwSettings settings, + DependencyFactory dependencyFactory) { + return new MockAwContents(browserContext, containerView, context, internalAccessAdapter, + nativeDrawGLFunctorFactory, contentsClient, settings, dependencyFactory); + } + } + @Override public void setUp() throws Exception { super.setUp(); mContentsClient = new TestAwContentsClient(); - mContainerView = createAwTestContainerViewOnMainSync(mContentsClient); - mAwContents = mContainerView.getAwContents(); + mContainerView = createAwTestContainerViewOnMainSync( + mContentsClient, false, new SafeBrowsingDependencyFactory()); + mAwContents = (MockAwContents) mContainerView.getAwContents(); mTestServer = EmbeddedTestServer.createAndStartServer(getInstrumentation().getContext()); getInstrumentation().runOnMainSync(new Runnable() { @@ -351,4 +404,35 @@ != GraphicsTestUtils.getPixelColorAtCenterOfView( mAwContents, mContainerView)); } + + @SmallTest + @Feature({"AndroidWebView"}) + @CommandLineFlags.Add(AwSwitches.WEBVIEW_ENABLE_SAFEBROWSING_SUPPORT) + public void testSafeBrowsingShowsNetworkErrorForInvisibleViews() throws Throwable { + mAwContents.setCanShowInterstitial(false); + mAwContents.setCanShowBigInterstitial(false); + final String responseUrl = mTestServer.getURL(MALWARE_HTML_PATH); + OnReceivedError2Helper errorHelper = mContentsClient.getOnReceivedError2Helper(); + int errorCount = errorHelper.getCallCount(); + loadUrlAsync(mAwContents, responseUrl); + errorHelper.waitForCallback(errorCount); + assertEquals(ErrorCodeConversionHelper.ERROR_UNKNOWN, errorHelper.getError().errorCode); + assertEquals("Network error is for the malicious page", responseUrl, + errorHelper.getRequest().url); + } + + @SmallTest + @Feature({"AndroidWebView"}) + @CommandLineFlags.Add(AwSwitches.WEBVIEW_ENABLE_SAFEBROWSING_SUPPORT) + public void testSafeBrowsingShowsNetworkErrorForOddSizedViews() throws Throwable { + mAwContents.setCanShowBigInterstitial(false); + final String responseUrl = mTestServer.getURL(MALWARE_HTML_PATH); + OnReceivedError2Helper errorHelper = mContentsClient.getOnReceivedError2Helper(); + int errorCount = errorHelper.getCallCount(); + loadUrlAsync(mAwContents, responseUrl); + errorHelper.waitForCallback(errorCount); + assertEquals(ErrorCodeConversionHelper.ERROR_UNKNOWN, errorHelper.getError().errorCode); + assertEquals("Network error is for the malicious page", responseUrl, + errorHelper.getRequest().url); + } }
diff --git a/android_webview/native/aw_contents.cc b/android_webview/native/aw_contents.cc index 5d34868..f357a4a9 100644 --- a/android_webview/native/aw_contents.cc +++ b/android_webview/native/aw_contents.cc
@@ -1407,12 +1407,12 @@ browser_view_renderer_.SetActiveCompositorID(compositor_id); } -bool AwContents::CanShowInterstitial() { +bool AwContents::CanShowBigInterstitial() { JNIEnv* env = AttachCurrentThread(); const ScopedJavaLocalRef<jobject> obj = java_ref_.get(env); if (obj.is_null()) return false; - return Java_AwContents_canShowInterstitial(env, obj); + return Java_AwContents_canShowBigInterstitial(env, obj); } void AwContents::CallProceedOnInterstitialForTesting(
diff --git a/android_webview/native/aw_contents.h b/android_webview/native/aw_contents.h index 0fa1fcc9..1248bd1 100644 --- a/android_webview/native/aw_contents.h +++ b/android_webview/native/aw_contents.h
@@ -364,7 +364,7 @@ void RenderProcessReady(content::RenderProcessHost* host) override; // AwSafeBrowsingUIManager::UIManagerClient implementation - bool CanShowInterstitial() override; + bool CanShowBigInterstitial() override; void CallProceedOnInterstitialForTesting( JNIEnv* env,
diff --git a/ash/app_list/app_list_presenter_delegate.cc b/ash/app_list/app_list_presenter_delegate.cc index dbc28e6..3a1f918c 100644 --- a/ash/app_list/app_list_presenter_delegate.cc +++ b/ash/app_list/app_list_presenter_delegate.cc
@@ -99,11 +99,13 @@ aura::Window* root_window = wm_root_window->aura_window(); aura::Window* container = GetRootWindowController(root_window) ->GetContainer(kShellWindowId_AppListContainer); - view->InitAsBubble(container, current_apps_page); - // The app list is centered over the display. - view->SetAnchorPoint(GetCenterOfDisplayForWindow( - wm_root_window, GetMinimumBoundsHeightForAppList(view))); + view->Initialize(container, current_apps_page); + + if (!app_list::switches::IsFullscreenAppListEnabled()) { + view->MaybeSetAnchorPoint(GetCenterOfDisplayForWindow( + wm_root_window, GetMinimumBoundsHeightForAppList(view))); + } keyboard::KeyboardController* keyboard_controller = keyboard::KeyboardController::GetInstance(); if (keyboard_controller) @@ -148,7 +150,7 @@ return; view_->UpdateBounds(); - view_->SetAnchorPoint(GetCenterOfDisplayForWindow( + view_->MaybeSetAnchorPoint(GetCenterOfDisplayForWindow( WmWindow::Get(view_->GetWidget()->GetNativeWindow()), GetMinimumBoundsHeightForAppList(view_))); }
diff --git a/ash/app_list/app_list_presenter_delegate_unittest.cc b/ash/app_list/app_list_presenter_delegate_unittest.cc index d554816..00525dc 100644 --- a/ash/app_list/app_list_presenter_delegate_unittest.cc +++ b/ash/app_list/app_list_presenter_delegate_unittest.cc
@@ -4,6 +4,7 @@ #include <memory> +#include "ash/ash_switches.h" #include "ash/public/cpp/shell_window_ids.h" #include "ash/shell.h" #include "ash/shell_port.h" @@ -11,7 +12,9 @@ #include "ash/test/test_app_list_view_presenter_impl.h" #include "ash/wm/window_util.h" #include "ash/wm_window.h" +#include "base/command_line.h" #include "base/macros.h" +#include "ui/app_list/app_list_switches.h" #include "ui/app_list/views/app_list_view.h" #include "ui/aura/test/test_windows.h" #include "ui/aura/window.h" @@ -26,9 +29,15 @@ return display::Screen::GetScreen()->GetPrimaryDisplay().id(); } +void SetFullscreenAppListSwitch() { + base::CommandLine::ForCurrentProcess()->AppendSwitch( + app_list::switches::kEnableFullscreenAppList); +} + } // namespace -class AppListPresenterDelegateTest : public test::AshTestBase { +class AppListPresenterDelegateTest : public test::AshTestBase, + public testing::WithParamInterface<bool> { public: AppListPresenterDelegateTest() {} ~AppListPresenterDelegateTest() override {} @@ -41,18 +50,29 @@ void SetUp() override { AshTestBase::SetUp(); + // If the current test is parameterized. + if (testing::UnitTest::GetInstance()->current_test_info()->value_param()) { + test_with_fullscreen_ = GetParam(); + if (test_with_fullscreen_) + SetFullscreenAppListSwitch(); + } // Make the display big enough to hold the app list. UpdateDisplay("1024x768"); } private: test::TestAppListViewPresenterImpl app_list_presenter_impl_; + bool test_with_fullscreen_; DISALLOW_COPY_AND_ASSIGN(AppListPresenterDelegateTest); }; +// Instantiate the Boolean which is used to toggle the Fullscreen app list in +// the parameterized tests. +INSTANTIATE_TEST_CASE_P(, AppListPresenterDelegateTest, testing::Bool()); + // Tests that app launcher hides when focus moves to a normal window. -TEST_F(AppListPresenterDelegateTest, HideOnFocusOut) { +TEST_P(AppListPresenterDelegateTest, HideOnFocusOut) { app_list_presenter_impl()->Show(GetPrimaryDisplayId()); EXPECT_TRUE(app_list_presenter_impl()->GetTargetVisibility()); @@ -64,7 +84,7 @@ // Tests that app launcher remains visible when focus is moved to a different // window in kShellWindowId_AppListContainer. -TEST_F(AppListPresenterDelegateTest, +TEST_P(AppListPresenterDelegateTest, RemainVisibleWhenFocusingToApplistContainer) { app_list_presenter_impl()->Show(GetPrimaryDisplayId()); EXPECT_TRUE(app_list_presenter_impl()->GetTargetVisibility()); @@ -122,7 +142,7 @@ // Tests opening the app launcher on a non-primary display, then deleting the // display. -TEST_F(AppListPresenterDelegateTest, NonPrimaryDisplay) { +TEST_P(AppListPresenterDelegateTest, NonPrimaryDisplay) { // Set up a screen with two displays (horizontally adjacent). UpdateDisplay("1024x768,1024x768"); @@ -156,10 +176,12 @@ // from the anchor (center) and height. There isn't a bounds rect that gives // the actual app list position (the widget bounds include the bubble border // which is much bigger than the actual app list size). + app_list::AppListView* app_list = app_list_presenter_impl()->GetView(); int app_list_view_top = app_list->anchor_rect().y() - app_list->bounds().height() / 2; const int kMinimalAppListMargin = 10; + EXPECT_GE(app_list_view_top, kMinimalAppListMargin); }
diff --git a/base/task_scheduler/scheduler_worker_pool_impl.h b/base/task_scheduler/scheduler_worker_pool_impl.h index 7b285a5..6fc5ee05 100644 --- a/base/task_scheduler/scheduler_worker_pool_impl.h +++ b/base/task_scheduler/scheduler_worker_pool_impl.h
@@ -38,16 +38,19 @@ class DelayedTaskManager; class TaskTracker; -// A pool of workers that run Tasks. This class is thread-safe. +// A pool of workers that run Tasks. +// +// The pool doesn't create threads until Start() is called. Tasks can be posted +// at any time but will not run until after Start() is called. +// +// This class is thread-safe. class BASE_EXPORT SchedulerWorkerPoolImpl : public SchedulerWorkerPool { public: // Callback invoked when a Sequence isn't empty after a worker pops a Task // from it. using ReEnqueueSequenceCallback = Callback<void(scoped_refptr<Sequence>)>; - // Constructs a pool without workers. Tasks can be posted to the pool, but - // they won't run until workers are created. To create workers and start - // running tasks, call Start(). + // Constructs a pool without workers. // // |name| is used to label the pool's threads ("TaskScheduler" + |name| + // index) and histograms ("TaskScheduler." + histogram name + "." + |name| +
diff --git a/base/task_scheduler/task_scheduler.cc b/base/task_scheduler/task_scheduler.cc index e6181dfb..c1eb432 100644 --- a/base/task_scheduler/task_scheduler.cc +++ b/base/task_scheduler/task_scheduler.cc
@@ -7,6 +7,7 @@ #include <algorithm> #include "base/logging.h" +#include "base/memory/ptr_util.h" #include "base/sys_info.h" #include "base/task_scheduler/scheduler_worker_pool_params.h" #include "base/task_scheduler/task_scheduler_impl.h" @@ -68,7 +69,8 @@ void TaskScheduler::CreateAndSetDefaultTaskScheduler( StringPiece name, const InitParams& init_params) { - SetInstance(internal::TaskSchedulerImpl::Create(name, init_params)); + SetInstance(MakeUnique<internal::TaskSchedulerImpl>(name)); + GetInstance()->Start(init_params); } // static
diff --git a/base/task_scheduler/task_scheduler.h b/base/task_scheduler/task_scheduler.h index 9c7207ef..3d3d5eb0 100644 --- a/base/task_scheduler/task_scheduler.h +++ b/base/task_scheduler/task_scheduler.h
@@ -33,9 +33,16 @@ class HistogramBase; // Interface for a task scheduler and static methods to manage the instance used -// by the post_task.h API. Note: all base/task_scheduler users should go through -// post_task.h instead of TaskScheduler except for the one callsite per process -// which manages the process' instance. +// by the post_task.h API. +// +// The task scheduler doesn't create threads until Start() is called. Tasks can +// be posted at any time but will not run until after Start() is called. +// +// The instance methods of this class are thread-safe. +// +// Note: All base/task_scheduler users should go through post_task.h instead of +// TaskScheduler except for the one callsite per process which manages the +// process's instance. class BASE_EXPORT TaskScheduler { public: struct BASE_EXPORT InitParams { @@ -59,6 +66,10 @@ // returned. virtual ~TaskScheduler() = default; + // Allows the task scheduler to create threads and run tasks following the + // |init_params| specification. CHECKs on failure. + virtual void Start(const InitParams& init_params) = 0; + // Posts |task| with a |delay| and specific |traits|. |delay| can be zero. // For one off tasks that don't require a TaskRunner. virtual void PostDelayedTaskWithTraits(
diff --git a/base/task_scheduler/task_scheduler_impl.cc b/base/task_scheduler/task_scheduler_impl.cc index 7a7786e..e9ff5135 100644 --- a/base/task_scheduler/task_scheduler_impl.cc +++ b/base/task_scheduler/task_scheduler_impl.cc
@@ -54,13 +54,29 @@ } // namespace -// static -std::unique_ptr<TaskSchedulerImpl> TaskSchedulerImpl::Create( - StringPiece name, - const TaskScheduler::InitParams& init_params) { - auto task_scheduler = WrapUnique(new TaskSchedulerImpl(name)); - task_scheduler->Initialize(init_params); - return task_scheduler; +TaskSchedulerImpl::TaskSchedulerImpl(StringPiece name) + : name_(name), + service_thread_("TaskSchedulerServiceThread"), + single_thread_task_runner_manager_(&task_tracker_, + &delayed_task_manager_) { + static_assert(arraysize(worker_pools_) == ENVIRONMENT_COUNT, + "The size of |worker_pools_| must match ENVIRONMENT_COUNT."); + static_assert( + arraysize(kEnvironmentParams) == ENVIRONMENT_COUNT, + "The size of |kEnvironmentParams| must match ENVIRONMENT_COUNT."); + + // Callback invoked by workers to re-enqueue a sequence in the appropriate + // PriorityQueue. + const auto reenqueue_sequence_callback = BindRepeating( + &TaskSchedulerImpl::ReEnqueueSequenceCallback, Unretained(this)); + + for (int environment_type = 0; environment_type < ENVIRONMENT_COUNT; + ++environment_type) { + worker_pools_[environment_type] = MakeUnique<SchedulerWorkerPoolImpl>( + name_ + kEnvironmentParams[environment_type].name_suffix, + kEnvironmentParams[environment_type].priority_hint, + reenqueue_sequence_callback, &task_tracker_, &delayed_task_manager_); + } } TaskSchedulerImpl::~TaskSchedulerImpl() { @@ -69,6 +85,40 @@ #endif } +void TaskSchedulerImpl::Start(const TaskScheduler::InitParams& init_params) { + // Start the service thread. On platforms that support it (POSIX except NaCL + // SFI), the service thread runs a MessageLoopForIO which is used to support + // FileDescriptorWatcher in the scope in which tasks run. + Thread::Options service_thread_options; + service_thread_options.message_loop_type = +#if defined(OS_POSIX) && !defined(OS_NACL_SFI) + MessageLoop::TYPE_IO; +#else + MessageLoop::TYPE_DEFAULT; +#endif + service_thread_options.timer_slack = TIMER_SLACK_MAXIMUM; + CHECK(service_thread_.StartWithOptions(service_thread_options)); + +#if defined(OS_POSIX) && !defined(OS_NACL_SFI) + // Needs to happen after starting the service thread to get its + // message_loop(). + task_tracker_.set_watch_file_descriptor_message_loop( + static_cast<MessageLoopForIO*>(service_thread_.message_loop())); +#endif + + // Needs to happen after starting the service thread to get its task_runner(). + delayed_task_manager_.Start(service_thread_.task_runner()); + + single_thread_task_runner_manager_.Start(); + + worker_pools_[BACKGROUND]->Start(init_params.background_worker_pool_params); + worker_pools_[BACKGROUND_BLOCKING]->Start( + init_params.background_blocking_worker_pool_params); + worker_pools_[FOREGROUND]->Start(init_params.foreground_worker_pool_params); + worker_pools_[FOREGROUND_BLOCKING]->Start( + init_params.foreground_blocking_worker_pool_params); +} + void TaskSchedulerImpl::PostDelayedTaskWithTraits( const tracked_objects::Location& from_here, const TaskTraits& traits, @@ -150,76 +200,6 @@ #endif } -TaskSchedulerImpl::TaskSchedulerImpl(StringPiece name) - : name_(name), - service_thread_("TaskSchedulerServiceThread"), - single_thread_task_runner_manager_(&task_tracker_, - &delayed_task_manager_) {} - -void TaskSchedulerImpl::Initialize( - const TaskScheduler::InitParams& init_params) { - // Start the service thread. On platforms that support it (POSIX except NaCL - // SFI), the service thread runs a MessageLoopForIO which is used to support - // FileDescriptorWatcher in the scope in which tasks run. - Thread::Options service_thread_options; - service_thread_options.message_loop_type = -#if defined(OS_POSIX) && !defined(OS_NACL_SFI) - MessageLoop::TYPE_IO; -#else - MessageLoop::TYPE_DEFAULT; -#endif - service_thread_options.timer_slack = TIMER_SLACK_MAXIMUM; - CHECK(service_thread_.StartWithOptions(service_thread_options)); - -#if defined(OS_POSIX) && !defined(OS_NACL_SFI) - // Needs to happen after starting the service thread to get its - // message_loop(). - task_tracker_.set_watch_file_descriptor_message_loop( - static_cast<MessageLoopForIO*>(service_thread_.message_loop())); -#endif - - // Needs to happen after starting the service thread to get its task_runner(). - delayed_task_manager_.Start(service_thread_.task_runner()); - - single_thread_task_runner_manager_.Start(); - - // Callback invoked by workers to re-enqueue a sequence in the appropriate - // PriorityQueue. - const SchedulerWorkerPoolImpl::ReEnqueueSequenceCallback - re_enqueue_sequence_callback = - Bind(&TaskSchedulerImpl::ReEnqueueSequenceCallback, Unretained(this)); - - // Order must match the EnvironmentType enum. - const SchedulerWorkerPoolParams* worker_pool_params[] = { - &init_params.background_worker_pool_params, - &init_params.background_blocking_worker_pool_params, - &init_params.foreground_worker_pool_params, - &init_params.foreground_blocking_worker_pool_params}; - - static_assert(arraysize(worker_pools_) == ENVIRONMENT_COUNT, - "The size of |worker_pools_| must match ENVIRONMENT_COUNT."); - static_assert( - arraysize(kEnvironmentParams) == ENVIRONMENT_COUNT, - "The size of |kEnvironmentParams| must match ENVIRONMENT_COUNT."); - static_assert( - arraysize(worker_pool_params) == ENVIRONMENT_COUNT, - "The size of |worker_pool_params| must match ENVIRONMENT_COUNT."); - - // Start worker pools. - for (int environment_type = 0; environment_type < ENVIRONMENT_COUNT; - ++environment_type) { - // Passing pointers to objects owned by |this| to the constructor of - // SchedulerWorkerPoolImpl is safe because a TaskSchedulerImpl can't be - // deleted before all its worker pools have been joined. - worker_pools_[environment_type] = MakeUnique<SchedulerWorkerPoolImpl>( - name_ + kEnvironmentParams[environment_type].name_suffix, - kEnvironmentParams[environment_type].priority_hint, - re_enqueue_sequence_callback, &task_tracker_, &delayed_task_manager_); - worker_pools_[environment_type]->Start( - *worker_pool_params[environment_type]); - } -} - SchedulerWorkerPoolImpl* TaskSchedulerImpl::GetWorkerPoolForTraits( const TaskTraits& traits) const { return worker_pools_[GetEnvironmentIndexForTraits(traits)].get();
diff --git a/base/task_scheduler/task_scheduler_impl.h b/base/task_scheduler/task_scheduler_impl.h index 7460cb1a..1307573 100644 --- a/base/task_scheduler/task_scheduler_impl.h +++ b/base/task_scheduler/task_scheduler_impl.h
@@ -38,17 +38,12 @@ // Default TaskScheduler implementation. This class is thread-safe. class BASE_EXPORT TaskSchedulerImpl : public TaskScheduler { public: - // Creates and returns an initialized TaskSchedulerImpl. CHECKs on failure. - // |name| is used to label threads and histograms. It should identify the - // component that creates the TaskScheduler. |init_params| contains params to - // initialize worker pools. - static std::unique_ptr<TaskSchedulerImpl> Create( - StringPiece name, - const TaskScheduler::InitParams& init_params); - + // |name| is used to label threads and histograms. + explicit TaskSchedulerImpl(StringPiece name); ~TaskSchedulerImpl() override; // TaskScheduler: + void Start(const TaskScheduler::InitParams& init_params) override; void PostDelayedTaskWithTraits(const tracked_objects::Location& from_here, const TaskTraits& traits, OnceClosure task, @@ -71,10 +66,6 @@ void JoinForTesting() override; private: - explicit TaskSchedulerImpl(StringPiece name); - - void Initialize(const TaskScheduler::InitParams& init_params); - // Returns the worker pool that runs Tasks with |traits|. SchedulerWorkerPoolImpl* GetWorkerPoolForTraits( const TaskTraits& traits) const;
diff --git a/base/task_scheduler/task_scheduler_impl_unittest.cc b/base/task_scheduler/task_scheduler_impl_unittest.cc index 04ddc6f..b8d8fad 100644 --- a/base/task_scheduler/task_scheduler_impl_unittest.cc +++ b/base/task_scheduler/task_scheduler_impl_unittest.cc
@@ -178,9 +178,9 @@ class TaskSchedulerImplTest : public testing::TestWithParam<TraitsExecutionModePair> { protected: - TaskSchedulerImplTest() = default; + TaskSchedulerImplTest() : scheduler_("Test") {} - void SetUp() override { + void StartTaskScheduler() { using StandbyThreadPolicy = SchedulerWorkerPoolParams::StandbyThreadPolicy; constexpr TimeDelta kSuggestedReclaimTime = TimeDelta::FromSeconds(30); @@ -189,22 +189,20 @@ constexpr int kMaxNumForegroundThreads = 4; constexpr int kMaxNumForegroundBlockingThreads = 12; - scheduler_ = TaskSchedulerImpl::Create( - "Test", {{StandbyThreadPolicy::LAZY, kMaxNumBackgroundThreads, - kSuggestedReclaimTime}, - {StandbyThreadPolicy::LAZY, kMaxNumBackgroundBlockingThreads, - kSuggestedReclaimTime}, - {StandbyThreadPolicy::LAZY, kMaxNumForegroundThreads, - kSuggestedReclaimTime}, - {StandbyThreadPolicy::LAZY, kMaxNumForegroundBlockingThreads, - kSuggestedReclaimTime}}); - - ASSERT_TRUE(scheduler_); + scheduler_.Start( + {{StandbyThreadPolicy::LAZY, kMaxNumBackgroundThreads, + kSuggestedReclaimTime}, + {StandbyThreadPolicy::LAZY, kMaxNumBackgroundBlockingThreads, + kSuggestedReclaimTime}, + {StandbyThreadPolicy::LAZY, kMaxNumForegroundThreads, + kSuggestedReclaimTime}, + {StandbyThreadPolicy::LAZY, kMaxNumForegroundBlockingThreads, + kSuggestedReclaimTime}}); } - void TearDown() override { scheduler_->JoinForTesting(); } + void TearDown() override { scheduler_.JoinForTesting(); } - std::unique_ptr<TaskSchedulerImpl> scheduler_; + TaskSchedulerImpl scheduler_; private: DISALLOW_COPY_AND_ASSIGN(TaskSchedulerImplTest); @@ -216,9 +214,10 @@ // TaskTraits and no delay runs on a thread with the expected priority and I/O // restrictions. The ExecutionMode parameter is ignored by this test. TEST_P(TaskSchedulerImplTest, PostDelayedTaskWithTraitsNoDelay) { + StartTaskScheduler(); WaitableEvent task_ran(WaitableEvent::ResetPolicy::MANUAL, WaitableEvent::InitialState::NOT_SIGNALED); - scheduler_->PostDelayedTaskWithTraits( + scheduler_.PostDelayedTaskWithTraits( FROM_HERE, GetParam().traits, BindOnce(&VerifyTaskEnvironmentAndSignalEvent, GetParam().traits, Unretained(&task_ran)), @@ -231,9 +230,10 @@ // and I/O restrictions after the delay expires. The ExecutionMode parameter is // ignored by this test. TEST_P(TaskSchedulerImplTest, PostDelayedTaskWithTraitsWithDelay) { + StartTaskScheduler(); WaitableEvent task_ran(WaitableEvent::ResetPolicy::MANUAL, WaitableEvent::InitialState::NOT_SIGNALED); - scheduler_->PostDelayedTaskWithTraits( + scheduler_.PostDelayedTaskWithTraits( FROM_HERE, GetParam().traits, BindOnce(&VerifyTimeAndTaskEnvironmentAndSignalEvent, GetParam().traits, TimeTicks::Now() + TestTimeouts::tiny_timeout(), @@ -246,9 +246,10 @@ // ExecutionMode run on a thread with the expected priority and I/O restrictions // and respect the characteristics of their ExecutionMode. TEST_P(TaskSchedulerImplTest, PostTasksViaTaskRunner) { + StartTaskScheduler(); test::TestTaskFactory factory( - CreateTaskRunnerWithTraitsAndExecutionMode( - scheduler_.get(), GetParam().traits, GetParam().execution_mode), + CreateTaskRunnerWithTraitsAndExecutionMode(&scheduler_, GetParam().traits, + GetParam().execution_mode), GetParam().execution_mode); EXPECT_FALSE(factory.task_runner()->RunsTasksOnCurrentThread()); @@ -261,6 +262,75 @@ factory.WaitForAllTasksToRun(); } +// Verifies that a task posted via PostDelayedTaskWithTraits without a delay +// doesn't run before Start() is called. +TEST_P(TaskSchedulerImplTest, PostDelayedTaskWithTraitsNoDelayBeforeStart) { + WaitableEvent task_running(WaitableEvent::ResetPolicy::MANUAL, + WaitableEvent::InitialState::NOT_SIGNALED); + scheduler_.PostDelayedTaskWithTraits( + FROM_HERE, GetParam().traits, + BindOnce(&VerifyTaskEnvironmentAndSignalEvent, GetParam().traits, + Unretained(&task_running)), + TimeDelta()); + + // Wait a little bit to make sure that the task isn't scheduled before + // Start(). Note: This test won't catch a case where the task runs just after + // the check and before Start(). However, we expect the test to be flaky if + // the tested code allows that to happen. + PlatformThread::Sleep(TestTimeouts::tiny_timeout()); + EXPECT_FALSE(task_running.IsSignaled()); + + StartTaskScheduler(); + task_running.Wait(); +} + +// Verifies that a task posted via PostDelayedTaskWithTraits with a delay +// doesn't run before Start() is called. +TEST_P(TaskSchedulerImplTest, PostDelayedTaskWithTraitsWithDelayBeforeStart) { + WaitableEvent task_running(WaitableEvent::ResetPolicy::MANUAL, + WaitableEvent::InitialState::NOT_SIGNALED); + scheduler_.PostDelayedTaskWithTraits( + FROM_HERE, GetParam().traits, + BindOnce(&VerifyTimeAndTaskEnvironmentAndSignalEvent, GetParam().traits, + TimeTicks::Now() + TestTimeouts::tiny_timeout(), + Unretained(&task_running)), + TestTimeouts::tiny_timeout()); + + // Wait a little bit to make sure that the task isn't scheduled before + // Start(). Note: This test won't catch a case where the task runs just after + // the check and before Start(). However, we expect the test to be flaky if + // the tested code allows that to happen. + PlatformThread::Sleep(TestTimeouts::tiny_timeout()); + EXPECT_FALSE(task_running.IsSignaled()); + + StartTaskScheduler(); + task_running.Wait(); +} + +// Verifies that a task posted via a TaskRunner doesn't run before Start() is +// called. +TEST_P(TaskSchedulerImplTest, PostTaskViaTaskRunnerBeforeStart) { + WaitableEvent task_running(WaitableEvent::ResetPolicy::MANUAL, + WaitableEvent::InitialState::NOT_SIGNALED); + CreateTaskRunnerWithTraitsAndExecutionMode(&scheduler_, GetParam().traits, + GetParam().execution_mode) + ->PostTask(FROM_HERE, + BindOnce(&VerifyTaskEnvironmentAndSignalEvent, + GetParam().traits, Unretained(&task_running))); + + // Wait a little bit to make sure that the task isn't scheduled before + // Start(). Note: This test won't catch a case where the task runs just after + // the check and before Start(). However, we expect the test to be flaky if + // the tested code allows that to happen. + PlatformThread::Sleep(TestTimeouts::tiny_timeout()); + EXPECT_FALSE(task_running.IsSignaled()); + + StartTaskScheduler(); + + // This should not hang if the task is scheduled after Start(). + task_running.Wait(); +} + INSTANTIATE_TEST_CASE_P(OneTraitsExecutionModePair, TaskSchedulerImplTest, ::testing::ValuesIn(GetTraitsExecutionModePairs())); @@ -270,11 +340,12 @@ // the expected priority and I/O restrictions and respects the characteristics // of its ExecutionMode. TEST_F(TaskSchedulerImplTest, MultipleTraitsExecutionModePairs) { + StartTaskScheduler(); std::vector<std::unique_ptr<ThreadPostingTasks>> threads_posting_tasks; for (const auto& traits_execution_mode_pair : GetTraitsExecutionModePairs()) { - threads_posting_tasks.push_back(WrapUnique(new ThreadPostingTasks( - scheduler_.get(), traits_execution_mode_pair.traits, - traits_execution_mode_pair.execution_mode))); + threads_posting_tasks.push_back(WrapUnique( + new ThreadPostingTasks(&scheduler_, traits_execution_mode_pair.traits, + traits_execution_mode_pair.execution_mode))); threads_posting_tasks.back()->Start(); } @@ -285,32 +356,34 @@ } TEST_F(TaskSchedulerImplTest, GetMaxConcurrentTasksWithTraitsDeprecated) { - EXPECT_EQ(1, scheduler_->GetMaxConcurrentTasksWithTraitsDeprecated( + StartTaskScheduler(); + EXPECT_EQ(1, scheduler_.GetMaxConcurrentTasksWithTraitsDeprecated( TaskTraits().WithPriority(TaskPriority::BACKGROUND))); EXPECT_EQ( - 3, scheduler_->GetMaxConcurrentTasksWithTraitsDeprecated( + 3, scheduler_.GetMaxConcurrentTasksWithTraitsDeprecated( TaskTraits().WithPriority(TaskPriority::BACKGROUND).MayBlock())); - EXPECT_EQ(4, scheduler_->GetMaxConcurrentTasksWithTraitsDeprecated( + EXPECT_EQ(4, scheduler_.GetMaxConcurrentTasksWithTraitsDeprecated( TaskTraits().WithPriority(TaskPriority::USER_VISIBLE))); EXPECT_EQ( 12, - scheduler_->GetMaxConcurrentTasksWithTraitsDeprecated( + scheduler_.GetMaxConcurrentTasksWithTraitsDeprecated( TaskTraits().WithPriority(TaskPriority::USER_VISIBLE).MayBlock())); - EXPECT_EQ(4, scheduler_->GetMaxConcurrentTasksWithTraitsDeprecated( + EXPECT_EQ(4, scheduler_.GetMaxConcurrentTasksWithTraitsDeprecated( TaskTraits().WithPriority(TaskPriority::USER_BLOCKING))); EXPECT_EQ( 12, - scheduler_->GetMaxConcurrentTasksWithTraitsDeprecated( + scheduler_.GetMaxConcurrentTasksWithTraitsDeprecated( TaskTraits().WithPriority(TaskPriority::USER_BLOCKING).MayBlock())); } // Verify that the RunsTasksOnCurrentThread() method of a SequencedTaskRunner // returns false when called from a task that isn't part of the sequence. TEST_F(TaskSchedulerImplTest, SequencedRunsTasksOnCurrentThread) { + StartTaskScheduler(); auto single_thread_task_runner = - scheduler_->CreateSingleThreadTaskRunnerWithTraits(TaskTraits()); + scheduler_.CreateSingleThreadTaskRunnerWithTraits(TaskTraits()); auto sequenced_task_runner = - scheduler_->CreateSequencedTaskRunnerWithTraits(TaskTraits()); + scheduler_.CreateSequencedTaskRunnerWithTraits(TaskTraits()); WaitableEvent task_ran(WaitableEvent::ResetPolicy::MANUAL, WaitableEvent::InitialState::NOT_SIGNALED); @@ -329,10 +402,11 @@ // Verify that the RunsTasksOnCurrentThread() method of a SingleThreadTaskRunner // returns false when called from a task that isn't part of the sequence. TEST_F(TaskSchedulerImplTest, SingleThreadRunsTasksOnCurrentThread) { + StartTaskScheduler(); auto sequenced_task_runner = - scheduler_->CreateSequencedTaskRunnerWithTraits(TaskTraits()); + scheduler_.CreateSequencedTaskRunnerWithTraits(TaskTraits()); auto single_thread_task_runner = - scheduler_->CreateSingleThreadTaskRunnerWithTraits(TaskTraits()); + scheduler_.CreateSingleThreadTaskRunnerWithTraits(TaskTraits()); WaitableEvent task_ran(WaitableEvent::ResetPolicy::MANUAL, WaitableEvent::InitialState::NOT_SIGNALED); @@ -350,8 +424,9 @@ #if defined(OS_WIN) TEST_F(TaskSchedulerImplTest, COMSTATaskRunnersRunWithCOMSTA) { + StartTaskScheduler(); auto com_sta_task_runner = - scheduler_->CreateCOMSTATaskRunnerWithTraits(TaskTraits()); + scheduler_.CreateCOMSTATaskRunnerWithTraits(TaskTraits()); WaitableEvent task_ran(WaitableEvent::ResetPolicy::MANUAL, WaitableEvent::InitialState::NOT_SIGNALED);
diff --git a/base/test/scoped_task_scheduler.cc b/base/test/scoped_task_scheduler.cc index 3c5b0e2f..ba19f62 100644 --- a/base/test/scoped_task_scheduler.cc +++ b/base/test/scoped_task_scheduler.cc
@@ -38,6 +38,9 @@ enum class ExecutionMode { PARALLEL, SEQUENCED, SINGLE_THREADED }; +// ScopedTaskScheduler intentionally breaks the TaskScheduler contract of not +// running tasks before Start(). This avoid having to call Start() with dummy +// parameters. class TestTaskScheduler : public TaskScheduler { public: // |external_message_loop| is an externally provided MessageLoop on which to @@ -47,6 +50,7 @@ ~TestTaskScheduler() override; // TaskScheduler: + void Start(const TaskScheduler::InitParams& init_params) override; void PostDelayedTaskWithTraits(const tracked_objects::Location& from_here, const TaskTraits& traits, OnceClosure task, @@ -164,6 +168,10 @@ Shutdown(); } +void TestTaskScheduler::Start(const TaskScheduler::InitParams&) { + NOTREACHED(); +} + void TestTaskScheduler::PostDelayedTaskWithTraits( const tracked_objects::Location& from_here, const TaskTraits& traits,
diff --git a/base/trace_event/trace_event_memory_overhead.cc b/base/trace_event/trace_event_memory_overhead.cc index 95177b5..d23383f 100644 --- a/base/trace_event/trace_event_memory_overhead.cc +++ b/base/trace_event/trace_event_memory_overhead.cc
@@ -84,9 +84,7 @@ } break; case Value::Type::BINARY: { - const Value* binary_value = nullptr; - value.GetAsBinary(&binary_value); - Add("BinaryValue", sizeof(Value) + binary_value->GetSize()); + Add("BinaryValue", sizeof(Value) + value.GetBlob().size()); } break; case Value::Type::DICTIONARY: {
diff --git a/base/values.cc b/base/values.cc index f24646cb..3397f1c3 100644 --- a/base/values.cc +++ b/base/values.cc
@@ -244,14 +244,6 @@ return *list_; } -size_t Value::GetSize() const { - return GetBlob().size(); -} - -const char* Value::GetBuffer() const { - return GetBlob().data(); -} - bool Value::GetAsBoolean(bool* out_value) const { if (out_value && is_bool()) { *out_value = bool_value_; @@ -312,14 +304,6 @@ return is_string(); } -bool Value::GetAsBinary(const Value** out_value) const { - if (out_value && is_blob()) { - *out_value = this; - return true; - } - return is_blob(); -} - bool Value::GetAsList(ListValue** out_value) { if (out_value && is_list()) { *out_value = static_cast<ListValue*>(this);
diff --git a/base/values.h b/base/values.h index 2bab074..99b30fc 100644 --- a/base/values.h +++ b/base/values.h
@@ -137,9 +137,6 @@ ListStorage& GetList(); const ListStorage& GetList() const; - size_t GetSize() const; // DEPRECATED, use GetBlob().size() instead. - const char* GetBuffer() const; // DEPRECATED, use GetBlob().data() instead. - // These methods allow the convenient retrieval of the contents of the Value. // If the current object can be converted into the given type, the value is // returned through the |out_value| parameter and true is returned; @@ -151,7 +148,6 @@ bool GetAsString(string16* out_value) const; bool GetAsString(const Value** out_value) const; bool GetAsString(StringPiece* out_value) const; - bool GetAsBinary(const Value** out_value) const; // ListValue::From is the equivalent for std::unique_ptr conversions. bool GetAsList(ListValue** out_value); bool GetAsList(const ListValue** out_value) const;
diff --git a/base/values_unittest.cc b/base/values_unittest.cc index 7f871123..a781dc4 100644 --- a/base/values_unittest.cc +++ b/base/values_unittest.cc
@@ -442,31 +442,26 @@ // Default constructor creates a BinaryValue with a buffer of size 0. auto binary = MakeUnique<Value>(Value::Type::BINARY); ASSERT_TRUE(binary.get()); - ASSERT_EQ(0U, binary->GetSize()); + ASSERT_TRUE(binary->GetBlob().empty()); // Test the common case of a non-empty buffer Value::BlobStorage buffer(15); char* original_buffer = buffer.data(); binary.reset(new Value(std::move(buffer))); ASSERT_TRUE(binary.get()); - ASSERT_TRUE(binary->GetBuffer()); - ASSERT_EQ(original_buffer, binary->GetBuffer()); - ASSERT_EQ(15U, binary->GetSize()); + ASSERT_TRUE(binary->GetBlob().data()); + ASSERT_EQ(original_buffer, binary->GetBlob().data()); + ASSERT_EQ(15U, binary->GetBlob().size()); char stack_buffer[42]; memset(stack_buffer, '!', 42); binary = Value::CreateWithCopiedBuffer(stack_buffer, 42); ASSERT_TRUE(binary.get()); - ASSERT_TRUE(binary->GetBuffer()); - ASSERT_NE(stack_buffer, binary->GetBuffer()); - ASSERT_EQ(42U, binary->GetSize()); - ASSERT_EQ(0, memcmp(stack_buffer, binary->GetBuffer(), binary->GetSize())); - - // Test overloaded GetAsBinary. - Value* narrow_value = binary.get(); - const Value* narrow_binary = NULL; - ASSERT_TRUE(narrow_value->GetAsBinary(&narrow_binary)); - EXPECT_EQ(binary.get(), narrow_binary); + ASSERT_TRUE(binary->GetBlob().data()); + ASSERT_NE(stack_buffer, binary->GetBlob().data()); + ASSERT_EQ(42U, binary->GetBlob().size()); + ASSERT_EQ(0, memcmp(stack_buffer, binary->GetBlob().data(), + binary->GetBlob().size())); } TEST(ValuesTest, StringValue) { @@ -754,10 +749,8 @@ ASSERT_TRUE(copy_binary); ASSERT_NE(copy_binary, original_binary); ASSERT_TRUE(copy_binary->IsType(Value::Type::BINARY)); - ASSERT_NE(original_binary->GetBuffer(), copy_binary->GetBuffer()); - ASSERT_EQ(original_binary->GetSize(), copy_binary->GetSize()); - ASSERT_EQ(0, memcmp(original_binary->GetBuffer(), copy_binary->GetBuffer(), - original_binary->GetSize())); + ASSERT_NE(original_binary->GetBlob().data(), copy_binary->GetBlob().data()); + ASSERT_EQ(original_binary->GetBlob(), copy_binary->GetBlob()); Value* copy_value = NULL; ASSERT_TRUE(copy_dict->Get("list", ©_value));
diff --git a/build/android/pylib/results/presentation/test_results_presentation.py b/build/android/pylib/results/presentation/test_results_presentation.py index 3324784..d7e2b5a 100755 --- a/build/android/pylib/results/presentation/test_results_presentation.py +++ b/build/android/pylib/results/presentation/test_results_presentation.py
@@ -308,12 +308,12 @@ def main(): parser = argparse.ArgumentParser() - parser.add_argument('--json-file', help='Path of json file.', required=True) + parser.add_argument('--json-file', help='Path of json file.') parser.add_argument('--cs-base-url', help='Base url for code search.', default='http://cs.chromium.org') parser.add_argument('--bucket', help='Google storage bucket.', required=True) - parser.add_argument('--builder-name', help='Builder name.', required=True) - parser.add_argument('--build-number', help='Build number.', required=True) + parser.add_argument('--builder-name', help='Builder name.') + parser.add_argument('--build-number', help='Build number.') parser.add_argument('--test-name', help='The name of the test.', required=True) parser.add_argument('--server-url', help='The url of the server.', @@ -324,18 +324,77 @@ 'whether to download the file, or view in browser.'), default='text/html', choices=['text/html', 'application/octet-stream']) + parser.add_argument( + '-o', '--output-json', + help='(Swarming Merge Script API)' + ' Output JSON file to create.') + parser.add_argument( + '--build-properties', + help='(Swarming Merge Script API) ' + 'Build property JSON file provided by recipes.') + parser.add_argument( + '--summary-json', + help='(Swarming Merge Script API)' + ' Summary of shard state running on swarming.' + ' (Output of the swarming.py collect' + ' --task-summary-json=XXX command.)') + parser.add_argument( + 'positional', nargs='*', + help='output.json from shards.') args = parser.parse_args() - if os.path.exists(args.json_file): - result_html_string = result_details(args.json_file, args.cs_base_url, - args.bucket, args.server_url) - print upload_to_google_bucket(result_html_string.encode('UTF-8'), - args.test_name, args.builder_name, - args.build_number, args.bucket, - args.server_url, args.content_type) - else: - raise IOError('--json-file %s not found.' % args.json_file) + if ((args.build_properties is None) == + (args.build_number is None or args.builder_name is None)): + raise parser.error('Exactly one of build_perperties or ' + '(build_number or builder_names) should be given.') + + if (args.build_number is None) != (args.builder_name is None): + raise parser.error('args.build_number and args.builder_name ' + 'has to be be given together' + 'or not given at all.') + + if (len(args.positional) == 0) == (args.json_file is None): + raise parser.error('Exactly one of args.positional and ' + 'args.json_file should be given.') + + if args.build_properties: + build_properties = json.loads(args.build_properties) + if ((not 'buildnumber' in build_properties) or + (not 'buildername' in build_properties)): + raise parser.error('Build number/builder name not specified.') + build_number = build_properties['buildnumber'] + builder_name = build_properties['buildername'] + elif args.build_number and args.builder_name: + build_number = args.build_number + builder_name = args.builder_name + + if args.positional: + if not len(args.positional) == 1: + raise parser.error('More than 1 json file specified.') + json_file = args.positional[0] + elif args.json_file: + json_file = args.json_file + + if not os.path.exists(json_file): + raise IOError('--json-file %s not found.' % json_file) + + result_html_string = result_details(json_file, args.cs_base_url, + args.bucket, args.server_url) + result_details_link = upload_to_google_bucket( + result_html_string.encode('UTF-8'), + args.test_name, builder_name, + build_number, args.bucket, + args.server_url, args.content_type) + + if args.output_json: + with open(json_file) as original_json_file: + json_object = json.load(original_json_file) + json_object['links'] = {'result_details': result_details_link} + with open(args.output_json, 'w') as f: + json.dump(json_object, f) + else: + print result_details_link if __name__ == '__main__': sys.exit(main())
diff --git a/build/config/win/BUILD.gn b/build/config/win/BUILD.gn index 2156313..69867ec 100644 --- a/build/config/win/BUILD.gn +++ b/build/config/win/BUILD.gn
@@ -86,13 +86,13 @@ # information is used by the Syzygy optimization tool when decomposing the # release image. It is enabled for syzyasan builds and opportunistically for # other builds where it is not prohibited (not supported when incrementally - # linking, using /debug:fastlink, or building with clang). + # linking, or using /debug:fastlink). if (is_syzyasan) { assert(!is_win_fastlink) ldflags = [ "/PROFILE" ] } else { if (!is_debug && !is_component_build) { - if (is_win_fastlink || is_clang) { + if (is_win_fastlink) { # /PROFILE implies the following linker flags. Therefore if we are # skipping /PROFILE because it is incompatible with /DEBUG:FASTLINK # we should explicitly add these flags in order to avoid unintended
diff --git a/cc/ipc/begin_frame_args_struct_traits.cc b/cc/ipc/begin_frame_args_struct_traits.cc index 8ba827d..fedd0dd 100644 --- a/cc/ipc/begin_frame_args_struct_traits.cc +++ b/cc/ipc/begin_frame_args_struct_traits.cc
@@ -29,6 +29,8 @@ bool StructTraits<cc::mojom::BeginFrameAckDataView, cc::BeginFrameAck>::Read( cc::mojom::BeginFrameAckDataView data, cc::BeginFrameAck* out) { + if (data.sequence_number() < cc::BeginFrameArgs::kStartingFrameNumber) + return false; out->source_id = data.source_id(); out->sequence_number = data.sequence_number(); out->latest_confirmed_sequence_number =
diff --git a/cc/ipc/cc_param_traits.cc b/cc/ipc/cc_param_traits.cc index 2f6c5c2..0248334 100644 --- a/cc/ipc/cc_param_traits.cc +++ b/cc/ipc/cc_param_traits.cc
@@ -960,6 +960,40 @@ l->append("])"); } +void ParamTraits<cc::BeginFrameAck>::GetSize(base::PickleSizer* s, + const param_type& p) { + GetParamSize(s, p.sequence_number); + GetParamSize(s, p.latest_confirmed_sequence_number); + GetParamSize(s, p.source_id); +} + +void ParamTraits<cc::BeginFrameAck>::Write(base::Pickle* m, + const param_type& p) { + m->WriteUInt64(p.sequence_number); + m->WriteUInt64(p.latest_confirmed_sequence_number); + m->WriteUInt32(p.source_id); + // |has_damage| is implicit through IPC message name, so not transmitted. +} + +bool ParamTraits<cc::BeginFrameAck>::Read(const base::Pickle* m, + base::PickleIterator* iter, + param_type* p) { + return iter->ReadUInt64(&p->sequence_number) && + p->sequence_number >= cc::BeginFrameArgs::kStartingFrameNumber && + iter->ReadUInt64(&p->latest_confirmed_sequence_number) && + iter->ReadUInt32(&p->source_id); +} + +void ParamTraits<cc::BeginFrameAck>::Log(const param_type& p, std::string* l) { + l->append("("); + LogParam(p.sequence_number, l); + l->append(", "); + LogParam(p.latest_confirmed_sequence_number, l); + l->append(", "); + LogParam(p.source_id, l); + l->append(")"); +} + } // namespace IPC // Generate param traits size methods.
diff --git a/cc/ipc/cc_param_traits.h b/cc/ipc/cc_param_traits.h index 14e3dba..d2e8b599 100644 --- a/cc/ipc/cc_param_traits.h +++ b/cc/ipc/cc_param_traits.h
@@ -142,6 +142,17 @@ static void Log(const param_type& p, std::string* l); }; +template <> +struct CC_IPC_EXPORT ParamTraits<cc::BeginFrameAck> { + typedef cc::BeginFrameAck param_type; + static void GetSize(base::PickleSizer* s, const param_type& p); + static void Write(base::Pickle* m, const param_type& p); + static bool Read(const base::Pickle* m, + base::PickleIterator* iter, + param_type* p); + static void Log(const param_type& p, std::string* l); +}; + } // namespace IPC #endif // CC_IPC_CC_PARAM_TRAITS_H_
diff --git a/cc/ipc/cc_param_traits_macros.h b/cc/ipc/cc_param_traits_macros.h index 24fd9e22..7c7f87f 100644 --- a/cc/ipc/cc_param_traits_macros.h +++ b/cc/ipc/cc_param_traits_macros.h
@@ -176,13 +176,6 @@ IPC_STRUCT_TRAITS_MEMBER(type) IPC_STRUCT_TRAITS_END() -IPC_STRUCT_TRAITS_BEGIN(cc::BeginFrameAck) - IPC_STRUCT_TRAITS_MEMBER(sequence_number) - IPC_STRUCT_TRAITS_MEMBER(latest_confirmed_sequence_number) - IPC_STRUCT_TRAITS_MEMBER(source_id) -// |has_damage| is implicit through IPC message name, so not transmitted. -IPC_STRUCT_TRAITS_END() - IPC_STRUCT_TRAITS_BEGIN(cc::CompositorFrameMetadata) IPC_STRUCT_TRAITS_MEMBER(device_scale_factor) IPC_STRUCT_TRAITS_MEMBER(root_scroll_offset)
diff --git a/cc/ipc/cc_param_traits_unittest.cc b/cc/ipc/cc_param_traits_unittest.cc index da75f2f1..776e5c2 100644 --- a/cc/ipc/cc_param_traits_unittest.cc +++ b/cc/ipc/cc_param_traits_unittest.cc
@@ -456,6 +456,8 @@ CompositorFrame frame_in; frame_in.render_pass_list.push_back(std::move(child_pass_in)); frame_in.render_pass_list.push_back(std::move(pass_in)); + frame_in.metadata.begin_frame_ack.sequence_number = + cc::BeginFrameArgs::kStartingFrameNumber; IPC::ParamTraits<CompositorFrame>::Write(&msg, frame_in); @@ -543,6 +545,8 @@ CompositorFrame frame_in; frame_in.render_pass_list.push_back(std::move(pass_in)); + frame_in.metadata.begin_frame_ack.sequence_number = + cc::BeginFrameArgs::kStartingFrameNumber; IPC::Message msg(1, 2, IPC::Message::PRIORITY_NORMAL); IPC::ParamTraits<CompositorFrame>::Write(&msg, frame_in); @@ -620,6 +624,8 @@ frame_in.resource_list.push_back(arbitrary_resource1); frame_in.resource_list.push_back(arbitrary_resource2); frame_in.render_pass_list.push_back(std::move(renderpass_in)); + frame_in.metadata.begin_frame_ack.sequence_number = + cc::BeginFrameArgs::kStartingFrameNumber; IPC::ParamTraits<CompositorFrame>::Write(&msg, frame_in);
diff --git a/cc/ipc/struct_traits_unittest.cc b/cc/ipc/struct_traits_unittest.cc index 46aa122..5b1b68e 100644 --- a/cc/ipc/struct_traits_unittest.cc +++ b/cc/ipc/struct_traits_unittest.cc
@@ -379,6 +379,7 @@ LocalSurfaceId(8765, base::UnguessableToken::Create())); embedded_surfaces.push_back(id2); uint32_t frame_token = 0xdeadbeef; + uint64_t begin_frame_ack_sequence_number = 0xdeadbeef; CompositorFrameMetadata input; input.device_scale_factor = device_scale_factor; @@ -403,6 +404,7 @@ input.referenced_surfaces = referenced_surfaces; input.embedded_surfaces = embedded_surfaces; input.frame_token = frame_token; + input.begin_frame_ack.sequence_number = begin_frame_ack_sequence_number; mojom::TraitsTestServicePtr proxy = GetTraitsTestProxy(); CompositorFrameMetadata output; @@ -438,6 +440,8 @@ for (uint32_t i = 0; i < embedded_surfaces.size(); ++i) EXPECT_EQ(embedded_surfaces[i], output.embedded_surfaces[i]); EXPECT_EQ(frame_token, output.frame_token); + EXPECT_EQ(begin_frame_ack_sequence_number, + output.begin_frame_ack.sequence_number); } TEST_F(StructTraitsTest, CopyOutputRequest_BitmapRequest) {
diff --git a/cc/layers/layer_impl.cc b/cc/layers/layer_impl.cc index f1ca86a..3643cfe 100644 --- a/cc/layers/layer_impl.cc +++ b/cc/layers/layer_impl.cc
@@ -382,7 +382,7 @@ if (!scroll_clip_layer) return gfx::Vector2dF(); - return scroll_clip_layer->bounds_delta(); + return scroll_clip_layer->ViewportBoundsDelta(); } std::unique_ptr<base::DictionaryValue> LayerImpl::LayerTreeAsJson() { @@ -504,14 +504,15 @@ } gfx::Size LayerImpl::bounds() const { - gfx::Vector2d delta = gfx::ToCeiledVector2d(bounds_delta_); - return gfx::Size(bounds_.width() + delta.x(), - bounds_.height() + delta.y()); + auto viewport_bounds_delta = gfx::ToCeiledVector2d(ViewportBoundsDelta()); + return gfx::Size(bounds_.width() + viewport_bounds_delta.x(), + bounds_.height() + viewport_bounds_delta.y()); } gfx::SizeF LayerImpl::BoundsForScrolling() const { - return gfx::SizeF(bounds_.width() + bounds_delta_.x(), - bounds_.height() + bounds_delta_.y()); + auto viewport_bounds_delta = ViewportBoundsDelta(); + return gfx::SizeF(bounds_.width() + viewport_bounds_delta.x(), + bounds_.height() + viewport_bounds_delta.y()); } void LayerImpl::SetBounds(const gfx::Size& bounds) { @@ -525,12 +526,11 @@ NoteLayerPropertyChanged(); } -void LayerImpl::SetBoundsDelta(const gfx::Vector2dF& bounds_delta) { +void LayerImpl::SetViewportBoundsDelta(const gfx::Vector2dF& bounds_delta) { DCHECK(IsActive()); - if (bounds_delta_ == bounds_delta) - return; - bounds_delta_ = bounds_delta; + if (bounds_delta == ViewportBoundsDelta()) + return; PropertyTrees* property_trees = GetPropertyTrees(); if (this == layer_tree_impl()->InnerViewportContainerLayer()) @@ -539,6 +539,8 @@ property_trees->SetOuterViewportContainerBoundsDelta(bounds_delta); else if (this == layer_tree_impl()->InnerViewportScrollLayer()) property_trees->SetInnerViewportScrollBoundsDelta(bounds_delta); + else + NOTREACHED(); layer_tree_impl()->DidUpdateScrollState(id()); @@ -558,6 +560,16 @@ } } +gfx::Vector2dF LayerImpl::ViewportBoundsDelta() const { + if (this == layer_tree_impl()->InnerViewportContainerLayer()) + return GetPropertyTrees()->inner_viewport_container_bounds_delta(); + else if (this == layer_tree_impl()->OuterViewportContainerLayer()) + return GetPropertyTrees()->outer_viewport_container_bounds_delta(); + else if (this == layer_tree_impl()->InnerViewportScrollLayer()) + return GetPropertyTrees()->inner_viewport_scroll_bounds_delta(); + return gfx::Vector2dF(); +} + ScrollbarLayerImplBase* LayerImpl::ToScrollbarLayer() { return nullptr; }
diff --git a/cc/layers/layer_impl.h b/cc/layers/layer_impl.h index 55258222..13733cc 100644 --- a/cc/layers/layer_impl.h +++ b/cc/layers/layer_impl.h
@@ -269,8 +269,12 @@ // Like bounds() but doesn't snap to int. Lossy on giant pages (e.g. millions // of pixels) due to use of single precision float. gfx::SizeF BoundsForScrolling() const; - void SetBoundsDelta(const gfx::Vector2dF& bounds_delta); - gfx::Vector2dF bounds_delta() const { return bounds_delta_; } + + // Viewport bounds delta are used for viewport layers and accounts for changes + // in the viewport layers from browser controls and page scale factors. These + // deltas are only set on the active tree. + void SetViewportBoundsDelta(const gfx::Vector2dF& bounds_delta); + gfx::Vector2dF ViewportBoundsDelta() const; void SetCurrentScrollOffset(const gfx::ScrollOffset& scroll_offset); gfx::ScrollOffset CurrentScrollOffset() const; @@ -471,8 +475,6 @@ std::unique_ptr<LayerImplTestProperties> test_properties_; - gfx::Vector2dF bounds_delta_; - // Properties synchronized from the associated Layer. gfx::Size bounds_; int scroll_clip_layer_id_;
diff --git a/cc/layers/layer_impl_unittest.cc b/cc/layers/layer_impl_unittest.cc index 2180d54..f8f55537 100644 --- a/cc/layers/layer_impl_unittest.cc +++ b/cc/layers/layer_impl_unittest.cc
@@ -138,6 +138,11 @@ root_clip_ptr->test_properties()->AddChild(std::move(root_ptr)); host_impl.active_tree()->SetRootLayerForTesting(std::move(root_clip_ptr)); + // Make root the inner viewport scroll layer. This ensures the later call to + // |SetViewportBoundsDelta| will be on a viewport layer. + host_impl.active_tree()->SetViewportLayersFromIds( + Layer::INVALID_ID, Layer::INVALID_ID, root->id(), Layer::INVALID_ID); + root->test_properties()->force_render_surface = true; root->SetMasksToBounds(true); root->layer_tree_impl()->ResetAllChangeTracking(); @@ -192,11 +197,13 @@ arbitrary_transform)); EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->ScrollBy(arbitrary_vector2d); root->SetNeedsPushProperties()); - // SetBoundsDelta changes subtree only when masks_to_bounds is true and it - // doesn't set needs_push_properties as it is always called on active tree. + // SetViewportBoundsDelta changes subtree only when masks_to_bounds is true + // and it doesn't set needs_push_properties as it is always called on active + // tree. root->SetMasksToBounds(true); - EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->SetBoundsDelta(arbitrary_vector2d); - root->SetNeedsPushProperties()); + EXECUTE_AND_VERIFY_SUBTREE_CHANGED( + root->SetViewportBoundsDelta(arbitrary_vector2d); + root->SetNeedsPushProperties()); // Changing these properties only affects the layer itself. EXECUTE_AND_VERIFY_ONLY_LAYER_CHANGED(root->SetDrawsContent(true));
diff --git a/cc/layers/layer_position_constraint_unittest.cc b/cc/layers/layer_position_constraint_unittest.cc index ce8e214..e264640 100644 --- a/cc/layers/layer_position_constraint_unittest.cc +++ b/cc/layers/layer_position_constraint_unittest.cc
@@ -215,7 +215,7 @@ DCHECK(scroll_layer->scrollable()); LayerImpl* container_layer = scroll_layer->scroll_clip_layer(); - container_layer->SetBoundsDelta(delta); + container_layer->SetViewportBoundsDelta(delta); } } // namespace
diff --git a/cc/surfaces/compositor_frame_sink_support.cc b/cc/surfaces/compositor_frame_sink_support.cc index d85a331..39b7fbd 100644 --- a/cc/surfaces/compositor_frame_sink_support.cc +++ b/cc/surfaces/compositor_frame_sink_support.cc
@@ -108,10 +108,7 @@ // TODO(eseckler): While a pending CompositorFrame exists (see TODO below), we // should not acknowledge immediately. Instead, we should update the ack that // will be sent to DisplayScheduler when the pending frame is activated. - if (ack.sequence_number < BeginFrameArgs::kStartingFrameNumber) { - DLOG(ERROR) << "Received BeginFrameDidNotSwap with invalid BeginFrameAck."; - return; - } + DCHECK_GE(ack.sequence_number, BeginFrameArgs::kStartingFrameNumber); // |has_damage| is not transmitted, but false by default. DCHECK(!ack.has_damage);
diff --git a/cc/test/fake_layer_tree_host.cc b/cc/test/fake_layer_tree_host.cc index fca7d4ba..474d4ed 100644 --- a/cc/test/fake_layer_tree_host.cc +++ b/cc/test/fake_layer_tree_host.cc
@@ -86,7 +86,6 @@ : Layer::INVALID_ID); } - active_tree()->UpdatePropertyTreesForBoundsDelta(); return active_tree()->root_layer_for_testing(); }
diff --git a/cc/test/layer_tree_test.cc b/cc/test/layer_tree_test.cc index 8a16671..db7a93c 100644 --- a/cc/test/layer_tree_test.cc +++ b/cc/test/layer_tree_test.cc
@@ -186,6 +186,7 @@ if (block_notify_ready_to_activate_for_testing_) { notify_ready_to_activate_was_blocked_ = true; } else { + test_hooks_->WillNotifyReadyToActivateOnThread(this); LayerTreeHostImpl::NotifyReadyToActivate(); test_hooks_->NotifyReadyToActivateOnThread(this); }
diff --git a/cc/test/test_hooks.h b/cc/test/test_hooks.h index 46991d38..bff5cd5 100644 --- a/cc/test/test_hooks.h +++ b/cc/test/test_hooks.h
@@ -46,6 +46,8 @@ LayerTreeHostImpl::FrameData* frame_data, DrawResult draw_result); virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) {} + virtual void WillNotifyReadyToActivateOnThread(LayerTreeHostImpl* host_impl) { + } virtual void NotifyReadyToActivateOnThread(LayerTreeHostImpl* host_impl) {} virtual void NotifyReadyToDrawOnThread(LayerTreeHostImpl* host_impl) {} virtual void NotifyAllTileTasksCompleted(LayerTreeHostImpl* host_impl) {}
diff --git a/cc/trees/layer_tree_host.cc b/cc/trees/layer_tree_host.cc index 82beb9ec..baf32a3 100644 --- a/cc/trees/layer_tree_host.cc +++ b/cc/trees/layer_tree_host.cc
@@ -339,7 +339,9 @@ // host pushes properties as animation host push properties can change // Animation::InEffect and we want the old InEffect value for updating // property tree scrolling and animation. - sync_tree->UpdatePropertyTreeScrollingAndAnimationFromMainThread(); + bool is_impl_side_update = false; + sync_tree->UpdatePropertyTreeScrollingAndAnimationFromMainThread( + is_impl_side_update); TRACE_EVENT0("cc", "LayerTreeHostInProcess::AnimationHost::PushProperties"); DCHECK(host_impl->mutator_host());
diff --git a/cc/trees/layer_tree_host_common_unittest.cc b/cc/trees/layer_tree_host_common_unittest.cc index 51ef650..6c96b6a9 100644 --- a/cc/trees/layer_tree_host_common_unittest.cc +++ b/cc/trees/layer_tree_host_common_unittest.cc
@@ -7343,7 +7343,7 @@ // We start to hide the toolbar, but not far enough that the sticky element // should be moved up yet. - root_impl->SetBoundsDelta(gfx::Vector2dF(0.f, -10.f)); + root_impl->SetViewportBoundsDelta(gfx::Vector2dF(0.f, -10.f)); ExecuteCalculateDrawProperties(root_impl, 1.f, 1.f, root_impl, inner_scroll, nullptr); EXPECT_VECTOR2DF_EQ( @@ -7351,7 +7351,7 @@ sticky_pos_impl->ScreenSpaceTransform().To2dTranslation()); // On hiding more of the toolbar the sticky element starts to stick. - root_impl->SetBoundsDelta(gfx::Vector2dF(0.f, -20.f)); + root_impl->SetViewportBoundsDelta(gfx::Vector2dF(0.f, -20.f)); ExecuteCalculateDrawProperties(root_impl, 1.f, 1.f, root_impl, inner_scroll, nullptr); EXPECT_VECTOR2DF_EQ( @@ -7360,7 +7360,7 @@ // On hiding more the sticky element stops moving as it has reached its // limit. - root_impl->SetBoundsDelta(gfx::Vector2dF(0.f, -30.f)); + root_impl->SetViewportBoundsDelta(gfx::Vector2dF(0.f, -30.f)); ExecuteCalculateDrawProperties(root_impl, 1.f, 1.f, root_impl, inner_scroll, nullptr); EXPECT_VECTOR2DF_EQ( @@ -7420,7 +7420,7 @@ // We start to hide the toolbar, but not far enough that the sticky element // should be moved up yet. - outer_clip_impl->SetBoundsDelta(gfx::Vector2dF(0.f, -10.f)); + outer_clip_impl->SetViewportBoundsDelta(gfx::Vector2dF(0.f, -10.f)); ExecuteCalculateDrawProperties(root_impl, 1.f, 1.f, root_impl, inner_scroll, outer_scroll); EXPECT_VECTOR2DF_EQ( @@ -7428,7 +7428,7 @@ sticky_pos_impl->ScreenSpaceTransform().To2dTranslation()); // On hiding more of the toolbar the sticky element starts to stick. - outer_clip_impl->SetBoundsDelta(gfx::Vector2dF(0.f, -20.f)); + outer_clip_impl->SetViewportBoundsDelta(gfx::Vector2dF(0.f, -20.f)); ExecuteCalculateDrawProperties(root_impl, 1.f, 1.f, root_impl, inner_scroll, outer_scroll); @@ -7438,7 +7438,7 @@ gfx::Vector2dF(0.f, 60.f), sticky_pos_impl->ScreenSpaceTransform().To2dTranslation()); - outer_clip_impl->SetBoundsDelta(gfx::Vector2dF(0.f, -30.f)); + outer_clip_impl->SetViewportBoundsDelta(gfx::Vector2dF(0.f, -30.f)); ExecuteCalculateDrawProperties(root_impl, 1.f, 1.f, root_impl, inner_scroll, outer_scroll); @@ -8857,7 +8857,7 @@ EXPECT_EQ(gfx::Rect(768 / 2, 582 / 2), content->visible_layer_rect()); } -TEST_F(LayerTreeHostCommonTest, BoundsDeltaAffectVisibleContentRect) { +TEST_F(LayerTreeHostCommonTest, ViewportBoundsDeltaAffectVisibleContentRect) { FakeImplTaskRunnerProvider task_runner_provider; TestTaskGraphRunner task_graph_runner; FakeLayerTreeHostImpl host_impl(&task_runner_provider, &task_graph_runner); @@ -8881,6 +8881,11 @@ root->SetBounds(root_size); root->SetMasksToBounds(true); + // Make root the inner viewport scroll layer. This ensures the later call to + // |SetViewportBoundsDelta| will be on a viewport layer. + host_impl.active_tree()->SetViewportLayersFromIds( + Layer::INVALID_ID, Layer::INVALID_ID, root->id(), Layer::INVALID_ID); + root->test_properties()->AddChild( LayerImpl::Create(host_impl.active_tree(), 2)); @@ -8897,7 +8902,7 @@ LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); EXPECT_EQ(gfx::Rect(root_size), sublayer->visible_layer_rect()); - root->SetBoundsDelta(gfx::Vector2dF(0.0, 50.0)); + root->SetViewportBoundsDelta(gfx::Vector2dF(0.0, 50.0)); LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); gfx::Rect affected_by_delta(0, 0, root_size.width(), @@ -8905,7 +8910,7 @@ EXPECT_EQ(affected_by_delta, sublayer->visible_layer_rect()); } -TEST_F(LayerTreeHostCommonTest, NodesAffectedByBoundsDeltaGetUpdated) { +TEST_F(LayerTreeHostCommonTest, NodesAffectedByViewportBoundsDeltaGetUpdated) { scoped_refptr<Layer> root = Layer::Create(); scoped_refptr<Layer> inner_viewport_container_layer = Layer::Create(); scoped_refptr<Layer> inner_viewport_scroll_layer = Layer::Create();
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc index 6965594..89c7ab70 100644 --- a/cc/trees/layer_tree_host_impl.cc +++ b/cc/trees/layer_tree_host_impl.cc
@@ -1073,6 +1073,19 @@ if (!CommitToActiveTree()) CreatePendingTree(); + + // The state of PropertyTrees on the recycle tree can be stale if scrolling + // and animation updates were made on the active tree, since these are not + // replicated on the recycle tree. We use the function below to handle the + // similar case for updates from the main thread not being in sync with + // changes made on the active tree. + // Note that while in practice only the scroll state should need to be + // updated, since the animation state is updated both on the recycle and + // active tree. We use the same function as for main thread commits for + // consistency. + bool is_impl_side_update = true; + sync_tree()->UpdatePropertyTreeScrollingAndAnimationFromMainThread( + is_impl_side_update); UpdateSyncTreeAfterCommitOrImplSideInvalidation(); } @@ -1945,7 +1958,7 @@ // for changes in the size (e.g. browser controls) since the last resize from // Blink. gfx::Vector2dF amount_to_expand(0.f, delta_from_top_controls); - inner_container->SetBoundsDelta(amount_to_expand); + inner_container->SetViewportBoundsDelta(amount_to_expand); if (outer_container && !outer_container->BoundsForScrolling().IsEmpty()) { // Adjust the outer viewport container as well, since adjusting only the @@ -1953,8 +1966,8 @@ // clamping. gfx::Vector2dF amount_to_expand_scaled = gfx::ScaleVector2d( amount_to_expand, 1.f / active_tree_->min_page_scale_factor()); - outer_container->SetBoundsDelta(amount_to_expand_scaled); - active_tree_->InnerViewportScrollLayer()->SetBoundsDelta( + outer_container->SetViewportBoundsDelta(amount_to_expand_scaled); + active_tree_->InnerViewportScrollLayer()->SetViewportBoundsDelta( amount_to_expand_scaled); anchor.ResetViewportToAnchoredPosition();
diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc index 15d79a9..74f2ab2 100644 --- a/cc/trees/layer_tree_host_impl_unittest.cc +++ b/cc/trees/layer_tree_host_impl_unittest.cc
@@ -2830,7 +2830,7 @@ host_impl_->DidFinishImplFrame(); } -TEST_F(LayerTreeHostImplTest, MaxScrollOffsetAffectedByBoundsDelta) { +TEST_F(LayerTreeHostImplTest, MaxScrollOffsetAffectedByViewportBoundsDelta) { SetupScrollAndContentsLayers(gfx::Size(100, 100)); host_impl_->SetViewportSize(gfx::Size(50, 50)); host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 0.5f, 4.f); @@ -2843,17 +2843,17 @@ DCHECK(inner_container); EXPECT_EQ(gfx::ScrollOffset(50, 50), inner_scroll->MaxScrollOffset()); - inner_container->SetBoundsDelta(gfx::Vector2dF(15.f, 15.f)); - inner_scroll->SetBoundsDelta(gfx::Vector2dF(7.f, 7.f)); + inner_container->SetViewportBoundsDelta(gfx::Vector2dF(15.f, 15.f)); + inner_scroll->SetViewportBoundsDelta(gfx::Vector2dF(7.f, 7.f)); EXPECT_EQ(gfx::ScrollOffset(42, 42), inner_scroll->MaxScrollOffset()); - inner_container->SetBoundsDelta(gfx::Vector2dF()); - inner_scroll->SetBoundsDelta(gfx::Vector2dF()); + inner_container->SetViewportBoundsDelta(gfx::Vector2dF()); + inner_scroll->SetViewportBoundsDelta(gfx::Vector2dF()); inner_scroll->SetBounds(gfx::Size()); host_impl_->active_tree()->BuildPropertyTreesForTesting(); DrawFrame(); - inner_scroll->SetBoundsDelta(gfx::Vector2dF(60.f, 60.f)); + inner_scroll->SetViewportBoundsDelta(gfx::Vector2dF(60.f, 60.f)); EXPECT_EQ(gfx::ScrollOffset(10, 10), inner_scroll->MaxScrollOffset()); } @@ -3410,8 +3410,9 @@ // Changing one of the viewport layers should result in a scrollbar animation // update. animation_task_ = base::Closure(); - host_impl_->active_tree()->InnerViewportContainerLayer()->SetBoundsDelta( - gfx::Vector2dF(10, 10)); + host_impl_->active_tree() + ->InnerViewportContainerLayer() + ->SetViewportBoundsDelta(gfx::Vector2dF(10, 10)); EXPECT_FALSE(animation_task_.Equals(base::Closure())); animation_task_ = base::Closure(); host_impl_->active_tree()->OuterViewportScrollLayer()->SetCurrentScrollOffset( @@ -4825,7 +4826,8 @@ // account for the difference between the layout height and the current // browser controls offset. EXPECT_EQ(viewport_size_, inner_clip_ptr->bounds()); - EXPECT_VECTOR_EQ(gfx::Vector2dF(0.f, 50.f), inner_clip_ptr->bounds_delta()); + EXPECT_VECTOR_EQ(gfx::Vector2dF(0.f, 50.f), + inner_clip_ptr->ViewportBoundsDelta()); host_impl_->active_tree()->SetCurrentBrowserControlsShownRatio(1.f); host_impl_->DidChangeBrowserControlsPosition(); @@ -4834,7 +4836,8 @@ host_impl_->browser_controls_manager()->TopControlsShownRatio()); EXPECT_EQ(50.f, host_impl_->browser_controls_manager()->TopControlsHeight()); EXPECT_EQ(50.f, host_impl_->browser_controls_manager()->ContentTopOffset()); - EXPECT_VECTOR_EQ(gfx::Vector2dF(0.f, 0.f), inner_clip_ptr->bounds_delta()); + EXPECT_VECTOR_EQ(gfx::Vector2dF(0.f, 0.f), + inner_clip_ptr->ViewportBoundsDelta()); EXPECT_EQ(gfx::Size(viewport_size_.width(), viewport_size_.height() - 50.f), inner_clip_ptr->bounds()); }
diff --git a/cc/trees/layer_tree_host_unittest_animation.cc b/cc/trees/layer_tree_host_unittest_animation.cc index ac4c3968..a5513c7e 100644 --- a/cc/trees/layer_tree_host_unittest_animation.cc +++ b/cc/trees/layer_tree_host_unittest_animation.cc
@@ -1648,6 +1648,84 @@ // compositor thread. MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestAnimationFinishesDuringCommit); +class LayerTreeHostAnimationTestImplSideInvalidation + : public LayerTreeHostAnimationTest { + public: + void SetupTree() override { + LayerTreeHostAnimationTest::SetupTree(); + layer_ = FakePictureLayer::Create(&client_); + layer_->SetBounds(gfx::Size(4, 4)); + client_.set_bounds(layer_->bounds()); + layer_tree_host()->root_layer()->AddChild(layer_); + + AttachPlayersToTimeline(); + + player_->AttachElement(layer_tree_host()->root_layer()->element_id()); + player_child_->AttachElement(layer_->element_id()); + } + + void BeginTest() override { PostSetNeedsCommitToMainThread(); } + + void DidCommit() override { + if (layer_tree_host()->SourceFrameNumber() == 1) + AddAnimatedTransformToPlayer(player_child_.get(), 0.04, 5, 5); + } + + void WillCommit() override { + if (layer_tree_host()->SourceFrameNumber() == 2) { + // Block until the animation finishes on the compositor thread. Since + // animations have already been ticked on the main thread, when the commit + // happens the state on the main thread will be consistent with having a + // running animation but the state on the compositor thread will be + // consistent with having only a finished animation. + completion_.Wait(); + } + } + + void DidInvalidateContentOnImplSide(LayerTreeHostImpl* host_impl) override { + DCHECK(did_request_impl_side_invalidation_); + completion_.Signal(); + } + + void UpdateAnimationState(LayerTreeHostImpl* host_impl, + bool has_unfinished_animation) override { + if (host_impl->active_tree()->source_frame_number() == 1 && + !has_unfinished_animation && !did_request_impl_side_invalidation_) { + // The animation on the active tree has finished, now request an impl-side + // invalidation and make sure it finishes before the main thread is + // released. + did_request_impl_side_invalidation_ = true; + host_impl->RequestImplSideInvalidation(); + } + } + + void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { + switch (host_impl->sync_tree()->source_frame_number()) { + case 1: + PostSetNeedsCommitToMainThread(); + break; + case 2: + gfx::Transform expected_transform; + expected_transform.Translate(5.f, 5.f); + LayerImpl* layer_impl = host_impl->sync_tree()->LayerById(layer_->id()); + EXPECT_TRANSFORMATION_MATRIX_EQ(expected_transform, + layer_impl->DrawTransform()); + EndTest(); + break; + } + } + + void AfterTest() override {} + + private: + scoped_refptr<Layer> layer_; + FakeContentLayerClient client_; + CompletionEvent completion_; + bool did_request_impl_side_invalidation_ = false; +}; + +MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestImplSideInvalidation); + class LayerTreeHostAnimationTestNotifyAnimationFinished : public LayerTreeHostAnimationTest { public:
diff --git a/cc/trees/layer_tree_host_unittest_scroll.cc b/cc/trees/layer_tree_host_unittest_scroll.cc index b547fefc..22ae78a 100644 --- a/cc/trees/layer_tree_host_unittest_scroll.cc +++ b/cc/trees/layer_tree_host_unittest_scroll.cc
@@ -2132,6 +2132,25 @@ SignalCompletionIfPossible(); } + void WillNotifyReadyToActivateOnThread( + LayerTreeHostImpl* host_impl) override { + // Ensure that the scroll-offsets on the TransformTree are consistent with + // the synced scroll offsets, for the pending tree. + if (!host_impl->pending_tree()) + return; + + LayerImpl* scroll_layer = + host_impl->pending_tree()->OuterViewportScrollLayer(); + gfx::ScrollOffset scroll_offset = scroll_layer->CurrentScrollOffset(); + int transform_index = scroll_layer->transform_tree_index(); + gfx::ScrollOffset transform_tree_scroll_offset = + host_impl->pending_tree() + ->property_trees() + ->transform_tree.Node(transform_index) + ->scroll_offset; + EXPECT_EQ(scroll_offset, transform_tree_scroll_offset); + } + void SignalCompletionIfPossible() { if (!invalidated_on_impl_thread_ || !impl_side_invalidation_event_) return;
diff --git a/cc/trees/layer_tree_impl.cc b/cc/trees/layer_tree_impl.cc index 58f8630..0461219ab 100644 --- a/cc/trees/layer_tree_impl.cc +++ b/cc/trees/layer_tree_impl.cc
@@ -262,7 +262,7 @@ scrollbar->SetScrollLayerLength(scroll_size.height()); } scrollbar_needs_animation |= - scrollbar->SetVerticalAdjust(clip_layer->bounds_delta().y()); + scrollbar->SetVerticalAdjust(clip_layer->ViewportBoundsDelta().y()); } scrollbar_needs_animation |= @@ -386,21 +386,6 @@ return ret; } -static void UpdateClipTreeForBoundsDeltaOnLayer(LayerImpl* layer, - ClipTree* clip_tree) { - if (layer && layer->masks_to_bounds()) { - ClipNode* clip_node = clip_tree->Node(layer->clip_tree_index()); - if (clip_node) { - DCHECK_EQ(layer->id(), clip_node->owning_layer_id); - gfx::SizeF bounds = gfx::SizeF(layer->bounds()); - if (clip_node->clip.size() != bounds) { - clip_node->clip.set_size(bounds); - clip_tree->set_needs_update(true); - } - } - } -} - void LayerTreeImpl::SetPropertyTrees(PropertyTrees* property_trees) { std::vector<std::unique_ptr<RenderSurfaceImpl>> old_render_surfaces; property_trees_.effect_tree.TakeRenderSurfaces(&old_render_surfaces); @@ -421,30 +406,6 @@ property_trees_.effect_tree.set_needs_update(true); } -void LayerTreeImpl::UpdatePropertyTreesForBoundsDelta() { - DCHECK(IsActiveTree()); - LayerImpl* inner_container = InnerViewportContainerLayer(); - LayerImpl* outer_container = OuterViewportContainerLayer(); - LayerImpl* inner_scroll = InnerViewportScrollLayer(); - - UpdateClipTreeForBoundsDeltaOnLayer(inner_container, - &property_trees_.clip_tree); - UpdateClipTreeForBoundsDeltaOnLayer(InnerViewportScrollLayer(), - &property_trees_.clip_tree); - UpdateClipTreeForBoundsDeltaOnLayer(outer_container, - &property_trees_.clip_tree); - - if (inner_container) - property_trees_.SetInnerViewportContainerBoundsDelta( - inner_container->bounds_delta()); - if (outer_container) - property_trees_.SetOuterViewportContainerBoundsDelta( - outer_container->bounds_delta()); - if (inner_scroll) - property_trees_.SetInnerViewportScrollBoundsDelta( - inner_scroll->bounds_delta()); -} - void LayerTreeImpl::PushPropertiesTo(LayerTreeImpl* target_tree) { // The request queue should have been processed and does not require a push. DCHECK_EQ(ui_resource_request_queue_.size(), 0u); @@ -467,11 +428,6 @@ target_tree->property_trees()->scroll_tree.PushScrollUpdatesFromPendingTree( &property_trees_, target_tree); - // This needs to be called early so that we don't clamp with incorrect max - // offsets when UpdateViewportContainerSizes is called from e.g. - // PushBrowserControls - target_tree->UpdatePropertyTreesForBoundsDelta(); - if (next_activation_forces_redraw_) { target_tree->ForceRedrawNextActivation(); next_activation_forces_redraw_ = false; @@ -760,7 +716,8 @@ return page_scale_factor; } -void LayerTreeImpl::UpdatePropertyTreeScrollingAndAnimationFromMainThread() { +void LayerTreeImpl::UpdatePropertyTreeScrollingAndAnimationFromMainThread( + bool is_impl_side_update) { // TODO(enne): This should get replaced by pulling out scrolling and // animations into their own trees. Then scrolls and animations would have // their own ways of synchronizing across commits. This occurs to push @@ -769,13 +726,19 @@ // frame to a newly-committed property tree. if (layer_list_.empty()) return; + + // Entries from |element_id_to_*_animations_| should be deleted only after + // they have been synchronized with the main thread, which will not be the + // case if this is an impl-side invalidation. + const bool can_delete_animations = !is_impl_side_update; auto element_id_to_opacity = element_id_to_opacity_animations_.begin(); while (element_id_to_opacity != element_id_to_opacity_animations_.end()) { const ElementId id = element_id_to_opacity->first; if (EffectNode* node = property_trees_.effect_tree.FindNodeFromElementId(id)) { - if (!node->is_currently_animating_opacity || - node->opacity == element_id_to_opacity->second) { + if ((!node->is_currently_animating_opacity || + node->opacity == element_id_to_opacity->second) && + can_delete_animations) { element_id_to_opacity_animations_.erase(element_id_to_opacity++); continue; } @@ -790,8 +753,9 @@ const ElementId id = element_id_to_filter->first; if (EffectNode* node = property_trees_.effect_tree.FindNodeFromElementId(id)) { - if (!node->is_currently_animating_filter || - node->filters == element_id_to_filter->second) { + if ((!node->is_currently_animating_filter || + node->filters == element_id_to_filter->second) && + can_delete_animations) { element_id_to_filter_animations_.erase(element_id_to_filter++); continue; } @@ -806,8 +770,9 @@ const ElementId id = element_id_to_transform->first; if (TransformNode* node = property_trees_.transform_tree.FindNodeFromElementId(id)) { - if (!node->is_currently_animating || - node->local == element_id_to_transform->second) { + if ((!node->is_currently_animating || + node->local == element_id_to_transform->second) && + can_delete_animations) { element_id_to_transform_animations_.erase(element_id_to_transform++); continue; }
diff --git a/cc/trees/layer_tree_impl.h b/cc/trees/layer_tree_impl.h index 7998290..9dbaa2c 100644 --- a/cc/trees/layer_tree_impl.h +++ b/cc/trees/layer_tree_impl.h
@@ -132,8 +132,6 @@ void SetPropertyTrees(PropertyTrees* property_trees); PropertyTrees* property_trees() { return &property_trees_; } - void UpdatePropertyTreesForBoundsDelta(); - void PushPropertiesTo(LayerTreeImpl* tree_impl); void MoveChangeTrackingToLayers(); @@ -208,7 +206,8 @@ has_transparent_background_ = transparent; } - void UpdatePropertyTreeScrollingAndAnimationFromMainThread(); + void UpdatePropertyTreeScrollingAndAnimationFromMainThread( + bool is_impl_side_update); void SetPageScaleOnActiveTree(float active_page_scale); void PushPageScaleFromMainThread(float page_scale_factor, float min_page_scale_factor,
diff --git a/chrome/android/java/res/drawable/bookmark_drawer_item_background.xml b/chrome/android/java/res/drawable/bookmark_drawer_item_background.xml deleted file mode 100644 index 110b6d11..0000000 --- a/chrome/android/java/res/drawable/bookmark_drawer_item_background.xml +++ /dev/null
@@ -1,10 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- 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. ---> -<selector xmlns:android="http://schemas.android.com/apk/res/android"> - <item android:state_activated="true" - android:drawable="@color/bookmark_drawer_selected_background_color" /> - <item android:drawable="@android:color/transparent"/> -</selector> \ No newline at end of file
diff --git a/chrome/android/java/res/layout-sw720dp/bookmark_main.xml b/chrome/android/java/res/layout-sw720dp/bookmark_main.xml deleted file mode 100644 index 255d3c4..0000000 --- a/chrome/android/java/res/layout-sw720dp/bookmark_main.xml +++ /dev/null
@@ -1,27 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- 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. --> - -<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:orientation="horizontal" > - - <org.chromium.chrome.browser.bookmarks.BookmarkDrawerListView - android:id="@+id/bookmark_drawer_list" - android:layout_width="256dp" - android:layout_height="match_parent" - android:layout_gravity="start" - android:background="@android:color/white" - android:choiceMode="singleChoice" - android:divider="@null" - android:dividerHeight="0dp" /> - - <org.chromium.chrome.browser.widget.selection.SelectableListLayout - android:id="@+id/selectable_list" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:background="@android:color/white" /> - -</LinearLayout> \ No newline at end of file
diff --git a/chrome/android/java/res/layout/bookmark_action_bar.xml b/chrome/android/java/res/layout/bookmark_action_bar.xml index e6c9a20..f055547d8 100644 --- a/chrome/android/java/res/layout/bookmark_action_bar.xml +++ b/chrome/android/java/res/layout/bookmark_action_bar.xml
@@ -7,5 +7,4 @@ xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/bookmark_action_bar" android:layout_width="match_parent" - android:layout_height="?attr/actionBarSize" - android:background="@color/appbar_background" /> + android:layout_height="?attr/actionBarSize" />
diff --git a/chrome/android/java/res/layout/bookmark_divider.xml b/chrome/android/java/res/layout/bookmark_divider.xml deleted file mode 100644 index 9c23fe4..0000000 --- a/chrome/android/java/res/layout/bookmark_divider.xml +++ /dev/null
@@ -1,17 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- 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. --> - -<!-- Wrap a framelayout because android list view does not respect margins. --> -<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="match_parent" - android:layout_height="17dp" > - - <View - android:layout_width="match_parent" - android:layout_height="1dp" - android:layout_gravity="center_vertical" - android:background="#ffD6D6D6" /> - -</FrameLayout> \ No newline at end of file
diff --git a/chrome/android/java/res/layout/bookmark_drawer_item.xml b/chrome/android/java/res/layout/bookmark_drawer_item.xml deleted file mode 100644 index d49ef155..0000000 --- a/chrome/android/java/res/layout/bookmark_drawer_item.xml +++ /dev/null
@@ -1,9 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- 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. --> - -<org.chromium.chrome.browser.bookmarks.BookmarkDrawerListItemView xmlns:android="http://schemas.android.com/apk/res/android" - style="@style/BookmarkDrawerItemStyle" - android:textColor="@color/bookmark_drawer_text_color" - android:background="@drawable/bookmark_drawer_item_background" />
diff --git a/chrome/android/java/res/layout/bookmark_drawer_title.xml b/chrome/android/java/res/layout/bookmark_drawer_title.xml deleted file mode 100644 index 3ef9d4b..0000000 --- a/chrome/android/java/res/layout/bookmark_drawer_title.xml +++ /dev/null
@@ -1,8 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- 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. --> - -<TextView xmlns:android="http://schemas.android.com/apk/res/android" - style="@style/BookmarkDrawerItemStyle" - android:textColor="?android:attr/textColorSecondary" /> \ No newline at end of file
diff --git a/chrome/android/java/res/layout/bookmark_main.xml b/chrome/android/java/res/layout/bookmark_main.xml index 685c8b0..5eb4beed 100644 --- a/chrome/android/java/res/layout/bookmark_main.xml +++ b/chrome/android/java/res/layout/bookmark_main.xml
@@ -3,25 +3,9 @@ Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. --> -<android.support.v4.widget.DrawerLayout +<org.chromium.chrome.browser.widget.selection.SelectableListLayout xmlns:android="http://schemas.android.com/apk/res/android" - android:id="@+id/bookmark_drawer_layout" + android:id="@+id/selectable_list" android:layout_width="match_parent" - android:layout_height="match_parent" > - - <org.chromium.chrome.browser.widget.selection.SelectableListLayout - android:id="@+id/selectable_list" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:background="@color/default_primary_color" /> - - <org.chromium.chrome.browser.bookmarks.BookmarkDrawerListView - android:id="@+id/bookmark_drawer_list" - android:layout_width="@dimen/drawer_width" - android:layout_height="match_parent" - android:layout_gravity="start" - android:background="@android:color/white" - android:choiceMode="singleChoice" - android:divider="@null" - android:dividerHeight="0dp" /> -</android.support.v4.widget.DrawerLayout> + android:layout_height="match_parent" + android:background="@color/default_primary_color" />
diff --git a/chrome/android/java/res/layout/search_widget_template.xml b/chrome/android/java/res/layout/search_widget_template.xml index 56db3421d..6781522 100644 --- a/chrome/android/java/res/layout/search_widget_template.xml +++ b/chrome/android/java/res/layout/search_widget_template.xml
@@ -38,9 +38,9 @@ android:id="@+id/microphone_icon" android:layout_width="48dp" android:layout_height="48dp" - android:src="@drawable/infobar_microphone" + android:src="@drawable/btn_mic" android:tint="@color/light_normal_color" - android:contentDescription="@null" - android:scaleType="centerInside" /> + android:scaleType="centerInside" + android:contentDescription="@string/accessibility_toolbar_btn_mic" /> </LinearLayout> \ No newline at end of file
diff --git a/chrome/android/java/res/values-v17/styles.xml b/chrome/android/java/res/values-v17/styles.xml index bfb8e10..e21804f00 100644 --- a/chrome/android/java/res/values-v17/styles.xml +++ b/chrome/android/java/res/values-v17/styles.xml
@@ -432,17 +432,6 @@ <style name="BookmarkMenuStyle" parent="Widget.AppCompat.ListPopupWindow"> <item name="android:popupBackground">@drawable/menu_bg</item> </style> - <style name="BookmarkDrawerItemStyle"> - <item name="android:layout_width">match_parent</item> - <item name="android:layout_height">?android:attr/listPreferredItemHeightSmall</item> - <item name="android:textAlignment">viewStart</item> - <item name="android:gravity">start|center_vertical</item> - <item name="android:paddingStart">@dimen/bookmark_drawer_drawable_padding</item> - <item name="android:paddingEnd">@dimen/bookmark_drawer_drawable_padding</item> - <item name="android:singleLine">true</item> - <item name="android:textAppearance">?android:attr/textAppearanceLargePopupMenu</item> - <item name="android:textSize">14sp</item> - </style> <!-- Contextual Search styles --> <style name="ContextualSearchTextViewLayout">
diff --git a/chrome/android/java/res/values/colors.xml b/chrome/android/java/res/values/colors.xml index 9b79693..7f1d80b 100644 --- a/chrome/android/java/res/values/colors.xml +++ b/chrome/android/java/res/values/colors.xml
@@ -180,7 +180,6 @@ <!-- Bookmark UI colors --> <color name="bookmark_detail_text">#212121</color> <color name="bookmark_detail_section">#7C7B79</color> - <color name="bookmark_drawer_selected_background_color">#F0F0F0</color> <!-- Favicon colors --> <color name="default_favicon_background_color">#ff787878</color>
diff --git a/chrome/android/java/res/values/dimens.xml b/chrome/android/java/res/values/dimens.xml index abd014c..0a30b9a6 100644 --- a/chrome/android/java/res/values/dimens.xml +++ b/chrome/android/java/res/values/dimens.xml
@@ -343,7 +343,6 @@ <dimen name="bookmark_item_popup_width">140dp</dimen> <dimen name="bookmark_folder_item_left">16dp</dimen> <dimen name="bookmark_minimum_dialog_size_tablet">500dp</dimen> - <dimen name="bookmark_drawer_drawable_padding">18dp</dimen> <!-- Bookmark widget dimensions --> <dimen name="bookmark_widget_min_width">64dp</dimen> @@ -456,6 +455,7 @@ <!-- TextBubble dimensions --> <dimen name="text_bubble_margin">2dp</dimen> <dimen name="text_bubble_corner_radius">3dp</dimen> + <dimen name="text_bubble_menu_anchor_y_inset">-14dp</dimen> <!-- Miscellaneous dimensions --> <dimen name="action_bar_shadow_height">10dp</dimen>
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkActionBar.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkActionBar.java index 06dad087..2589d04f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkActionBar.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkActionBar.java
@@ -146,19 +146,21 @@ getMenu().findItem(R.id.search_menu_id).setVisible(true); getMenu().findItem(R.id.edit_menu_id).setVisible(mCurrentFolder.isEditable()); - // If the parent folder is a top level node, we don't go up anymore. - if (mDelegate.getModel().getTopLevelFolderParentIDs().contains( - mCurrentFolder.getParentId())) { - if (TextUtils.isEmpty(mCurrentFolder.getTitle())) { - setTitle(R.string.bookmarks); - } else { - setTitle(mCurrentFolder.getTitle()); - } - setNavigationButton(NAVIGATION_BUTTON_MENU); + // If this is the root folder, we can't go up anymore. + if (folder.equals(mDelegate.getModel().getRootFolderId())) { + setTitle(R.string.bookmarks); + setNavigationButton(NAVIGATION_BUTTON_NONE); + return; + } + + if (mDelegate.getModel().getTopLevelFolderParentIDs().contains(mCurrentFolder.getParentId()) + && TextUtils.isEmpty(mCurrentFolder.getTitle())) { + setTitle(R.string.bookmarks); } else { setTitle(mCurrentFolder.getTitle()); - setNavigationButton(NAVIGATION_BUTTON_BACK); } + + setNavigationButton(NAVIGATION_BUTTON_BACK); } @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkDelegate.java index 3813d11..3eb632b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkDelegate.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkDelegate.java
@@ -4,8 +4,6 @@ package org.chromium.chrome.browser.bookmarks; -import android.support.v4.widget.DrawerLayout; - import org.chromium.chrome.browser.favicon.LargeIconBridge; import org.chromium.chrome.browser.widget.selection.SelectionDelegate; import org.chromium.components.bookmarks.BookmarkId; @@ -35,8 +33,7 @@ boolean isDialogUi(); /** - * Corresponds to any folder named list item in the side drawer. Shows bookmarks under the - * folder. + * Shows bookmarks contained in the specified folder. * @param folder Parent folder that contains bookmarks to show as its children. */ void openFolder(BookmarkId folder); @@ -53,21 +50,6 @@ void notifyStateChange(BookmarkUIObserver observer); /** - * @return Whether there is a drawer. - */ - boolean doesDrawerExist(); - - /** - * Close drawer if it's visible. - */ - void closeDrawer(); - - /** - * @return The current drawer layout instance, if it exists. - */ - DrawerLayout getDrawerLayout(); - - /** * Closes the Bookmark UI (if on phone) and opens the given bookmark. * @param bookmark bookmark to open. * @param launchLocation The UI location where user tried to open bookmark. It is one of
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkDrawerListItemView.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkDrawerListItemView.java deleted file mode 100644 index 19a8b41..0000000 --- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkDrawerListItemView.java +++ /dev/null
@@ -1,35 +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. - -package org.chromium.chrome.browser.bookmarks; - -import android.annotation.SuppressLint; -import android.content.Context; -import android.graphics.drawable.Drawable; -import android.support.v7.widget.AppCompatTextView; -import android.util.AttributeSet; - -import org.chromium.base.ApiCompatibilityUtils; -import org.chromium.chrome.R; -import org.chromium.chrome.browser.widget.TintedDrawable; - -@SuppressLint("Instantiatable") -class BookmarkDrawerListItemView extends AppCompatTextView { - public BookmarkDrawerListItemView(Context context, AttributeSet attrs) { - super(context, attrs); - } - - void setIcon(int iconDrawableId) { - if (iconDrawableId == 0) { - setCompoundDrawablePadding(0); - } else { - setCompoundDrawablePadding(getResources().getDimensionPixelSize( - R.dimen.bookmark_drawer_drawable_padding)); - } - - Drawable drawable = TintedDrawable.constructTintedDrawable(getResources(), iconDrawableId); - ApiCompatibilityUtils.setCompoundDrawablesRelativeWithIntrinsicBounds( - this, drawable, null, null, null); - } -}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkDrawerListView.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkDrawerListView.java deleted file mode 100644 index eaa36c4..0000000 --- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkDrawerListView.java +++ /dev/null
@@ -1,94 +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. - -package org.chromium.chrome.browser.bookmarks; - -import android.annotation.SuppressLint; -import android.content.Context; -import android.util.AttributeSet; -import android.view.View; -import android.widget.AdapterView; -import android.widget.ListView; - -import org.chromium.chrome.browser.bookmarks.BookmarkBridge.BookmarkModelObserver; -import org.chromium.components.bookmarks.BookmarkId; - -import java.util.List; - -/** - * Main drawer list view of bookmark UI. It is responsible for presenting different viewing - * modes and let users to choose. - */ -@SuppressLint("Instantiatable") -class BookmarkDrawerListView extends ListView implements BookmarkUIObserver { - private BookmarkDelegate mDelegate; - - private BookmarkModelObserver mBookmarkModelObserver = new BookmarkModelObserver() { - @Override - public void bookmarkModelChanged() { - mDelegate.notifyStateChange(BookmarkDrawerListView.this); - } - }; - - private final BookmarkDrawerListViewAdapter mAdapter = - new BookmarkDrawerListViewAdapter(); - - public BookmarkDrawerListView(final Context context, AttributeSet attrs) { - super(context, attrs); - - setAdapter(mAdapter); - setOnItemClickListener(new OnItemClickListener() { - @Override - public void onItemClick(AdapterView<?> parent, View view, int position, long id) { - mDelegate.closeDrawer(); - - BookmarkDrawerListViewAdapter.Item item = - (BookmarkDrawerListViewAdapter.Item) mAdapter.getItem(position); - - switch (item.mType) { - case BookmarkDrawerListViewAdapter.TYPE_FOLDER: - mDelegate.openFolder(item.mFolderId); - break; - default: - assert false; - } - } - }); - } - - void showLoadingUi() { - mAdapter.clear(); - mAdapter.notifyDataSetChanged(); - clearChoices(); - } - - // BookmarkUIObserver implementations. - - @Override - public void onBookmarkDelegateInitialized(BookmarkDelegate delegate) { - mDelegate = delegate; - delegate.getModel().addObserver(mBookmarkModelObserver); - mAdapter.setBookmarkUIDelegate(delegate); - delegate.addUIObserver(this); - } - - @Override - public void onDestroy() { - mDelegate.getModel().removeObserver(mBookmarkModelObserver); - mDelegate.removeUIObserver(this); - } - - @Override - public void onFolderStateSet(BookmarkId folder) { - mAdapter.updateList(); - setItemChecked(mAdapter.getItemPosition(BookmarkUIState.STATE_FOLDER, folder), - true); - } - - @Override - public void onSearchStateSet() {} - - @Override - public void onSelectionStateChange(List<BookmarkId> selectedBookmarks) {} -}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkDrawerListViewAdapter.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkDrawerListViewAdapter.java deleted file mode 100644 index 4a6edaea..0000000 --- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkDrawerListViewAdapter.java +++ /dev/null
@@ -1,331 +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. - -package org.chromium.chrome.browser.bookmarks; - -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.BaseAdapter; -import android.widget.TextView; - -import org.chromium.chrome.R; -import org.chromium.chrome.browser.bookmarks.BookmarkBridge.BookmarkItem; -import org.chromium.components.bookmarks.BookmarkId; - -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -/** - * BaseAdapter for BookmarkDrawerListView. It manages items to list there. - */ -class BookmarkDrawerListViewAdapter extends BaseAdapter { - static final int TYPE_FOLDER = 0; - static final int TYPE_DIVIDER = -1; - static final int TYPE_FOLDERS_TITLE = -2; - - static final int VIEW_TYPE_ITEM = 0; - static final int VIEW_TYPE_DIVIDER = 1; - static final int VIEW_TYPE_TITLE = 2; - - private BookmarkDelegate mDelegate; - private List<Item> mTopSection = new ArrayList<Item>(); - private List<Item> mBottomSection = new ArrayList<Item>(); - // array containing the order of sections - private List<?>[] mSections = {mTopSection, mBottomSection}; - - private BookmarkId mDesktopNodeId; - private BookmarkId mMobileNodeId; - private BookmarkId mOthersNodeId; - private List<BookmarkId> mManagedAndPartnerFolderIds; - - /** - * Represents each item in the list. - */ - static class Item { - final int mType; - final BookmarkId mFolderId; - - Item(int itemType) { - mType = itemType; - mFolderId = null; - } - - Item(BookmarkId folderId) { - assert folderId != null; - mType = TYPE_FOLDER; - mFolderId = folderId; - } - - @Override - public int hashCode() { - // hash function generated by Eclipse - final int prime = 31; - int result = 1; - result = prime * result + ((mFolderId == null) ? 0 : mFolderId.hashCode()); - result = prime * result + mType; - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) return true; - if (obj == null) return false; - if (getClass() != obj.getClass()) return false; - Item other = (Item) obj; - if (mFolderId == null) { - if (other.mFolderId != null) return false; - } else if (!mFolderId.equals(other.mFolderId)) { - return false; - } - if (mType != other.mType) { - return false; - } - return true; - } - } - - private void repopulateTopSection() { - mTopSection.clear(); - if (mDelegate.getModel().isFolderVisible(mMobileNodeId)) { - mTopSection.add(new Item(mMobileNodeId)); - } - if (mDelegate.getModel().isFolderVisible(mDesktopNodeId)) { - mTopSection.add(new Item(mDesktopNodeId)); - } - if (mDelegate.getModel().isFolderVisible(mOthersNodeId)) { - mTopSection.add(new Item(mOthersNodeId)); - } - if (mManagedAndPartnerFolderIds != null) { - for (BookmarkId id : mManagedAndPartnerFolderIds) { - mTopSection.add(new Item(id)); - } - } - } - - void updateList() { - mDesktopNodeId = mDelegate.getModel().getDesktopFolderId(); - mMobileNodeId = mDelegate.getModel().getMobileFolderId(); - mOthersNodeId = mDelegate.getModel().getOtherFolderId(); - mManagedAndPartnerFolderIds = mDelegate.getModel().getTopLevelFolderIDs(true, false); - repopulateTopSection(); - - setTopFolders(mDelegate.getModel().getTopLevelFolderIDs(false, true)); - notifyDataSetChanged(); - } - - /** - * Sets folders to show. - */ - void setTopFolders(List<BookmarkId> folders) { - mBottomSection.clear(); - - if (folders.size() > 0) { - // Add a divider and title to the top of the section. - mBottomSection.add(new Item(TYPE_DIVIDER)); - mBottomSection.add(new Item(TYPE_FOLDERS_TITLE)); - } - - // Add the rest of the items. - for (BookmarkId id : folders) { - mBottomSection.add(new Item(id)); - } - } - - /** - * Clear everything so that it doesn't have any entry. - */ - void clear() { - mTopSection.clear(); - mBottomSection.clear(); - } - - void setBookmarkUIDelegate(BookmarkDelegate delegate) { - mDelegate = delegate; - } - - /** - * Get the position in the list of a given item - * @param item Item to search for - * @return index of the item or -1 if not found - */ - int positionOfItem(Item item) { - int offset = 0; - for (List<?> section : mSections) { - int index = section.indexOf(item); - if (index != -1) { - return offset + index; - } - // If not found in current section, offset the potential result by - // the section size. - offset += section.size(); - } - return -1; - } - - /** - * Get the position in the list of a given bookmark folder id - * @param id Id of bookmark folder - * @return index of bookmark folder or -1 if not found - */ - int positionOfBookmarkId(BookmarkId id) { - return positionOfItem(new Item(id)); - } - - /** - * Get item position of the given mode. - */ - int getItemPosition(int state, Object modeDetail) { - if (state == BookmarkUIState.STATE_FOLDER) { - Set<BookmarkId> topLevelFolderParents = new HashSet<>(); - topLevelFolderParents.addAll(mDelegate.getModel().getTopLevelFolderParentIDs()); - topLevelFolderParents.add(mDesktopNodeId); - topLevelFolderParents.add(mOthersNodeId); - topLevelFolderParents.add(mMobileNodeId); - - // Find top folder id that contains |folder|. - BookmarkId topFolderId = (BookmarkId) modeDetail; - while (true) { - BookmarkId parentId = - mDelegate.getModel().getBookmarkById(topFolderId).getParentId(); - if (topLevelFolderParents.contains(parentId)) { - break; - } - topFolderId = parentId; - } - return positionOfBookmarkId(topFolderId); - } - - return -1; - } - - // BaseAdapter implementations. - - @Override - public boolean areAllItemsEnabled() { - return false; - } - - @Override - public boolean isEnabled(int position) { - Item item = (Item) getItem(position); - return item.mType != TYPE_DIVIDER && item.mType != TYPE_FOLDERS_TITLE; - } - - @Override - public int getItemViewType(int position) { - Item item = (Item) getItem(position); - if (item.mType == TYPE_DIVIDER) { - return VIEW_TYPE_DIVIDER; - } else if (item.mType == TYPE_FOLDERS_TITLE) { - return VIEW_TYPE_TITLE; - } else { - return VIEW_TYPE_ITEM; - } - } - - @Override - public int getViewTypeCount() { - return 3; - } - - @Override - public int getCount() { - int sum = 0; - for (List<?> section : mSections) { - sum += section.size(); - } - return sum; - } - - @Override - public long getItemId(int position) { - return position; - } - - @Override - public Object getItem(int position) { - if (position < 0) { - return null; - } - for (List<?> section : mSections) { - if (position < section.size()) { - return section.get(position); - } - position -= section.size(); - } - return null; - } - - @Override - public View getView(int position, View convertView, ViewGroup parent) { - final Item item = (Item) getItem(position); - - // Inflate view if convertView is null. - if (convertView == null) { - final int itemViewType = getItemViewType(position); - if (itemViewType == VIEW_TYPE_ITEM) { - convertView = LayoutInflater.from(parent.getContext()).inflate( - R.layout.bookmark_drawer_item, parent, false); - } else if (itemViewType == VIEW_TYPE_DIVIDER) { - convertView = LayoutInflater.from(parent.getContext()).inflate( - R.layout.bookmark_divider, parent, false); - } else if (itemViewType == VIEW_TYPE_TITLE) { - convertView = LayoutInflater.from(parent.getContext()).inflate( - R.layout.bookmark_drawer_title, parent, false); - } else { - assert false : "Invalid item view type."; - } - } - - if (item.mType == TYPE_DIVIDER) return convertView; - - if (item.mType == TYPE_FOLDERS_TITLE) { - String title = convertView.getContext().getResources().getString( - R.string.bookmark_drawer_folders); - ((TextView) convertView).setText(title); - return convertView; - } - - final BookmarkDrawerListItemView listItemView = - (BookmarkDrawerListItemView) convertView; - String title; - int iconDrawableId; - - switch (item.mType) { - case TYPE_FOLDER: - BookmarkItem folder = mDelegate.getModel().getBookmarkById(item.mFolderId); - // The folder shouldn't be null but there was one crash report for an NPE when - // trying to retrieve the BookmarkItem title. See crbug.com/709164. - if (folder != null) { - title = folder.getTitle(); - } else { - title = ""; - } - - if (mManagedAndPartnerFolderIds != null - && mManagedAndPartnerFolderIds.contains(item.mFolderId)) { - iconDrawableId = R.drawable.bookmark_managed; - } else if (item.mFolderId.equals(mMobileNodeId) - || item.mFolderId.equals(mOthersNodeId) - || item.mFolderId.equals(mDesktopNodeId)) { - iconDrawableId = R.drawable.bookmark_folder; - } else { - iconDrawableId = 0; - } - break; - default: - title = ""; - iconDrawableId = 0; - assert false; - } - - listItemView.setText(title); - listItemView.setIcon(iconDrawableId); - - return convertView; - } -}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkItemsAdapter.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkItemsAdapter.java index 0675e4ba..7619513 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkItemsAdapter.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkItemsAdapter.java
@@ -19,7 +19,6 @@ import org.chromium.chrome.browser.bookmarks.BookmarkBridge.BookmarkModelObserver; import org.chromium.chrome.browser.bookmarks.BookmarkPromoHeader.PromoHeaderShowingChangeListener; import org.chromium.components.bookmarks.BookmarkId; -import org.chromium.ui.base.DeviceFormFactor; import java.util.ArrayList; import java.util.List; @@ -31,28 +30,26 @@ BookmarkUIObserver, PromoHeaderShowingChangeListener { private static final int PROMO_HEADER_VIEW = 0; private static final int FOLDER_VIEW = 1; - private static final int DIVIDER_VIEW = 2; - private static final int BOOKMARK_VIEW = 3; + private static final int BOOKMARK_VIEW = 2; private static final int MAXIMUM_NUMBER_OF_SEARCH_RESULTS = 500; private static final String EMPTY_QUERY = null; + private final List<List<? extends Object>> mSections; + private final List<Object> mPromoHeaderSection = new ArrayList<>(); + private final List<BookmarkId> mFolderSection = new ArrayList<>(); + private final List<BookmarkId> mBookmarkSection = new ArrayList<>(); + + private final List<BookmarkRow> mBookmarkRows = new ArrayList<>(); + private final List<BookmarkRow> mFolderRows = new ArrayList<>(); + + private final List<BookmarkId> mTopLevelFolders = new ArrayList<>(); + private BookmarkDelegate mDelegate; private Context mContext; private BookmarkPromoHeader mPromoHeaderManager; - private boolean mShouldShowDividers; private String mSearchText; - private List<List<? extends Object>> mSections; - private List<Object> mPromoHeaderSection = new ArrayList<>(); - private List<Object> mFolderDividerSection; - private List<BookmarkId> mFolderSection = new ArrayList<>(); - private List<Object> mBookmarkDividerSection; - private List<BookmarkId> mBookmarkSection = new ArrayList<>(); - - private List<BookmarkRow> mBookmarkRows = new ArrayList<>(); - private List<BookmarkRow> mFolderRows = new ArrayList<>(); - private BookmarkModelObserver mBookmarkModelObserver = new BookmarkModelObserver() { @Override public void bookmarkNodeChanged(BookmarkItem node) { @@ -90,25 +87,9 @@ BookmarkItemsAdapter(Context context) { mContext = context; - // TODO(twellington): remove dividers entirely after the bookmarks 720dp layout is restyled - // to match the < 720dp style. - mShouldShowDividers = DeviceFormFactor.isLargeTablet(context); - mSections = new ArrayList<>(); mSections.add(mPromoHeaderSection); - - if (mShouldShowDividers) { - mFolderDividerSection = new ArrayList<>(); - mSections.add(mFolderDividerSection); - } - mSections.add(mFolderSection); - - if (mShouldShowDividers) { - mBookmarkDividerSection = new ArrayList<>(); - mSections.add(mBookmarkDividerSection); - } - mSections.add(mBookmarkSection); } @@ -166,22 +147,6 @@ updateHeaderAndNotify(); } - private void updateDividerSections() { - if (!mShouldShowDividers) return; - - mFolderDividerSection.clear(); - mBookmarkDividerSection.clear(); - - boolean isHeaderPresent = !mPromoHeaderSection.isEmpty(); - - if (isHeaderPresent && !mFolderSection.isEmpty()) { - mFolderDividerSection.add(null); - } - if ((isHeaderPresent || !mFolderSection.isEmpty()) && !mBookmarkSection.isEmpty()) { - mBookmarkDividerSection.add(null); - } - } - private void removeItem(int position) { List<?> section = getSection(position); assert section == mFolderSection || section == mBookmarkSection; @@ -218,9 +183,6 @@ if (section == mPromoHeaderSection) { return PROMO_HEADER_VIEW; - } else if (section == mFolderDividerSection - || section == mBookmarkDividerSection) { - return DIVIDER_VIEW; } else if (section == mFolderSection) { return FOLDER_VIEW; } else if (section == mBookmarkSection) { @@ -238,9 +200,6 @@ switch (viewType) { case PROMO_HEADER_VIEW: return mPromoHeaderManager.createHolder(parent); - case DIVIDER_VIEW: - return new ViewHolder(LayoutInflater.from(parent.getContext()).inflate( - R.layout.bookmark_divider, parent, false)) {}; case FOLDER_VIEW: BookmarkFolderRow folder = (BookmarkFolderRow) LayoutInflater.from( parent.getContext()).inflate(R.layout.bookmark_folder_row, parent, false); @@ -266,7 +225,6 @@ switch (getItemViewType(position)) { case PROMO_HEADER_VIEW: - case DIVIDER_VIEW: break; case FOLDER_VIEW: ((BookmarkRow) holder.itemView).setBookmarkId(id); @@ -301,6 +259,7 @@ mDelegate.addUIObserver(this); mDelegate.getModel().addObserver(mBookmarkModelObserver); mPromoHeaderManager = new BookmarkPromoHeader(mContext, this); + populateTopLevelFoldersList(); } @Override @@ -315,10 +274,15 @@ @Override public void onFolderStateSet(BookmarkId folder) { assert mDelegate != null; - setBookmarks(mDelegate.getModel().getChildIDs(folder, true, false), - mDelegate.getModel().getChildIDs(folder, false, true)); mSearchText = EMPTY_QUERY; + + if (folder.equals(mDelegate.getModel().getRootFolderId())) { + setBookmarks(mTopLevelFolders, new ArrayList<BookmarkId>()); + } else { + setBookmarks(mDelegate.getModel().getChildIDs(folder, true, false), + mDelegate.getModel().getChildIDs(folder, false, true)); + } } @Override @@ -348,7 +312,6 @@ private void updateHeaderAndNotify() { updateHeader(); - updateDividerSections(); notifyDataSetChanged(); } @@ -368,6 +331,22 @@ } } + private void populateTopLevelFoldersList() { + BookmarkId desktopNodeId = mDelegate.getModel().getDesktopFolderId(); + BookmarkId mobileNodeId = mDelegate.getModel().getMobileFolderId(); + BookmarkId othersNodeId = mDelegate.getModel().getOtherFolderId(); + + if (mDelegate.getModel().isFolderVisible(mobileNodeId)) { + mTopLevelFolders.add(mobileNodeId); + } + if (mDelegate.getModel().isFolderVisible(desktopNodeId)) { + mTopLevelFolders.add(desktopNodeId); + } + if (mDelegate.getModel().isFolderVisible(othersNodeId)) { + mTopLevelFolders.add(othersNodeId); + } + } + @VisibleForTesting public BookmarkDelegate getDelegateForTesting() { return mDelegate;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkManager.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkManager.java index 1b6af8d..c22811a 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkManager.java
@@ -8,8 +8,6 @@ import android.app.ActivityManager; import android.content.Context; import android.support.graphics.drawable.VectorDrawableCompat; -import android.support.v4.view.GravityCompat; -import android.support.v4.widget.DrawerLayout; import android.support.v7.widget.RecyclerView; import android.text.TextUtils; import android.view.View; @@ -17,6 +15,7 @@ import org.chromium.base.ContextUtils; import org.chromium.base.ObserverList; +import org.chromium.base.VisibleForTesting; import org.chromium.base.metrics.RecordUserAction; import org.chromium.chrome.R; import org.chromium.chrome.browser.BasicNativePage; @@ -59,8 +58,6 @@ private RecyclerView mRecyclerView; private BookmarkItemsAdapter mAdapter; private BookmarkActionBar mToolbar; - private DrawerLayout mDrawer; - private BookmarkDrawerListView mDrawerListView; private SelectionDelegate<BookmarkId> mSelectionDelegate; private final Stack<BookmarkUIState> mStateStack = new Stack<>(); private LargeIconBridge mLargeIconBridge; @@ -106,7 +103,6 @@ private final Runnable mModelLoadedRunnable = new Runnable() { @Override public void run() { - mDrawerListView.onBookmarkDelegateInitialized(BookmarkManager.this); mAdapter.onBookmarkDelegateInitialized(BookmarkManager.this); mToolbar.onBookmarkDelegateInitialized(BookmarkManager.this); if (!TextUtils.isEmpty(mInitialUrl)) { @@ -137,9 +133,6 @@ mBookmarkModel = new BookmarkModel(); mMainView = (ViewGroup) mActivity.getLayoutInflater().inflate(R.layout.bookmark_main, null); - mDrawer = (DrawerLayout) mMainView.findViewById(R.id.bookmark_drawer_layout); - mDrawerListView = (BookmarkDrawerListView) mMainView.findViewById( - R.id.bookmark_drawer_list); @SuppressWarnings("unchecked") SelectableListLayout<BookmarkId> selectableList = @@ -155,8 +148,8 @@ mRecyclerView = mSelectableListLayout.initializeRecyclerView(mAdapter); mToolbar = (BookmarkActionBar) mSelectableListLayout.initializeToolbar( - R.layout.bookmark_action_bar, mSelectionDelegate, 0, mDrawer, - R.id.normal_menu_group, R.id.selection_mode_menu_group, null, true, null); + R.layout.bookmark_action_bar, mSelectionDelegate, 0, null, R.id.normal_menu_group, + R.id.selection_mode_menu_group, R.color.default_primary_color, false, null); mToolbar.initializeSearchView( this, R.string.bookmark_action_bar_search, R.id.search_menu_id); @@ -214,13 +207,6 @@ * @return True if manager handles this event, false if it decides to ignore. */ public boolean onBackPressed() { - if (doesDrawerExist()) { - if (mDrawer.isDrawerVisible(GravityCompat.START)) { - mDrawer.closeDrawer(GravityCompat.START); - return true; - } - } - // TODO(twellington): replicate this behavior for other list UIs during unification. if (mSelectionDelegate.isSelectionEnabled()) { mSelectionDelegate.clearSelection(); @@ -296,7 +282,6 @@ */ private void initializeToLoadingState() { mToolbar.showLoadingUi(); - mDrawerListView.showLoadingUi(); assert mStateStack.isEmpty(); setState(BookmarkUIState.createLoadingState()); } @@ -388,23 +373,6 @@ } @Override - public boolean doesDrawerExist() { - return mDrawer != null; - } - - @Override - public void closeDrawer() { - if (!doesDrawerExist()) return; - - mDrawer.closeDrawer(GravityCompat.START); - } - - @Override - public DrawerLayout getDrawerLayout() { - return mDrawer; - } - - @Override public void openBookmark(BookmarkId bookmark, int launchLocation) { mSelectionDelegate.clearSelection(); if (BookmarkUtils.openBookmark( @@ -470,4 +438,11 @@ public void onEndSearch() { closeSearchUI(); } + + // Testing methods + + @VisibleForTesting + public BookmarkActionBar getToolbarForTests() { + return mToolbar; + } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkRow.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkRow.java index eadfccef..8644e69 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkRow.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkRow.java
@@ -20,7 +20,6 @@ import org.chromium.chrome.browser.widget.TintedImageButton; import org.chromium.chrome.browser.widget.selection.SelectableItemView; import org.chromium.components.bookmarks.BookmarkId; -import org.chromium.ui.base.DeviceFormFactor; import java.util.List; @@ -37,7 +36,6 @@ protected BookmarkId mBookmarkId; private ListPopupWindow mPopupMenu; private boolean mIsAttachedToWindow; - private boolean mShouldUseListItemBackground; /** * Constructor for inflating from XML. @@ -54,10 +52,10 @@ mBookmarkId = bookmarkId; BookmarkItem bookmarkItem = mDelegate.getModel().getBookmarkById(bookmarkId); clearPopup(); - if (isSelectable()) { - mMoreIcon.setVisibility(bookmarkItem.isEditable() ? VISIBLE : GONE); - setChecked(mDelegate.getSelectionDelegate().isItemSelected(bookmarkId)); - } + + mMoreIcon.setVisibility(bookmarkItem.isEditable() ? VISIBLE : GONE); + setChecked(mDelegate.getSelectionDelegate().isItemSelected(bookmarkId)); + super.setItem(bookmarkId); return bookmarkItem; } @@ -80,17 +78,8 @@ } private void updateSelectionState() { - if (isSelectable()) mMoreIcon.setClickable( - !mDelegate.getSelectionDelegate().isSelectionEnabled()); + mMoreIcon.setClickable(!mDelegate.getSelectionDelegate().isSelectionEnabled()); } - - /** - * @return Whether this row is selectable. - */ - protected boolean isSelectable() { - return true; - } - /** * Show drop-down menu after user click on more-info icon * @param view The anchor view for the menu @@ -178,26 +167,18 @@ mIconImageView = (ImageView) findViewById(R.id.bookmark_image); mTitleView = (TextView) findViewById(R.id.title); - if (isSelectable()) { - mMoreIcon = (TintedImageButton) findViewById(R.id.more); - mMoreIcon.setVisibility(VISIBLE); - mMoreIcon.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View view) { - showMenu(view); - } - }); - } - - // TODO(twellington): remove this after the bookmarks 720dp layout is restyled - // to match the < 720dp style. - mShouldUseListItemBackground = !DeviceFormFactor.isLargeTablet(getContext()); + mMoreIcon = (TintedImageButton) findViewById(R.id.more); + mMoreIcon.setVisibility(VISIBLE); + mMoreIcon.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View view) { + showMenu(view); + } + }); // TODO(twellington): Replace this with a MarginResizer after the bookmarks layout is width // constrained to 600dp. - if (mShouldUseListItemBackground) { - setLateralMarginsForDefaultDisplay(findViewById(R.id.bookmark_row)); - } + setLateralMarginsForDefaultDisplay(findViewById(R.id.bookmark_row)); } @Override @@ -217,17 +198,6 @@ } // SelectableItem overrides. - @Override - public boolean onLongClick(View view) { - if (!isSelectable()) return false; - return super.onLongClick(view); - } - - @Override - public boolean isChecked() { - if (!isSelectable()) return false; - return super.isChecked(); - } @Override public void toggle() { @@ -235,14 +205,8 @@ } @Override - public void setChecked(boolean checked) { - // Unselectable rows do not have highlight view. - if (isSelectable()) super.setChecked(checked); - } - - @Override public void onSelectionStateChange(List<BookmarkId> selectedBookmarks) { - if (isSelectable()) super.onSelectionStateChange(selectedBookmarks); + super.onSelectionStateChange(selectedBookmarks); updateSelectionState(); } @@ -265,11 +229,4 @@ @Override public void onSearchStateSet() {} - - @Override - public void setBackgroundResourceForGroupPosition( - boolean isFirstInGroup, boolean isLastInGroup) { - if (!mShouldUseListItemBackground) return; - super.setBackgroundResourceForGroupPosition(isFirstInGroup, isLastInGroup); - } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkUIState.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkUIState.java index e9c07cb..8d9cb74 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkUIState.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkUIState.java
@@ -108,8 +108,7 @@ if (mUrl == null || mState == STATE_INVALID) return false; if (mState == STATE_FOLDER) { - return mFolder != null && bookmarkModel.doesBookmarkExist(mFolder) - && !mFolder.equals(bookmarkModel.getRootFolderId()); + return mFolder != null && bookmarkModel.doesBookmarkExist(mFolder); } return true;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadUtils.java index e5dc7328..45fb196 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadUtils.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadUtils.java
@@ -39,6 +39,7 @@ import org.chromium.chrome.browser.download.ui.BackendProvider.DownloadDelegate; import org.chromium.chrome.browser.download.ui.DownloadFilter; import org.chromium.chrome.browser.download.ui.DownloadHistoryItemWrapper; +import org.chromium.chrome.browser.feature_engagement_tracker.FeatureEngagementTrackerFactory; import org.chromium.chrome.browser.offlinepages.DownloadUiActionFlags; import org.chromium.chrome.browser.offlinepages.OfflinePageBridge; import org.chromium.chrome.browser.offlinepages.downloads.OfflinePageDownloadBridge; @@ -46,6 +47,8 @@ import org.chromium.chrome.browser.tabmodel.TabModel.TabLaunchType; import org.chromium.chrome.browser.tabmodel.document.TabDelegate; import org.chromium.chrome.browser.util.IntentUtils; +import org.chromium.components.feature_engagement_tracker.EventConstants; +import org.chromium.components.feature_engagement_tracker.FeatureEngagementTracker; import org.chromium.content_public.browser.DownloadState; import org.chromium.content_public.browser.LoadUrlParams; import org.chromium.ui.base.DeviceFormFactor; @@ -216,6 +219,11 @@ bridge.destroy(); DownloadUtils.recordDownloadPageMetrics(tab); } + + FeatureEngagementTracker tracker = + FeatureEngagementTrackerFactory.getFeatureEngagementTrackerForProfile( + tab.getProfile()); + tracker.notifyEvent(EventConstants.DOWNLOAD_PAGE_STARTED); } /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunActivity.java index 66d20a5a..b5ac2c5 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunActivity.java
@@ -27,6 +27,7 @@ import org.chromium.chrome.browser.preferences.datareduction.DataReductionPromoUtils; import org.chromium.chrome.browser.preferences.datareduction.DataReductionProxyUma; import org.chromium.chrome.browser.profiles.Profile; +import org.chromium.chrome.browser.searchwidget.SearchWidgetProvider; import org.chromium.chrome.browser.util.IntentUtils; import java.lang.ref.WeakReference; @@ -46,6 +47,24 @@ * The activity might be run more than once, e.g. 1) for ToS and sign-in, and 2) for intro. */ public class FirstRunActivity extends AsyncInitializationActivity implements FirstRunPageDelegate { + /** Alerted about various events when FirstRunActivity performs them. */ + public interface FirstRunActivityObserver { + /** See {@link #onFlowIsKnown}. */ + void onFlowIsKnown(Bundle freProperties); + + /** See {@link #acceptTermsOfService}. */ + void onAcceptTermsOfService(); + + /** See {@link #jumpToPage}. */ + void onJumpToPage(int position); + + /** Called when First Run is completed. */ + void onUpdateCachedEngineName(); + + /** See {@link #abortFirstRunExperience}. */ + void onAbortFirstRunExperience(); + } + protected static final String TAG = "FirstRunActivity"; // Incoming parameters: @@ -95,6 +114,8 @@ @VisibleForTesting static FirstRunGlue sGlue = new FirstRunGlueImpl(); + private static FirstRunActivityObserver sObserver; + private boolean mShowWelcomePage = true; private String mResultSignInAccountName; @@ -241,6 +262,7 @@ skipPagesIfNecessary(); } + if (sObserver != null) sObserver.onFlowIsKnown(mFreProperties); recordFreProgressHistogram(mFreProgressStates.get(0)); } }; @@ -391,6 +413,7 @@ finishAllTheActivities(getLocalClassName(), Activity.RESULT_CANCELED, intent); sendPendingIntentIfNecessary(false); + if (sObserver != null) sObserver.onAbortFirstRunExperience(); } @Override @@ -442,6 +465,10 @@ resultData.putExtras(mFreProperties); finishAllTheActivities(getLocalClassName(), Activity.RESULT_OK, resultData); + // Update the search engine name cached by the widget. + SearchWidgetProvider.updateCachedEngineName(); + if (sObserver != null) sObserver.onUpdateCachedEngineName(); + sendPendingIntentIfNecessary(true); } @@ -464,7 +491,9 @@ @Override public boolean didAcceptTermsOfService() { - return sGlue.didAcceptTermsOfService(getApplicationContext()); + boolean result = sGlue.didAcceptTermsOfService(getApplicationContext()); + if (sObserver != null) sObserver.onAcceptTermsOfService(); + return result; } @Override @@ -546,6 +575,8 @@ * @param position A page index to transition to. */ private boolean jumpToPage(int position) { + if (sObserver != null) sObserver.onJumpToPage(position); + if (mShowWelcomePage && !didAcceptTermsOfService()) { return position == 0; } @@ -603,9 +634,9 @@ CustomTabActivity.showInfoPage(this, getString(url)); } - /** Returns whether or not First Run is ready for interaction. */ @VisibleForTesting - public boolean isPostNativePageSequenceCreated() { - return mPostNativePageSequenceCreated; + public static void setObserverForTest(FirstRunActivityObserver observer) { + assert sObserver == null; + sObserver = observer; } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/searchwidget/SearchWidgetProvider.java b/chrome/android/java/src/org/chromium/chrome/browser/searchwidget/SearchWidgetProvider.java index cc0b913ba..d66b67a8 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/searchwidget/SearchWidgetProvider.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/searchwidget/SearchWidgetProvider.java
@@ -95,14 +95,7 @@ } private void updateCachedEngineName() { - assert LibraryLoader.isInitialized(); - - // Getting an instance of the TemplateUrlService requires that the native library be - // loaded, but the TemplateUrlService also itself needs to be initialized. - TemplateUrlService service = TemplateUrlService.getInstance(); - assert service.isLoaded(); - SearchWidgetProvider.updateCachedEngineName( - service.getDefaultSearchEngineTemplateUrl().getShortName()); + SearchWidgetProvider.updateCachedEngineName(); } } @@ -120,7 +113,7 @@ "org.chromium.chrome.browser.searchwidget.IS_VOICE_SEARCH_AVAILABLE"; private static final String PREF_NUM_CONSECUTIVE_CRASHES = "org.chromium.chrome.browser.searchwidget.NUM_CONSECUTIVE_CRASHES"; - private static final String PREF_SEARCH_ENGINE_SHORTNAME = + static final String PREF_SEARCH_ENGINE_SHORTNAME = "org.chromium.chrome.browser.searchwidget.SEARCH_ENGINE_SHORTNAME"; /** Number of consecutive crashes this widget will absorb before giving up. */ @@ -263,7 +256,7 @@ } // Update what string is displayed by the widget. - String text = TextUtils.isEmpty(engineName) + String text = TextUtils.isEmpty(engineName) || !shouldShowFullString() ? context.getString(R.string.search_widget_default) : context.getString(R.string.search_with_product, engineName); views.setTextViewText(R.id.title, text); @@ -288,6 +281,19 @@ } } + /** Attempts to update the cached search engine name. */ + public static void updateCachedEngineName() { + ThreadUtils.assertOnUiThread(); + if (!LibraryLoader.isInitialized()) return; + + // Getting an instance of the TemplateUrlService requires that the native library be + // loaded, but the TemplateUrlService also itself needs to be initialized. + TemplateUrlService service = TemplateUrlService.getInstance(); + if (!service.isLoaded()) return; + + updateCachedEngineName(service.getDefaultSearchEngineTemplateUrl().getShortName()); + } + /** * Updates the name of the user's default search engine that is cached in SharedPreferences. * Caching it in SharedPreferences prevents us from having to load the native library and the @@ -295,6 +301,9 @@ */ static void updateCachedEngineName(String engineName) { SharedPreferences prefs = getDelegate().getSharedPreferences(); + + if (!shouldShowFullString()) engineName = null; + if (!TextUtils.equals(getCachedEngineName(prefs), engineName)) { prefs.edit().putString(PREF_SEARCH_ENGINE_SHORTNAME, engineName).apply(); performUpdate(null); @@ -362,6 +371,12 @@ } } + static boolean shouldShowFullString() { + Intent freIntent = FirstRunFlowSequencer.checkIfFirstRunIsNecessary( + getDelegate().getContext(), null, false); + return freIntent == null; + } + /** Sets an {@link SearchWidgetProviderDelegate} to interact with. */ @VisibleForTesting static void setDelegateForTest(SearchWidgetProviderDelegate delegate) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java index 560c303..411f44b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java
@@ -18,6 +18,7 @@ import android.view.View.OnClickListener; import android.view.ViewGroup.MarginLayoutParams; import android.widget.FrameLayout; +import android.widget.PopupWindow.OnDismissListener; import org.chromium.base.ApiCompatibilityUtils; import org.chromium.base.Callback; @@ -27,6 +28,7 @@ import org.chromium.base.metrics.RecordUserAction; import org.chromium.chrome.R; import org.chromium.chrome.browser.ChromeActivity; +import org.chromium.chrome.browser.ChromeTabbedActivity; import org.chromium.chrome.browser.NativePage; import org.chromium.chrome.browser.TabLoadStatus; import org.chromium.chrome.browser.UrlConstants; @@ -43,11 +45,14 @@ import org.chromium.chrome.browser.compositor.layouts.OverviewModeBehavior; import org.chromium.chrome.browser.compositor.layouts.OverviewModeBehavior.OverviewModeObserver; import org.chromium.chrome.browser.compositor.layouts.SceneChangeObserver; +import org.chromium.chrome.browser.download.DownloadUtils; +import org.chromium.chrome.browser.feature_engagement_tracker.FeatureEngagementTrackerFactory; import org.chromium.chrome.browser.fullscreen.BrowserStateBrowserControlsVisibilityDelegate; import org.chromium.chrome.browser.fullscreen.FullscreenManager; import org.chromium.chrome.browser.ntp.IncognitoNewTabPage; import org.chromium.chrome.browser.ntp.NativePageFactory; import org.chromium.chrome.browser.ntp.NewTabPage; +import org.chromium.chrome.browser.offlinepages.OfflinePageBridge; import org.chromium.chrome.browser.omnibox.LocationBar; import org.chromium.chrome.browser.omnibox.UrlFocusChangeListener; import org.chromium.chrome.browser.partnercustomizations.HomepageManager; @@ -70,6 +75,10 @@ import org.chromium.chrome.browser.toolbar.ActionModeController.ActionBarDelegate; import org.chromium.chrome.browser.widget.findinpage.FindToolbarManager; import org.chromium.chrome.browser.widget.findinpage.FindToolbarObserver; +import org.chromium.chrome.browser.widget.textbubble.ViewAnchoredTextBubble; +import org.chromium.components.feature_engagement_tracker.EventConstants; +import org.chromium.components.feature_engagement_tracker.FeatureConstants; +import org.chromium.components.feature_engagement_tracker.FeatureEngagementTracker; import org.chromium.content_public.browser.LoadUrlParams; import org.chromium.content_public.browser.NavigationController; import org.chromium.content_public.browser.NavigationEntry; @@ -139,6 +148,7 @@ private final ActionModeController mActionModeController; private final LoadProgressSimulator mLoadProgressSimulator; private final Callback<Boolean> mUrlFocusChangedCallback; + private final Handler mHandler = new Handler(); private BrowserStateBrowserControlsVisibilityDelegate mControlsVisibilityDelegate; private int mFullscreenFocusToken = FullscreenManager.INVALID_TOKEN; @@ -153,6 +163,8 @@ private AppMenuButtonHelper mAppMenuButtonHelper; + private ViewAnchoredTextBubble mTextBubble; + private HomepageStateListener mHomepageStateListener; private boolean mInitializedWithNative; @@ -340,6 +352,16 @@ } @Override + public void onPageLoadFinished(Tab tab) { + if (tab.isShowingErrorPage()) { + handleIPHForErrorPageShown(tab); + return; + } + + handleIPHForSuccessfulPageLoad(tab); + } + + @Override public void onLoadStarted(Tab tab, boolean toDifferentDocument) { if (!toDifferentDocument) return; updateButtonStatus(); @@ -481,6 +503,67 @@ if (mToolbar.getProgressBar() != null) mToolbar.getProgressBar().finish(false); } } + + private void handleIPHForSuccessfulPageLoad(final Tab tab) { + if (mTextBubble != null) { + mTextBubble.dismiss(); + mTextBubble = null; + return; + } + + // TODO(shaktisahu): Find out if the download menu button is enabled (crbug/712438). + if (!(activity instanceof ChromeTabbedActivity) + || DeviceFormFactor.isTablet(mToolbar.getContext()) + || activity.isInOverviewMode() + || !DownloadUtils.isAllowedToDownloadPage(tab)) { + return; + } + + final FeatureEngagementTracker tracker = + FeatureEngagementTrackerFactory.getFeatureEngagementTrackerForProfile( + tab.getProfile()); + + if (!tracker.shouldTriggerHelpUI(FeatureConstants.DOWNLOAD_PAGE_FEATURE)) return; + + mTextBubble = new ViewAnchoredTextBubble(mToolbar.getContext(), getMenuAnchor(), + R.string.iph_download_page_for_offline_usage_text); + mTextBubble.setDismissOnTouchInteraction(true); + mTextBubble.addOnDismissListener(new OnDismissListener() { + @Override + public void onDismiss() { + mHandler.post(new Runnable() { + @Override + public void run() { + tracker.dismissed(); + activity.getAppMenuHandler().setMenuHighlight(null); + } + }); + } + }); + activity.getAppMenuHandler().setMenuHighlight(R.id.offline_page_id); + int yInsetPx = activity.getResources().getDimensionPixelOffset( + R.dimen.text_bubble_menu_anchor_y_inset); + mTextBubble.setInsetPx(0, yInsetPx, 0, 0); + mTextBubble.show(); + } + + private void handleIPHForErrorPageShown(Tab tab) { + if (!(activity instanceof ChromeTabbedActivity) + || DeviceFormFactor.isTablet(mToolbar.getContext())) { + return; + } + + OfflinePageBridge bridge = OfflinePageBridge.getForProfile(tab.getProfile()); + if (bridge == null + || !bridge.isShowingDownloadButtonInErrorPage(tab.getWebContents())) { + return; + } + + FeatureEngagementTracker tracker = + FeatureEngagementTrackerFactory.getFeatureEngagementTrackerForProfile( + tab.getProfile()); + tracker.notifyEvent(EventConstants.USER_HAS_SEEN_DINO); + } }; mBookmarksObserver = new BookmarkBridge.BookmarkModelObserver() {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/selection/SelectableListToolbar.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/selection/SelectableListToolbar.java index a483eb00..d94bab3 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/widget/selection/SelectableListToolbar.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/selection/SelectableListToolbar.java
@@ -82,13 +82,13 @@ } /** No navigation button is displayed. **/ - protected static final int NAVIGATION_BUTTON_NONE = 0; + public static final int NAVIGATION_BUTTON_NONE = 0; /** Button to open the DrawerLayout. Only valid if mDrawerLayout is set. **/ - protected static final int NAVIGATION_BUTTON_MENU = 1; + public static final int NAVIGATION_BUTTON_MENU = 1; /** Button to navigate back. This calls {@link #onNavigationBack()}. **/ - protected static final int NAVIGATION_BUTTON_BACK = 2; + public static final int NAVIGATION_BUTTON_BACK = 2; /** Button to clear the selection. **/ - protected static final int NAVIGATION_BUTTON_SELECTION_BACK = 3; + public static final int NAVIGATION_BUTTON_SELECTION_BACK = 3; /** An observer list for this toolbar. */ private final ObserverList<SelectableListToolbarObserver> mObservers = new ObserverList<>(); @@ -594,4 +594,9 @@ public View getSearchViewForTests() { return mSearchView; } + + @VisibleForTesting + public int getNavigationButtonForTests() { + return mNavigationButton; + } }
diff --git a/chrome/android/java/strings/android_chrome_strings.grd b/chrome/android/java/strings/android_chrome_strings.grd index cb60f363..1160091 100644 --- a/chrome/android/java/strings/android_chrome_strings.grd +++ b/chrome/android/java/strings/android_chrome_strings.grd
@@ -2356,9 +2356,6 @@ <message name="IDS_BOOKMARK_PAGE_FAILED" desc="Message shown when the user tries to add a bookmark but the browser fails to save it."> Failed to add bookmark. </message> - <message name="IDS_BOOKMARK_DRAWER_FOLDERS" desc="Title for the list of folders in the drawer view. [CHAR-LIMIT=32]"> - Folders - </message> <message name="IDS_BOOKMARK_PARENT_FOLDER" desc="Header text for title of parent folder of the bookmark [CHAR-LIMIT=32]"> Parent folder </message> @@ -2945,6 +2942,11 @@ VIDEO </message> + <!-- In-Product Help strings --> + <message name="IDS_IPH_DOWNLOAD_PAGE_FOR_OFFLINE_USAGE_TEXT" desc="The in-product-help message after a successful navigation prompting user to download the pages to view offline."> + Download pages to use them offline + </message> + <!-- Search Widget strings --> <message name="IDS_SEARCH_WIDGET_DEFAULT" desc="Default text for the search widget"> Search
diff --git a/chrome/android/java_sources.gni b/chrome/android/java_sources.gni index 22fb56f..803d3e4 100644 --- a/chrome/android/java_sources.gni +++ b/chrome/android/java_sources.gni
@@ -101,9 +101,6 @@ "java/src/org/chromium/chrome/browser/bookmarks/BookmarkAddEditFolderActivity.java", "java/src/org/chromium/chrome/browser/bookmarks/BookmarkBridge.java", "java/src/org/chromium/chrome/browser/bookmarks/BookmarkDelegate.java", - "java/src/org/chromium/chrome/browser/bookmarks/BookmarkDrawerListItemView.java", - "java/src/org/chromium/chrome/browser/bookmarks/BookmarkDrawerListView.java", - "java/src/org/chromium/chrome/browser/bookmarks/BookmarkDrawerListViewAdapter.java", "java/src/org/chromium/chrome/browser/bookmarks/BookmarkEditActivity.java", "java/src/org/chromium/chrome/browser/bookmarks/BookmarkFolderRow.java", "java/src/org/chromium/chrome/browser/bookmarks/BookmarkFolderSelectActivity.java", @@ -1376,6 +1373,7 @@ "javatests/src/org/chromium/chrome/browser/feedback/ConnectivityCheckerTestBase.java", "javatests/src/org/chromium/chrome/browser/feedback/ConnectivityTaskTest.java", "javatests/src/org/chromium/chrome/browser/feedback/FeedbackCollectorTest.java", + "javatests/src/org/chromium/chrome/browser/firstrun/FirstRunActivityTestObserver.java", "javatests/src/org/chromium/chrome/browser/firstrun/FirstRunIntegrationTest.java", "javatests/src/org/chromium/chrome/browser/fullscreen/FullscreenManagerTest.java", "javatests/src/org/chromium/chrome/browser/gcore/MockConnectedTask.java",
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkTest.java index 6f5535f..e98e844c 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkTest.java
@@ -21,6 +21,7 @@ import org.chromium.chrome.browser.ChromeActivity; import org.chromium.chrome.browser.UrlConstants; import org.chromium.chrome.browser.bookmarks.BookmarkBridge.BookmarkItem; +import org.chromium.chrome.browser.widget.selection.SelectableListToolbar; import org.chromium.chrome.test.ChromeActivityTestCaseBase; import org.chromium.chrome.test.util.ActivityUtils; import org.chromium.chrome.test.util.BookmarkTestUtil; @@ -178,6 +179,40 @@ } @MediumTest + public void testTopLevelFolders() throws InterruptedException { + openBookmarkManager(); + final BookmarkDelegate delegate = + ((BookmarkItemsAdapter) mItemsContainer.getAdapter()).getDelegateForTesting(); + final BookmarkActionBar toolbar = ((BookmarkManager) delegate).getToolbarForTests(); + + // Open the "Mobile bookmarks" folder. + ThreadUtils.runOnUiThreadBlocking(new Runnable() { + @Override + public void run() { + delegate.openFolder(mBookmarkModel.getMobileFolderId()); + } + }); + + assertEquals(SelectableListToolbar.NAVIGATION_BUTTON_BACK, + toolbar.getNavigationButtonForTests()); + assertFalse(toolbar.getMenu().findItem(R.id.edit_menu_id).isVisible()); + + // Call BookmarkActionBar#onClick() to activate the navigation button. + ThreadUtils.runOnUiThreadBlocking(new Runnable() { + @Override + public void run() { + toolbar.onClick(toolbar); + } + }); + + // Check that we are in the root folder. + assertEquals("Bookmarks", toolbar.getTitle()); + assertEquals(SelectableListToolbar.NAVIGATION_BUTTON_NONE, + toolbar.getNavigationButtonForTests()); + assertFalse(toolbar.getMenu().findItem(R.id.edit_menu_id).isVisible()); + } + + @MediumTest public void testSearchBookmarks() throws Exception { BookmarkPromoHeader.setShouldShowForTests(); addBookmark(TEST_PAGE_TITLE_GOOGLE, mTestPage);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/firstrun/FirstRunActivityTestObserver.java b/chrome/android/javatests/src/org/chromium/chrome/browser/firstrun/FirstRunActivityTestObserver.java new file mode 100644 index 0000000..67433e9 --- /dev/null +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/firstrun/FirstRunActivityTestObserver.java
@@ -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. + +package org.chromium.chrome.browser.firstrun; + +import android.os.Bundle; + +import org.chromium.base.test.util.CallbackHelper; + +/** Records when the FirstRunActivity has progressed through various states. */ +public class FirstRunActivityTestObserver implements FirstRunActivity.FirstRunActivityObserver { + public final CallbackHelper flowIsKnownCallback = new CallbackHelper(); + public final CallbackHelper acceptTermsOfServiceCallback = new CallbackHelper(); + public final CallbackHelper jumpToPageCallback = new CallbackHelper(); + public final CallbackHelper updateCachedEngineCallback = new CallbackHelper(); + public final CallbackHelper abortFirstRunExperienceCallback = new CallbackHelper(); + + public Bundle freProperties; + + @Override + public void onFlowIsKnown(Bundle freProperties) { + this.freProperties = freProperties; + flowIsKnownCallback.notifyCalled(); + } + + @Override + public void onAcceptTermsOfService() { + acceptTermsOfServiceCallback.notifyCalled(); + } + + @Override + public void onJumpToPage(int position) { + jumpToPageCallback.notifyCalled(); + } + + @Override + public void onUpdateCachedEngineName() { + updateCachedEngineCallback.notifyCalled(); + } + + @Override + public void onAbortFirstRunExperience() { + abortFirstRunExperienceCallback.notifyCalled(); + } +} \ No newline at end of file
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/firstrun/FirstRunIntegrationTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/firstrun/FirstRunIntegrationTest.java index df5bf024c..6f4df703 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/firstrun/FirstRunIntegrationTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/firstrun/FirstRunIntegrationTest.java
@@ -10,17 +10,21 @@ import android.content.Context; import android.content.Intent; import android.net.Uri; +import android.os.Bundle; import android.support.customtabs.CustomTabsIntent; +import android.support.test.filters.MediumTest; import android.support.test.filters.SmallTest; -import android.test.InstrumentationTestCase; +import android.widget.Button; +import org.chromium.base.ThreadUtils; import org.chromium.base.test.util.CommandLineFlags; +import org.chromium.chrome.R; import org.chromium.chrome.browser.ChromeSwitches; import org.chromium.chrome.browser.ChromeTabbedActivity; import org.chromium.chrome.browser.customtabs.CustomTabActivity; import org.chromium.chrome.browser.document.ChromeLauncherActivity; import org.chromium.chrome.browser.searchwidget.SearchActivity; -import org.chromium.chrome.test.util.ApplicationTestUtils; +import org.chromium.chrome.test.MultiActivityTestBase; import org.chromium.content.browser.test.util.Criteria; import org.chromium.content.browser.test.util.CriteriaHelper; @@ -28,16 +32,19 @@ * Integration test suite for the first run experience. */ @CommandLineFlags.Remove(ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE) -public class FirstRunIntegrationTest extends InstrumentationTestCase { +public class FirstRunIntegrationTest extends MultiActivityTestBase { + private FirstRunActivityTestObserver mTestObserver = new FirstRunActivityTestObserver(); + private Activity mActivity; + @Override public void setUp() throws Exception { super.setUp(); - ApplicationTestUtils.setUp(getInstrumentation().getTargetContext(), true); + FirstRunActivity.setObserverForTest(mTestObserver); } @Override public void tearDown() throws Exception { - ApplicationTestUtils.tearDown(getInstrumentation().getTargetContext()); + if (mActivity != null) mActivity.finish(); super.tearDown(); } @@ -164,4 +171,121 @@ assertEquals(0, freMonitor.getHits()); } + @SmallTest + public void testAbortFirstRun() throws Exception { + final ActivityMonitor freMonitor = + new ActivityMonitor(FirstRunActivity.class.getName(), null, false); + Instrumentation instrumentation = getInstrumentation(); + instrumentation.addMonitor(freMonitor); + + final Context context = instrumentation.getTargetContext(); + Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://test.com")); + intent.setPackage(context.getPackageName()); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + context.startActivity(intent); + + // Because the AsyncInitializationActivity notices that the FRE hasn't been run yet, it + // redirects to it. Once the user closes the FRE, the user should be kicked back into the + // startup flow where they were interrupted. + mActivity = instrumentation.waitForMonitorWithTimeout( + freMonitor, CriteriaHelper.DEFAULT_MAX_TIME_TO_POLL); + instrumentation.removeMonitor(freMonitor); + ActivityMonitor activityMonitor = + new ActivityMonitor(ChromeLauncherActivity.class.getName(), null, false); + instrumentation.addMonitor(activityMonitor); + + assertEquals(0, mTestObserver.abortFirstRunExperienceCallback.getCallCount()); + mActivity.onBackPressed(); + mTestObserver.abortFirstRunExperienceCallback.waitForCallback( + "FirstRunActivity didn't abort", 0); + + mActivity = instrumentation.waitForMonitorWithTimeout( + activityMonitor, CriteriaHelper.DEFAULT_MAX_TIME_TO_POLL); + CriteriaHelper.pollInstrumentationThread(new Criteria() { + @Override + public boolean isSatisfied() { + return mActivity.isFinishing(); + } + }); + } + + @MediumTest + public void testClickThroughFirstRun() throws Exception { + final ActivityMonitor freMonitor = + new ActivityMonitor(FirstRunActivity.class.getName(), null, false); + Instrumentation instrumentation = getInstrumentation(); + instrumentation.addMonitor(freMonitor); + + final Context context = instrumentation.getTargetContext(); + Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://test.com")); + intent.setPackage(context.getPackageName()); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + context.startActivity(intent); + + // Because the AsyncInitializationActivity notices that the FRE hasn't been run yet, it + // redirects to it. Once the user closes the FRE, the user should be kicked back into the + // startup flow where they were interrupted. + mActivity = instrumentation.waitForMonitorWithTimeout( + freMonitor, CriteriaHelper.DEFAULT_MAX_TIME_TO_POLL); + instrumentation.removeMonitor(freMonitor); + ActivityMonitor activityMonitor = + new ActivityMonitor(ChromeTabbedActivity.class.getName(), null, false); + instrumentation.addMonitor(activityMonitor); + + mTestObserver.flowIsKnownCallback.waitForCallback("Failed to finalize the flow", 0); + Bundle freProperties = mTestObserver.freProperties; + assertEquals(0, mTestObserver.updateCachedEngineCallback.getCallCount()); + + // Accept the ToS. + if (freProperties.getBoolean(FirstRunActivity.SHOW_WELCOME_PAGE)) { + clickButton(mActivity, R.id.terms_accept, "Failed to accept ToS"); + mTestObserver.acceptTermsOfServiceCallback.waitForCallback( + "Failed to accept the ToS", 0); + mTestObserver.jumpToPageCallback.waitForCallback( + "Failed to try moving to the next screen", 0); + } + + // Acknowledge that Data Saver will be enabled. + if (freProperties.getBoolean(FirstRunActivity.SHOW_DATA_REDUCTION_PAGE)) { + int jumpCallCount = mTestObserver.jumpToPageCallback.getCallCount(); + clickButton(mActivity, R.id.next_button, "Failed to skip data saver"); + mTestObserver.jumpToPageCallback.waitForCallback( + "Failed to try moving to next screen", jumpCallCount); + } + + // Don't sign in the user. + if (freProperties.getBoolean(FirstRunActivity.SHOW_SIGNIN_PAGE)) { + int jumpCallCount = mTestObserver.jumpToPageCallback.getCallCount(); + clickButton(mActivity, R.id.negative_button, "Failed to skip signing-in"); + mTestObserver.jumpToPageCallback.waitForCallback( + "Failed to try moving to next screen", jumpCallCount); + } + + // FRE should be completed now, which will kick the user back into the interrupted flow. + // In this case, the user gets sent to the ChromeTabbedActivity after a View Intent is + // processed by ChromeLauncherActivity. + mTestObserver.updateCachedEngineCallback.waitForCallback( + "Failed to alert search widgets that an update is necessary", 0); + mActivity = instrumentation.waitForMonitorWithTimeout( + activityMonitor, CriteriaHelper.DEFAULT_MAX_TIME_TO_POLL); + assertNotNull(mActivity); + } + + private void clickButton(final Activity activity, final int id, final String message) { + CriteriaHelper.pollUiThread(new Criteria() { + @Override + public boolean isSatisfied() { + return activity.findViewById(id) != null; + } + }); + + ThreadUtils.runOnUiThread(new Runnable() { + @Override + public void run() { + Button button = (Button) activity.findViewById(id); + assertNotNull(message, button); + button.performClick(); + } + }); + } }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/searchwidget/SearchWidgetProviderTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/searchwidget/SearchWidgetProviderTest.java index 18161df..c7f970fb 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/searchwidget/SearchWidgetProviderTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/searchwidget/SearchWidgetProviderTest.java
@@ -28,6 +28,7 @@ import org.chromium.chrome.browser.ChromeSwitches; import org.chromium.chrome.browser.firstrun.FirstRunActivity; import org.chromium.chrome.browser.util.IntentUtils; +import org.chromium.chrome.test.util.ApplicationTestUtils; import org.chromium.content.browser.test.util.CriteriaHelper; import java.util.ArrayList; @@ -89,6 +90,7 @@ @Override public void setUp() throws Exception { super.setUp(); + ApplicationTestUtils.setUp(getInstrumentation().getTargetContext(), true); SearchActivity.disableForTests(); mContext = new TestContext(); @@ -96,6 +98,12 @@ SearchWidgetProvider.setDelegateForTest(mDelegate); } + @Override + public void tearDown() throws Exception { + ApplicationTestUtils.tearDown(getInstrumentation().getTargetContext()); + super.tearDown(); + } + @SmallTest public void testUpdateAll() { SearchWidgetProvider.handleAction( @@ -121,6 +129,36 @@ checkWidgetStates(TEXT_SEARCH_ENGINE_FULL, View.VISIBLE); } + @SmallTest + @CommandLineFlags.Remove(ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE) + public void testUpdateCachedEngineNameBeforeFirstRun() { + assertFalse(SearchWidgetProvider.shouldShowFullString()); + SearchWidgetProvider.handleAction( + new Intent(SearchWidgetProvider.ACTION_UPDATE_ALL_WIDGETS)); + + // Without any idea of what the default search engine is, widgets should default to saying + // just "Search". + checkWidgetStates(TEXT_GENERIC, View.VISIBLE); + + // Until First Run is complete, no search engine branding should be displayed. Widgets are + // already displaying the generic string, and should continue doing so, so they don't get + // updated. + mDelegate.mViews.clear(); + SearchWidgetProvider.updateCachedEngineName(TEXT_SEARCH_ENGINE); + assertEquals(0, mDelegate.mViews.size()); + + // Manually set the preference, then update the cached engine name again. The + // SearchWidgetProvider should now believe that its widgets are displaying branding when it + // isn't allowed to, then update them. + mDelegate.mViews.clear(); + mDelegate.getSharedPreferences() + .edit() + .putString(SearchWidgetProvider.PREF_SEARCH_ENGINE_SHORTNAME, TEXT_SEARCH_ENGINE) + .apply(); + SearchWidgetProvider.updateCachedEngineName(TEXT_SEARCH_ENGINE); + checkWidgetStates(TEXT_GENERIC, View.VISIBLE); + } + private void checkWidgetStates(final String expectedString, final int expectedMicrophoneState) { // Confirm that all the widgets got updated. Assert.assertEquals(TestDelegate.ALL_IDS.length, mDelegate.mViews.size());
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 4c5a0616..7452083b 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
@@ -47,16 +47,7 @@ @Override protected void setUp() throws Exception { super.setUp(); - // We need to run the constructor on the main/UI thread, otherwise the Choreographer - // acquired in the constructor is incorrect during e2e tests - final AtomicReference<VrShellDelegate> delegate = new AtomicReference<VrShellDelegate>(); - ThreadUtils.runOnUiThreadBlocking(new Runnable() { - @Override - public void run() { - delegate.set(VrShellDelegate.getInstanceForTesting()); - } - }); - mDelegate = delegate.get(); + mDelegate = VrUtils.getVrShellDelegateInstance(); } @Override
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/VrUtils.java b/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/VrUtils.java index e16076e..d63fa85 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/VrUtils.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/VrUtils.java
@@ -22,6 +22,7 @@ import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.util.concurrent.Callable; +import java.util.concurrent.atomic.AtomicReference; /** * Class containing static functions and constants that are useful for VR @@ -48,6 +49,23 @@ private static final int RESERVED = 456; /** + * 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() {
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 b9311fd..7ef17e1 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
@@ -229,7 +229,6 @@ * Tests that a successful requestPresent call actually enters VR */ @SmallTest - @DisabledTest(message = "crbug.com/713781") public void testRequestPresentEntersVr() throws InterruptedException { String testName = "test_requestPresent_enters_vr"; loadUrl(getHtmlTestFile(testName), PAGE_LOAD_TIMEOUT_S); @@ -309,7 +308,6 @@ * Tests that non-focused tabs cannot get pose information. */ @SmallTest - @DisabledTest(message = "crbug.com/713781") public void testPoseDataUnfocusedTab() throws InterruptedException { String testName = "test_pose_data_unfocused_tab"; loadUrl(getHtmlTestFile(testName), PAGE_LOAD_TIMEOUT_S); @@ -331,7 +329,7 @@ private void infoBarTestHelper(int checkerReturnValue) throws InterruptedException { MockVrCoreVersionCheckerImpl mockChecker = new MockVrCoreVersionCheckerImpl(); mockChecker.setMockReturnValue(checkerReturnValue); - VrShellDelegate.getInstanceForTesting().overrideVrCoreVersionCheckerForTesting(mockChecker); + VrUtils.getVrShellDelegateInstance().overrideVrCoreVersionCheckerForTesting(mockChecker); String testName = "generic_webvr_page"; loadUrl(getHtmlTestFile(testName), PAGE_LOAD_TIMEOUT_S); String displayFound = "VRDisplay Found"; @@ -382,7 +380,6 @@ * VR Services is installed and up to date. */ @MediumTest - @DisabledTest(message = "crbug.com/713781") public void testInfoBarNotPresentWhenVrServicesCurrent() throws InterruptedException { infoBarTestHelper(VrCoreVersionChecker.VR_READY); } @@ -392,7 +389,6 @@ * VR Services is outdated. */ @MediumTest - @DisabledTest(message = "crbug.com/713781") public void testInfoBarPresentWhenVrServicesOutdated() throws InterruptedException { infoBarTestHelper(VrCoreVersionChecker.VR_OUT_OF_DATE); } @@ -402,7 +398,6 @@ * Services is missing. */ @MediumTest - @DisabledTest(message = "crbug.com/713781") public void testInfoBarPresentWhenVrServicesMissing() throws InterruptedException { infoBarTestHelper(VrCoreVersionChecker.VR_NOT_AVAILABLE); } @@ -412,7 +407,6 @@ * is not supported on the device. */ @MediumTest - @DisabledTest(message = "crbug.com/713781") public void testInfoBarNotPresentWhenVrServicesNotSupported() throws InterruptedException { infoBarTestHelper(VrCoreVersionChecker.VR_NOT_SUPPORTED); } @@ -422,7 +416,6 @@ * devices the WebVR tests are run on continuously. */ @MediumTest - @DisabledTest(message = "crbug.com/713781") public void testDeviceCapabilitiesMatchExpectations() throws InterruptedException { String testName = "test_device_capabilities_match_expectations"; loadUrl(getHtmlTestFile(testName), PAGE_LOAD_TIMEOUT_S);
diff --git a/chrome/android/sync_shell/javatests/src/org/chromium/chrome/browser/sync/FirstRunTest.java b/chrome/android/sync_shell/javatests/src/org/chromium/chrome/browser/sync/FirstRunTest.java index a6f9789..383be52 100644 --- a/chrome/android/sync_shell/javatests/src/org/chromium/chrome/browser/sync/FirstRunTest.java +++ b/chrome/android/sync_shell/javatests/src/org/chromium/chrome/browser/sync/FirstRunTest.java
@@ -14,12 +14,14 @@ import android.support.test.filters.SmallTest; import org.chromium.base.ThreadUtils; +import org.chromium.base.test.util.CallbackHelper; import org.chromium.base.test.util.CommandLineFlags; import org.chromium.base.test.util.Feature; import org.chromium.base.test.util.FlakyTest; import org.chromium.base.test.util.RetryOnFailure; import org.chromium.chrome.browser.ChromeSwitches; import org.chromium.chrome.browser.firstrun.FirstRunActivity; +import org.chromium.chrome.browser.firstrun.FirstRunActivity.FirstRunActivityObserver; import org.chromium.chrome.browser.firstrun.FirstRunFlowSequencer; import org.chromium.chrome.browser.firstrun.FirstRunSignInProcessor; import org.chromium.chrome.browser.preferences.Preferences; @@ -30,6 +32,8 @@ import org.chromium.content.browser.test.util.Criteria; import org.chromium.content.browser.test.util.CriteriaHelper; +import java.util.concurrent.TimeoutException; + /** * Tests for the first run experience. */ @@ -43,10 +47,34 @@ NO; } + private static final class TestObserver implements FirstRunActivityObserver { + public final CallbackHelper flowIsKnownCallback = new CallbackHelper(); + + @Override + public void onFlowIsKnown(Bundle freProperties) { + flowIsKnownCallback.notifyCalled(); + } + + @Override + public void onAcceptTermsOfService() {} + + @Override + public void onJumpToPage(int position) {} + + @Override + public void onUpdateCachedEngineName() {} + + @Override + public void onAbortFirstRunExperience() {} + } + + private final TestObserver mTestObserver = new TestObserver(); private FirstRunActivity mActivity; @Override public void startMainActivity() throws InterruptedException { + FirstRunActivity.setObserverForTest(mTestObserver); + // Starts up and waits for the FirstRunActivity to be ready. // This isn't exactly what startMainActivity is supposed to be doing, but short of a // refactoring of SyncTestBase to use something other than ChromeTabbedActivity, it's the @@ -78,17 +106,21 @@ assertTrue(activity instanceof FirstRunActivity); mActivity = (FirstRunActivity) activity; - CriteriaHelper.pollUiThread(new Criteria() { - @Override - public boolean isSatisfied() { - return mActivity.isPostNativePageSequenceCreated(); - } - }); + try { + mTestObserver.flowIsKnownCallback.waitForCallback(0); + } catch (TimeoutException e) { + fail(); + } getInstrumentation().waitForIdleSync(); } @Override + public void setUp() throws Exception { + super.setUp(); + } + + @Override public void tearDown() throws Exception { if (mActivity != null) mActivity.finish(); super.tearDown();
diff --git a/chrome/browser/android/bookmarks/bookmark_bridge.cc b/chrome/browser/android/bookmarks/bookmark_bridge.cc index c7485920..ac4fa92 100644 --- a/chrome/browser/android/bookmarks/bookmark_bridge.cc +++ b/chrome/browser/android/bookmarks/bookmark_bridge.cc
@@ -802,7 +802,7 @@ node->type() != BookmarkNode::URL)) { return false; } - if (!IsEditBookmarksEnabled()) + if (!IsEditBookmarksEnabled() || bookmark_model_->is_permanent_node(node)) return false; if (partner_bookmarks_shim_->IsPartnerBookmark(node)) return partner_bookmarks_shim_->IsEditable(node);
diff --git a/chrome/browser/android/offline_pages/prerendering_offliner_unittest.cc b/chrome/browser/android/offline_pages/prerendering_offliner_unittest.cc index 7e73c92..cc95fccc 100644 --- a/chrome/browser/android/offline_pages/prerendering_offliner_unittest.cc +++ b/chrome/browser/android/offline_pages/prerendering_offliner_unittest.cc
@@ -45,7 +45,8 @@ mock_loading_(false), mock_loaded_(false), mock_is_lowbar_met_(false), - start_snapshot_called_(false) {} + start_snapshot_called_(false), + web_contents_(nullptr) {} ~MockPrerenderingLoader() override { delete web_contents_; } bool LoadPage(const GURL& url,
diff --git a/chrome/browser/apps/guest_view/web_view_browsertest.cc b/chrome/browser/apps/guest_view/web_view_browsertest.cc index ac62700..bf978ee 100644 --- a/chrome/browser/apps/guest_view/web_view_browsertest.cc +++ b/chrome/browser/apps/guest_view/web_view_browsertest.cc
@@ -3144,6 +3144,10 @@ TestHelper("testFindAPI_findupdate", "web_view/shim", NO_TEST_SERVER); } +IN_PROC_BROWSER_TEST_P(WebViewTest, Shim_testFindInMultipleWebViews) { + TestHelper("testFindInMultipleWebViews", "web_view/shim", NO_TEST_SERVER); +} + IN_PROC_BROWSER_TEST_P(WebViewTest, Shim_TestLoadDataAPI) { TestHelper("testLoadDataAPI", "web_view/shim", NEEDS_TEST_SERVER); }
diff --git a/chrome/browser/chrome_find_request_manager_browsertest.cc b/chrome/browser/chrome_find_request_manager_browsertest.cc index 36a9791..0ced9a28 100644 --- a/chrome/browser/chrome_find_request_manager_browsertest.cc +++ b/chrome/browser/chrome_find_request_manager_browsertest.cc
@@ -9,6 +9,8 @@ #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/ui_test_utils.h" +#include "content/public/browser/browser_context.h" +#include "content/public/browser/browser_plugin_guest_manager.h" #include "content/public/common/content_switches.h" #include "content/public/test/browser_test_utils.h" #include "content/public/test/find_test_utils.h" @@ -83,7 +85,7 @@ // Tests searching in a full-page PDF. IN_PROC_BROWSER_TEST_F(ChromeFindRequestManagerTest, FindInPDF) { LoadAndWait("/find_in_pdf_page.pdf"); - pdf_extension_test_util::EnsurePDFHasLoaded(contents()); + ASSERT_TRUE(pdf_extension_test_util::EnsurePDFHasLoaded(contents())); blink::WebFindOptions options; Find("result", options); @@ -98,4 +100,31 @@ EXPECT_EQ(3, results.active_match_ordinal); } +// Tests searching in a page with embedded PDFs. Note that this test, the +// FindInPDF test, and the find tests in web_view_browsertest.cc ensure that +// find-in-page works across GuestViews. +// +// TODO(paulmeyer): Note that this is left disabled for now since +// EnsurePDFHasLoaded() currently does not work for embedded PDFs. This will be +// fixed and enabled in a subsequent patch. +IN_PROC_BROWSER_TEST_F(ChromeFindRequestManagerTest, + DISABLED_FindInEmbeddedPDFs) { + LoadAndWait("/find_in_embedded_pdf_page.html"); + ASSERT_TRUE(pdf_extension_test_util::EnsurePDFHasLoaded(contents())); + + blink::WebFindOptions options; + Find("result", options); + options.find_next = true; + options.forward = false; + Find("result", options); + Find("result", options); + Find("result", options); + delegate()->WaitForFinalReply(); + + FindResults results = delegate()->GetFindResults(); + EXPECT_EQ(last_request_id(), results.request_id); + EXPECT_EQ(13, results.number_of_matches); + EXPECT_EQ(11, results.active_match_ordinal); +} + } // namespace content
diff --git a/chrome/browser/chromeos/net/tether_notification_presenter_unittest.cc b/chrome/browser/chromeos/net/tether_notification_presenter_unittest.cc index eb1cf51..9959cb2f 100644 --- a/chrome/browser/chromeos/net/tether_notification_presenter_unittest.cc +++ b/chrome/browser/chromeos/net/tether_notification_presenter_unittest.cc
@@ -125,8 +125,6 @@ bool shared) override {} void CreateConfigurationAndConnect(base::DictionaryValue* shill_properties, bool shared) override {} - void SetTetherDelegate(TetherDelegate* tether_delegate) override {} - void CreateConfiguration(base::DictionaryValue* shill_properties, bool shared) override {}
diff --git a/chrome/browser/chromeos/tether/tether_service.cc b/chrome/browser/chromeos/tether/tether_service.cc index f201966..2707391 100644 --- a/chrome/browser/chromeos/tether/tether_service.cc +++ b/chrome/browser/chromeos/tether/tether_service.cc
@@ -59,7 +59,8 @@ ProfileOAuth2TokenServiceFactory::GetForProfile(profile_), chromeos::NetworkHandler::Get()->network_state_handler(), chromeos::NetworkHandler::Get()->managed_network_configuration_handler(), - chromeos::NetworkConnect::Get()); + chromeos::NetworkConnect::Get(), + chromeos::NetworkHandler::Get()->network_connection_handler()); } bool TetherService::IsAllowed() const {
diff --git a/chrome/browser/component_updater/sw_reporter_installer_win.cc b/chrome/browser/component_updater/sw_reporter_installer_win.cc index ea42ade..385bf12 100644 --- a/chrome/browser/component_updater/sw_reporter_installer_win.cc +++ b/chrome/browser/component_updater/sw_reporter_installer_win.cc
@@ -498,4 +498,13 @@ registry->RegisterStringPref(prefs::kSwReporterPromptSeed, ""); } +void RegisterUserInitiatedSwReporterScan(base::Closure callback) { + // Fetch the latest version of the Cleanup component and run it, + // bypassing the usual scheduling logic. Once the scan is done, report + // whether the scan was successful and the names of the Unwanted Software that + // can be removed by the Cleanup tool. + // TODO(proberge): Implement me. + callback.Run(); +} + } // namespace component_updater
diff --git a/chrome/browser/component_updater/sw_reporter_installer_win.h b/chrome/browser/component_updater/sw_reporter_installer_win.h index aab0298..79064eb 100644 --- a/chrome/browser/component_updater/sw_reporter_installer_win.h +++ b/chrome/browser/component_updater/sw_reporter_installer_win.h
@@ -31,6 +31,8 @@ class ComponentUpdateService; +constexpr char kSwReporterComponentId[] = "gkmgaooipdjhmangpemjhigmamcehddo"; + // These MUST match the values for SwReporterExperimentError in histograms.xml. // Exposed for testing. enum SwReporterExperimentError { @@ -91,6 +93,10 @@ void RegisterProfilePrefsForSwReporter( user_prefs::PrefRegistrySyncable* registry); +// Called by chrome://cleanup/ to manually trigger a reporter run. +// TODO(proberge): Replace the Closure with a typed callback. +void RegisterUserInitiatedSwReporterScan(base::Closure callback); + } // namespace component_updater #endif // CHROME_BROWSER_COMPONENT_UPDATER_SW_REPORTER_INSTALLER_WIN_H_
diff --git a/chrome/browser/extensions/api/certificate_provider/certificate_provider_apitest.cc b/chrome/browser/extensions/api/certificate_provider/certificate_provider_apitest.cc index 866e14da..ea3cebef 100644 --- a/chrome/browser/extensions/api/certificate_provider/certificate_provider_apitest.cc +++ b/chrome/browser/extensions/api/certificate_provider/certificate_provider_apitest.cc
@@ -72,15 +72,8 @@ void StoreDigest(std::vector<uint8_t>* digest, const base::Closure& callback, const base::Value* value) { - const base::Value* binary = nullptr; - const bool is_binary = value->GetAsBinary(&binary); - EXPECT_TRUE(is_binary) << "Unexpected value in StoreDigest"; - if (is_binary) { - const uint8_t* const binary_begin = - reinterpret_cast<const uint8_t*>(binary->GetBuffer()); - digest->assign(binary_begin, binary_begin + binary->GetSize()); - } - + ASSERT_TRUE(value->is_blob()) << "Unexpected value in StoreDigest"; + digest->assign(value->GetBlob().begin(), value->GetBlob().end()); callback.Run(); }
diff --git a/chrome/browser/extensions/api/easy_unlock_private/easy_unlock_private_api_chromeos_unittest.cc b/chrome/browser/extensions/api/easy_unlock_private/easy_unlock_private_api_chromeos_unittest.cc index 232618e..b4b40a72 100644 --- a/chrome/browser/extensions/api/easy_unlock_private/easy_unlock_private_api_chromeos_unittest.cc +++ b/chrome/browser/extensions/api/easy_unlock_private/easy_unlock_private_api_chromeos_unittest.cc
@@ -169,8 +169,8 @@ return ""; } - return std::string(result_binary_value->GetBuffer(), - result_binary_value->GetSize()); + return std::string(result_binary_value->GetBlob().data(), + result_binary_value->GetBlob().size()); } chromeos::EasyUnlockClient* client_; @@ -200,8 +200,8 @@ ASSERT_TRUE(private_key); EXPECT_TRUE(chromeos::FakeEasyUnlockClient::IsEcP256KeyPair( - std::string(private_key->GetBuffer(), private_key->GetSize()), - std::string(public_key->GetBuffer(), public_key->GetSize()))); + std::string(private_key->GetBlob().data(), private_key->GetBlob().size()), + std::string(public_key->GetBlob().data(), public_key->GetBlob().size()))); } TEST_F(EasyUnlockPrivateApiTest, PerformECDHKeyAgreement) {
diff --git a/chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_api_unittest.cc b/chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_api_unittest.cc index 29bda41..8bb9198 100644 --- a/chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_api_unittest.cc +++ b/chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_api_unittest.cc
@@ -390,10 +390,9 @@ std::unique_ptr<base::Value> value( RunFunctionAndReturnSingleResult(func_.get(), CreateArgs(), browser())); - const base::Value* response; - ASSERT_TRUE(value->GetAsBinary(&response)); + ASSERT_TRUE(value->is_blob()); EXPECT_EQ("response", - std::string(response->GetBuffer(), response->GetSize())); + std::string(value->GetBlob().data(), value->GetBlob().size())); } TEST_F(EPKChallengeMachineKeyTest, KeyRegisteredSuccess) { @@ -420,10 +419,9 @@ std::unique_ptr<base::Value> value(RunFunctionAndReturnSingleResult( func_.get(), CreateArgsRegister(), browser())); - const base::Value* response; - ASSERT_TRUE(value->GetAsBinary(&response)); + ASSERT_TRUE(value->is_blob()); EXPECT_EQ("response", - std::string(response->GetBuffer(), response->GetSize())); + std::string(value->GetBlob().data(), value->GetBlob().size())); } TEST_F(EPKChallengeMachineKeyTest, AttestationNotPrepared) { @@ -595,10 +593,9 @@ std::unique_ptr<base::Value> value( RunFunctionAndReturnSingleResult(func_.get(), CreateArgs(), browser())); - const base::Value* response; - ASSERT_TRUE(value->GetAsBinary(&response)); + ASSERT_TRUE(value->is_blob()); EXPECT_EQ("response", - std::string(response->GetBuffer(), response->GetSize())); + std::string(value->GetBlob().data(), value->GetBlob().size())); } TEST_F(EPKChallengeUserKeyTest, AttestationNotPrepared) {
diff --git a/chrome/browser/extensions/api/idltest/idltest_api.cc b/chrome/browser/extensions/api/idltest/idltest_api.cc index da7ba52e..e6b65fb 100644 --- a/chrome/browser/extensions/api/idltest/idltest_api.cc +++ b/chrome/browser/extensions/api/idltest/idltest_api.cc
@@ -17,9 +17,8 @@ std::unique_ptr<base::ListValue> CopyBinaryValueToIntegerList( const Value* input) { std::unique_ptr<base::ListValue> output(new base::ListValue()); - const char* input_buffer = input->GetBuffer(); - for (size_t i = 0; i < input->GetSize(); i++) { - output->AppendInteger(input_buffer[i]); + for (char c : input->GetBlob()) { + output->AppendInteger(c); } return output; }
diff --git a/chrome/browser/extensions/extension_action.cc b/chrome/browser/extensions/extension_action.cc index 00345b4..031f956 100644 --- a/chrome/browser/extensions/extension_action.cc +++ b/chrome/browser/extensions/extension_action.cc
@@ -126,11 +126,11 @@ gfx::ImageSkia* icon) { for (base::DictionaryValue::Iterator iter(dict); !iter.IsAtEnd(); iter.Advance()) { - const base::Value* image_data; std::string binary_string64; IPC::Message pickle; - if (iter.value().GetAsBinary(&image_data)) { - pickle = IPC::Message(image_data->GetBuffer(), image_data->GetSize()); + if (iter.value().is_blob()) { + pickle = IPC::Message(iter.value().GetBlob().data(), + iter.value().GetBlob().size()); } else if (iter.value().GetAsString(&binary_string64)) { std::string binary_string; if (!base::Base64Decode(binary_string64, &binary_string))
diff --git a/chrome/browser/policy/configuration_policy_handler_list_factory.cc b/chrome/browser/policy/configuration_policy_handler_list_factory.cc index ed27626..03bc6a89 100644 --- a/chrome/browser/policy/configuration_policy_handler_list_factory.cc +++ b/chrome/browser/policy/configuration_policy_handler_list_factory.cc
@@ -549,6 +549,9 @@ { key::kEasyUnlockAllowed, prefs::kEasyUnlockAllowed, base::Value::Type::BOOLEAN }, + { key::kInstantTetheringAllowed, + prefs::kInstantTetheringAllowed, + base::Value::Type::BOOLEAN }, { key::kCaptivePortalAuthenticationIgnoresProxy, prefs::kCaptivePortalAuthenticationIgnoresProxy, base::Value::Type::BOOLEAN },
diff --git a/chrome/browser/resources/cleanup_tool/cleanup_browser_proxy.js b/chrome/browser/resources/cleanup_tool/cleanup_browser_proxy.js index 1e0e859..d62dbe2f 100644 --- a/chrome/browser/resources/cleanup_tool/cleanup_browser_proxy.js +++ b/chrome/browser/resources/cleanup_tool/cleanup_browser_proxy.js
@@ -27,6 +27,11 @@ * @return {!Promise<LastScanResult>} */ requestLastScanResult: function() {}, + /** + * Attempts to run the Chrome Cleanup Tool in scanning mode. + * @return {!Promise<LastScanResult>} + */ + startScan: function() {}, }; /** @@ -41,6 +46,10 @@ requestLastScanResult: function() { return cr.sendWithPromise('requestLastScanResult'); }, + /** @override */ + startScan: function() { + return cr.sendWithPromise('startScan'); + }, }; return {
diff --git a/chrome/browser/resources/cleanup_tool/manager.js b/chrome/browser/resources/cleanup_tool/manager.js index 81ad588..d9bfa9a8 100644 --- a/chrome/browser/resources/cleanup_tool/manager.js +++ b/chrome/browser/resources/cleanup_tool/manager.js
@@ -51,7 +51,16 @@ * @private */ onScanTap_: function() { - // TODO implement me. + this.isRunningScanner = true; + this.browserProxy_.startScan().then(this.onScanComplete_.bind(this)); + }, + + /** + * @param {LastScanResult} lastScanResults + */ + onScanComplete_: function(lastScanResults) { + this.isRunningScanner = false; + this.updateLastScanState_(lastScanResults); }, /**
diff --git a/chrome/browser/ui/ash/app_list/app_list_presenter_delegate_mus.cc b/chrome/browser/ui/ash/app_list/app_list_presenter_delegate_mus.cc index 1ca9e18..d82621b 100644 --- a/chrome/browser/ui/ash/app_list/app_list_presenter_delegate_mus.cc +++ b/chrome/browser/ui/ash/app_list/app_list_presenter_delegate_mus.cc
@@ -64,8 +64,9 @@ // the only thing this is used for is choosing the right scale factor in // AppListMainView::PreloadIcons(), so we take care of that - perhaps by // passing the display_id or the scale factor directly - view->InitAsBubble(nullptr /* parent */, current_apps_page); - view->SetAnchorPoint( + view->Initialize(nullptr /* parent */, current_apps_page); + + view->MaybeSetAnchorPoint( GetCenterOfDisplay(display_id, GetMinimumBoundsHeightForAppList(view))); // TODO(mfomitchev): Setup updating bounds on keyboard bounds change.
diff --git a/chrome/browser/ui/views/passwords/credentials_item_view.cc b/chrome/browser/ui/views/passwords/credentials_item_view.cc index 5aafc94..3eff92e 100644 --- a/chrome/browser/ui/views/passwords/credentials_item_view.cc +++ b/chrome/browser/ui/views/passwords/credentials_item_view.cc
@@ -150,7 +150,7 @@ const gfx::Insets insets(GetInsets()); size.Enlarge(insets.width(), insets.height()); size.Enlarge(ChromeLayoutProvider::Get()->GetDistanceMetric( - DISTANCE_UNRELATED_CONTROL_HORIZONTAL), + DISTANCE_RELATED_LABEL_HORIZONTAL), 0); // Make the size at least as large as the minimum size needed by the border. @@ -180,7 +180,7 @@ (upper_size.height() + lower_size.height())) / 2; gfx::Point label_origin(image_origin.x() + image_size.width() + ChromeLayoutProvider::Get()->GetDistanceMetric( - DISTANCE_UNRELATED_CONTROL_HORIZONTAL), + DISTANCE_RELATED_LABEL_HORIZONTAL), child_area.origin().y() + y_offset); if (upper_label_) upper_label_->SetBoundsRect(gfx::Rect(label_origin, upper_size));
diff --git a/chrome/browser/ui/views/passwords/manage_passwords_bubble_view.cc b/chrome/browser/ui/views/passwords/manage_passwords_bubble_view.cc index 03b1af0f..35a9376 100644 --- a/chrome/browser/ui/views/passwords/manage_passwords_bubble_view.cc +++ b/chrome/browser/ui/views/passwords/manage_passwords_bubble_view.cc
@@ -230,20 +230,17 @@ SetLayoutManager(new views::FillLayout); const autofill::PasswordForm& form = parent_->model()->pending_password(); CredentialsItemView* credential; + base::string16 upper_text, lower_text = form.username_value; if (ChromeLayoutProvider::Get()->IsHarmonyMode()) { - credential = new CredentialsItemView( - this, - l10n_util::GetStringUTF16(IDS_MANAGE_PASSWORDS_AUTO_SIGNIN_TITLE_MD), - form.username_value, kButtonHoverColor, &form, - parent_->model()->GetProfile()->GetRequestContext()); + upper_text = + l10n_util::GetStringUTF16(IDS_MANAGE_PASSWORDS_AUTO_SIGNIN_TITLE_MD); } else { - credential = new CredentialsItemView( - this, base::string16(), - l10n_util::GetStringFUTF16(IDS_MANAGE_PASSWORDS_AUTO_SIGNIN_TITLE, - form.username_value), - kButtonHoverColor, &form, - parent_->model()->GetProfile()->GetRequestContext()); + lower_text = l10n_util::GetStringFUTF16( + IDS_MANAGE_PASSWORDS_AUTO_SIGNIN_TITLE, lower_text); } + credential = new CredentialsItemView( + this, upper_text, lower_text, kButtonHoverColor, &form, + parent_->model()->GetProfile()->GetRequestContext()); credential->SetEnabled(false); AddChildView(credential);
diff --git a/chrome/browser/ui/views/passwords/password_dialog_view_browsertest.cc b/chrome/browser/ui/views/passwords/password_dialog_view_browsertest.cc index 3ceb8f9..fc6b2e90 100644 --- a/chrome/browser/ui/views/passwords/password_dialog_view_browsertest.cc +++ b/chrome/browser/ui/views/passwords/password_dialog_view_browsertest.cc
@@ -478,8 +478,7 @@ if (name == "PopupAutoSigninPrompt") { form.icon_url = GURL("broken url"); local_credentials.push_back(base::MakeUnique<autofill::PasswordForm>(form)); - GURL icon_url("https://google.com/icon.png"); - form.icon_url = icon_url; + form.icon_url = GURL("https://google.com/icon.png"); form.display_name = base::ASCIIToUTF16("Peter Pan"); form.federation_origin = url::Origin(GURL("https://google.com/federation")); local_credentials.push_back(base::MakeUnique<autofill::PasswordForm>(form));
diff --git a/chrome/browser/ui/views/payments/payment_request_sheet_controller.cc b/chrome/browser/ui/views/payments/payment_request_sheet_controller.cc index 89415610..c77fc39 100644 --- a/chrome/browser/ui/views/payments/payment_request_sheet_controller.cc +++ b/chrome/browser/ui/views/payments/payment_request_sheet_controller.cc
@@ -41,6 +41,9 @@ FillContentView(content_view_); content_view_->Layout(); pane_->SizeToPreferredSize(); + // Now that the content and its surrounding pane are updated, force a Layout + // on the ScrollView so that it updates its scroll bars now. + scroll_->Layout(); } std::unique_ptr<views::Button> @@ -117,12 +120,12 @@ pane_layout->AddView(content_view_); pane_->SizeToPreferredSize(); - std::unique_ptr<views::ScrollView> scroll = - base::MakeUnique<views::ScrollView>(); - scroll->EnableViewPortLayer(); - scroll->set_hide_horizontal_scrollbar(true); - scroll->SetContents(pane_); - layout->AddView(scroll.release()); + scroll_ = base::MakeUnique<views::ScrollView>(); + scroll_->set_owned_by_client(); + scroll_->EnableViewPortLayer(); + scroll_->set_hide_horizontal_scrollbar(true); + scroll_->SetContents(pane_); + layout->AddView(scroll_.get()); layout->StartRow(0, 0); layout->AddView(CreateFooterView().release());
diff --git a/chrome/browser/ui/views/payments/payment_request_sheet_controller.h b/chrome/browser/ui/views/payments/payment_request_sheet_controller.h index 666a059..5aa37b5 100644 --- a/chrome/browser/ui/views/payments/payment_request_sheet_controller.h +++ b/chrome/browser/ui/views/payments/payment_request_sheet_controller.h
@@ -119,6 +119,10 @@ views::View* pane_; views::View* content_view_; + // Hold on to the ScrollView because it must be explicitly laid out in some + // cases. + std::unique_ptr<views::ScrollView> scroll_; + DISALLOW_COPY_AND_ASSIGN(PaymentRequestSheetController); };
diff --git a/chrome/browser/ui/views/payments/shipping_address_editor_view_controller_browsertest.cc b/chrome/browser/ui/views/payments/shipping_address_editor_view_controller_browsertest.cc index 704c45e..9d2f969 100644 --- a/chrome/browser/ui/views/payments/shipping_address_editor_view_controller_browsertest.cc +++ b/chrome/browser/ui/views/payments/shipping_address_editor_view_controller_browsertest.cc
@@ -177,7 +177,7 @@ profile->GetRawInfo(autofill::ADDRESS_HOME_COUNTRY)); EXPECT_EQ(base::ASCIIToUTF16(kAnyState), profile->GetRawInfo(autofill::ADDRESS_HOME_STATE)); - ExpectExistingRequiredFields(nullptr); + ExpectExistingRequiredFields(/*unset_types=*/nullptr); } IN_PROC_BROWSER_TEST_F(PaymentRequestShippingAddressEditorTest, AsyncData) { @@ -216,7 +216,7 @@ profile->GetRawInfo(autofill::ADDRESS_HOME_COUNTRY)); EXPECT_EQ(base::ASCIIToUTF16(kAnyState), profile->GetRawInfo(autofill::ADDRESS_HOME_STATE)); - ExpectExistingRequiredFields(nullptr); + ExpectExistingRequiredFields(/*unset_types=*/nullptr); // One shipping profile is available and selected. PaymentRequest* request = GetPaymentRequests(GetActiveWebContents()).front(); @@ -357,7 +357,7 @@ EXPECT_EQ(base::ASCIIToUTF16(kAnyState), profile->GetRawInfo(autofill::ADDRESS_HOME_STATE)); - ExpectExistingRequiredFields(nullptr); + ExpectExistingRequiredFields(/*unset_types=*/nullptr); } IN_PROC_BROWSER_TEST_F(PaymentRequestShippingAddressEditorTest, @@ -397,7 +397,57 @@ EXPECT_EQ(base::ASCIIToUTF16(kAnyState), profile->GetRawInfo(autofill::ADDRESS_HOME_STATE)); - ExpectExistingRequiredFields(nullptr); + ExpectExistingRequiredFields(/*unset_types=*/nullptr); +} + +IN_PROC_BROWSER_TEST_F(PaymentRequestShippingAddressEditorTest, + SelectingIncompleteAddress) { + // Add incomplete address. + autofill::AutofillProfile profile; + profile.SetInfo(autofill::AutofillType(autofill::NAME_FULL), + base::ASCIIToUTF16(kNameFull), "fr_CA"); + PaymentRequestBrowserTestBase::AddAutofillProfile(profile); + + InvokePaymentRequestUI(); + + // One shipping address is available, but it's not selected. + PaymentRequest* request = GetPaymentRequests(GetActiveWebContents()).front(); + EXPECT_EQ(1U, request->state()->shipping_profiles().size()); + EXPECT_EQ(nullptr, request->state()->selected_shipping_profile()); + + OpenShippingAddressSectionScreen(); + + ResetEventObserver(DialogEvent::SHIPPING_ADDRESS_EDITOR_OPENED); + ClickOnChildInListViewAndWait(/*child_index=*/0, /*num_children=*/1, + DialogViewID::SHIPPING_ADDRESS_SHEET_LIST_VIEW); + + EXPECT_EQ(base::ASCIIToUTF16(kNameFull), + GetEditorTextfieldValue(autofill::NAME_FULL)); + EXPECT_EQ(base::ASCIIToUTF16(""), + GetEditorTextfieldValue(autofill::ADDRESS_HOME_ZIP)); + + // Set all required fields. + SetCommonFields(); + + // Verifying the data is in the DB. + autofill::PersonalDataManager* personal_data_manager = GetDataManager(); + personal_data_manager->AddObserver(&personal_data_observer_); + + ResetEventObserver(DialogEvent::BACK_TO_PAYMENT_SHEET_NAVIGATION); + + // Wait until the web database has been updated and the notification sent. + base::RunLoop data_loop; + EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged()) + .WillOnce(QuitMessageLoop(&data_loop)); + ClickOnDialogViewAndWait(DialogViewID::EDITOR_SAVE_BUTTON); + data_loop.Run(); + + ExpectExistingRequiredFields(/*unset_types=*/nullptr); + + // Still have one shipping address, but now it's selected. + EXPECT_EQ(1U, request->state()->shipping_profiles().size()); + EXPECT_EQ(request->state()->shipping_profiles().back(), + request->state()->selected_shipping_profile()); } } // namespace payments
diff --git a/chrome/browser/ui/webui/cleanup_tool/cleanup_action_handler.cc b/chrome/browser/ui/webui/cleanup_tool/cleanup_action_handler.cc index 1a84b1a..e6bd13e7 100644 --- a/chrome/browser/ui/webui/cleanup_tool/cleanup_action_handler.cc +++ b/chrome/browser/ui/webui/cleanup_tool/cleanup_action_handler.cc
@@ -5,9 +5,34 @@ #include "chrome/browser/ui/webui/cleanup_tool/cleanup_action_handler.h" #include "base/bind.h" +#include "base/timer/timer.h" #include "base/values.h" +#include "chrome/browser/browser_process.h" +#include "chrome/browser/component_updater/sw_reporter_installer_win.h" -CleanupActionHandler::CleanupActionHandler() {} +namespace { + +bool IsCleanupComponentRegistered() { + component_updater::ComponentUpdateService* cus = + g_browser_process->component_updater(); + std::vector<std::string> component_ids = cus->GetComponentIDs(); + + return std::find(component_ids.begin(), component_ids.end(), + component_updater::kSwReporterComponentId) != + component_ids.end(); +} + +// TODO(proberge): Localize strings once they are finalized. +constexpr char kDetectionOkText[] = "No problems detected"; +constexpr char kDetectionUwSText[] = "2 potentially harmful programs detected"; +constexpr char kDetectionTimeText[] = "Last scanned today"; +constexpr char kCleanupUnsupportedText[] = "Chrome Cleanup is not supported."; +constexpr char kUnsupportedHelpText[] = "Please try reinstalling Chrome"; + +} // namespace + +CleanupActionHandler::CleanupActionHandler() + : callback_weak_ptr_factory_(this) {} CleanupActionHandler::~CleanupActionHandler() {} @@ -16,6 +41,13 @@ "requestLastScanResult", base::Bind(&CleanupActionHandler::HandleRequestLastScanResult, base::Unretained(this))); + web_ui()->RegisterMessageCallback( + "startScan", base::Bind(&CleanupActionHandler::HandleStartScan, + base::Unretained(this))); +} + +void CleanupActionHandler::OnJavascriptDisallowed() { + callback_weak_ptr_factory_.InvalidateWeakPtrs(); } void CleanupActionHandler::HandleRequestLastScanResult( @@ -27,12 +59,46 @@ base::DictionaryValue last_scan_results; // TODO(proberge): Return real information about the last run. - // TODO(proberge): Localize strings once they are finalized. last_scan_results.SetBoolean("hasScanResults", false); last_scan_results.SetBoolean("isInfected", false); - last_scan_results.SetString("detectionStatusText", "No problems detected"); - last_scan_results.SetString("detectionTimeText", "Last scanned today"); + last_scan_results.SetString("detectionStatusText", kDetectionOkText); + last_scan_results.SetString("detectionTimeText", kDetectionTimeText); AllowJavascript(); ResolveJavascriptCallback(base::Value(webui_callback_id), last_scan_results); } + +void CleanupActionHandler::HandleStartScan(const base::ListValue* args) { + std::string webui_callback_id; + CHECK_EQ(1U, args->GetSize()); + bool success = args->GetString(0, &webui_callback_id); + DCHECK(success); + + if (!IsCleanupComponentRegistered()) { + base::DictionaryValue scan_results; + scan_results.SetBoolean("hasScanResults", false); + scan_results.SetBoolean("isInfected", false); + scan_results.SetString("detectionStatusText", kCleanupUnsupportedText); + scan_results.SetString("detectionTimeText", kUnsupportedHelpText); + + AllowJavascript(); + ResolveJavascriptCallback(base::Value(webui_callback_id), scan_results); + return; + } + + component_updater::RegisterUserInitiatedSwReporterScan( + base::Bind(&CleanupActionHandler::ReportScanResults, + callback_weak_ptr_factory_.GetWeakPtr(), webui_callback_id)); +} + +void CleanupActionHandler::ReportScanResults(const std::string& callback_id) { + base::DictionaryValue scan_results; + // TODO(proberge): Return real information about the scan. + scan_results.SetBoolean("hasScanResults", true); + scan_results.SetBoolean("isInfected", true); + scan_results.SetString("detectionStatusText", kDetectionUwSText); + scan_results.SetString("detectionTimeText", kDetectionTimeText); + + AllowJavascript(); + ResolveJavascriptCallback(base::Value(callback_id), scan_results); +}
diff --git a/chrome/browser/ui/webui/cleanup_tool/cleanup_action_handler.h b/chrome/browser/ui/webui/cleanup_tool/cleanup_action_handler.h index 87ee24a..894fc45 100644 --- a/chrome/browser/ui/webui/cleanup_tool/cleanup_action_handler.h +++ b/chrome/browser/ui/webui/cleanup_tool/cleanup_action_handler.h
@@ -7,6 +7,8 @@ #include "base/callback.h" #include "base/macros.h" +#include "base/memory/weak_ptr.h" +#include "components/component_updater/component_updater_service.h" #include "content/public/browser/web_ui_message_handler.h" // The handler for Javascript messages related to the "Chrome Cleanup" view. @@ -19,7 +21,18 @@ void RegisterMessages() override; private: + // Invalidates the weak pointers in callbacks that are no longer safe to run. + void OnJavascriptDisallowed() override; + void HandleRequestLastScanResult(const base::ListValue* args); + void HandleStartScan(const base::ListValue* args); + + // Returns the scan result initiated by HandleStartScan() to the Javascript + // caller refererenced by |callback_id|. + void ReportScanResults(const std::string& callback_id); + + // Used to cancel callbacks when JavaScript becomes disallowed. + base::WeakPtrFactory<CleanupActionHandler> callback_weak_ptr_factory_; DISALLOW_COPY_AND_ASSIGN(CleanupActionHandler); };
diff --git a/chrome/browser/win/jumplist.cc b/chrome/browser/win/jumplist.cc index 1c3059a2..54d4fb98 100644 --- a/chrome/browser/win/jumplist.cc +++ b/chrome/browser/win/jumplist.cc
@@ -207,19 +207,30 @@ if (begin_update_timer.Elapsed() >= kTimeOutForJumplistUpdate) return; - // We allocate 60% of the given JumpList slots to "most-visited" items - // and 40% to "recently-closed" items, respectively. - // Nevertheless, if there are not so many items in |recently_closed_pages|, - // we give the remaining slots to "most-visited" items. // The default maximum number of items to display in JumpList is 10. - // https://msdn.microsoft.com/en-us/library/windows/desktop/dd378398(v=vs.85).aspx - const int kMostVisited = 60; - const int kRecentlyClosed = 40; + // https://msdn.microsoft.com/library/windows/desktop/dd378398.aspx + // The "Most visited" category title always takes 1 of the JumpList slots if + // |most_visited_pages| isn't empty. + // The "Recently closed" category title will also take 1 if + // |recently_closed_pages| isn't empty. + // For the remaining slots, we allocate 5/8 (i.e., 5 slots if both categories + // present) to "most-visited" items and 3/8 (i.e., 3 slots if both categories + // present) to "recently-closed" items, respectively. + + const int kMostVisited = 50; + const int kRecentlyClosed = 30; const int kTotal = kMostVisited + kRecentlyClosed; + + // Adjust the available jumplist slots to account for the category titles. + size_t user_max_items_adjusted = jumplist_updater.user_max_items(); + if (!most_visited_pages.empty()) + --user_max_items_adjusted; + if (!recently_closed_pages.empty()) + --user_max_items_adjusted; + size_t most_visited_items = - MulDiv(jumplist_updater.user_max_items(), kMostVisited, kTotal); - size_t recently_closed_items = - jumplist_updater.user_max_items() - most_visited_items; + MulDiv(user_max_items_adjusted, kMostVisited, kTotal); + size_t recently_closed_items = user_max_items_adjusted - most_visited_items; if (recently_closed_pages.size() < recently_closed_items) { most_visited_items += recently_closed_items - recently_closed_pages.size(); recently_closed_items = recently_closed_pages.size(); @@ -441,7 +452,7 @@ // An empty string. This value is to be updated in OnFaviconDataAvailable(). // This code is copied from // RecentlyClosedTabsHandler::TabRestoreServiceChanged() to emulate it. - const int kRecentlyClosedCount = 4; + const int kRecentlyClosedCount = 3; sessions::TabRestoreService* tab_restore_service = TabRestoreServiceFactory::GetForProfile(profile_); for (const auto& entry : tab_restore_service->entries()) {
diff --git a/chrome/installer/gcapi_mac/BUILD.gn b/chrome/installer/gcapi_mac/BUILD.gn new file mode 100644 index 0000000..dd1103b --- /dev/null +++ b/chrome/installer/gcapi_mac/BUILD.gn
@@ -0,0 +1,48 @@ +# 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/sysroot.gni") + +assert(is_mac) + +config("gcapi_config") { + cflags = [ + "-isysroot", + sysroot, + "-mmacosx-version-min=10.5", + ] + ldflags = [ + "-isysroot", + sysroot, + "-mmacosx-version-min=10.5", + ] +} + +static_library("gcapi_lib") { + complete_static_lib = true + sources = [ + "gcapi.h", + "gcapi.mm", + ] + + libs = [ "Cocoa.framework" ] + + # Don't use runtime_library, to be able to pick a custom mmacosx-version-min. + configs -= [ "//build/config/compiler:runtime_library" ] + configs += [ ":gcapi_config" ] +} + +executable("gcapi_example") { + sources = [ + "gcapi_example_client.mm", + ] + + deps = [ + ":gcapi_lib", + ] + + # Don't use runtime_library, to be able to pick a custom mmacosx-version-min. + configs -= [ "//build/config/compiler:runtime_library" ] + configs += [ ":gcapi_config" ] +}
diff --git a/chrome/test/data/extensions/platform_apps/web_view/shim/main.js b/chrome/test/data/extensions/platform_apps/web_view/shim/main.js index 6aceb59..7a1cd01f 100644 --- a/chrome/test/data/extensions/platform_apps/web_view/shim/main.js +++ b/chrome/test/data/extensions/platform_apps/web_view/shim/main.js
@@ -2578,19 +2578,22 @@ document.body.appendChild(webview); }; +var testFindPage = + 'data:text/html,Dog dog dog Dog dog dogcatDog dogDogdog.<br>' + + 'Dog dog dog Dog dog dogcatDog dogDogdog.<br>' + + 'Dog dog dog Dog dog dogcatDog dogDogdog.<br>' + + 'Dog dog dog Dog dog dogcatDog dogDogdog.<br>' + + 'Dog dog dog Dog dog dogcatDog dogDogdog.<br>' + + 'Dog dog dog Dog dog dogcatDog dogDogdog.<br>' + + 'Dog dog dog Dog dog dogcatDog dogDogdog.<br>' + + 'Dog dog dog Dog dog dogcatDog dogDogdog.<br>' + + 'Dog dog dog Dog dog dogcatDog dogDogdog.<br>' + + 'Dog dog dog Dog dog dogcatDog dogDogdog.<br><br>' + + '<a href="about:blank">Click here!</a>'; + function testFindAPI() { var webview = new WebView(); - webview.src = 'data:text/html,Dog dog dog Dog dog dogcatDog dogDogdog.<br>' + - 'Dog dog dog Dog dog dogcatDog dogDogdog.<br>' + - 'Dog dog dog Dog dog dogcatDog dogDogdog.<br>' + - 'Dog dog dog Dog dog dogcatDog dogDogdog.<br>' + - 'Dog dog dog Dog dog dogcatDog dogDogdog.<br>' + - 'Dog dog dog Dog dog dogcatDog dogDogdog.<br>' + - 'Dog dog dog Dog dog dogcatDog dogDogdog.<br>' + - 'Dog dog dog Dog dog dogcatDog dogDogdog.<br>' + - 'Dog dog dog Dog dog dogcatDog dogDogdog.<br>' + - 'Dog dog dog Dog dog dogcatDog dogDogdog.<br><br>' + - '<a href="about:blank">Click here!</a>'; + webview.src = testFindPage; var loadstopListener2 = function(e) { embedder.test.assertEq(webview.src, "about:blank"); @@ -2664,17 +2667,8 @@ function testFindAPI_findupdate() { var webview = new WebView(); - webview.src = 'data:text/html,Dog dog dog Dog dog dogcatDog dogDogdog.<br>' + - 'Dog dog dog Dog dog dogcatDog dogDogdog.<br>' + - 'Dog dog dog Dog dog dogcatDog dogDogdog.<br>' + - 'Dog dog dog Dog dog dogcatDog dogDogdog.<br>' + - 'Dog dog dog Dog dog dogcatDog dogDogdog.<br>' + - 'Dog dog dog Dog dog dogcatDog dogDogdog.<br>' + - 'Dog dog dog Dog dog dogcatDog dogDogdog.<br>' + - 'Dog dog dog Dog dog dogcatDog dogDogdog.<br>' + - 'Dog dog dog Dog dog dogcatDog dogDogdog.<br>' + - 'Dog dog dog Dog dog dogcatDog dogDogdog.<br><br>' + - '<a href="about:blank">Click here!</a>'; + webview.src = testFindPage; + var canceledTest = false; webview.addEventListener('loadstop', function(e) { // Test the |findupdate| event. @@ -2705,6 +2699,50 @@ document.body.appendChild(webview); }; +function testFindInMultipleWebViews() { + var webviews = [new WebView(), new WebView(), new WebView()]; + var promises = []; + + // Search in all WebViews simultaneously. + for (var i in webviews) { + webviews[i].src = testFindPage; + promises[i] = new Promise((resolve, reject) => { + webviews[i].addEventListener('loadstop', function(id, event) { + LOG("Searching WebView " + id + "."); + + var webview = webviews[id]; + webview.find("dog", {}, (results_a) => { + embedder.test.assertEq(results_a.numberOfMatches, 100); + embedder.test.assertTrue(results_a.selectionRect.width > 0); + embedder.test.assertTrue(results_a.selectionRect.height > 0); + + // Test finding next active matches. + webview.find("dog"); + webview.find("dog"); + webview.find("dog"); + webview.find("dog"); + webview.find("dog", {}, (results_b) => { + embedder.test.assertEq(results_b.activeMatchOrdinal, 6); + LOG("Searched WebView " + id + " successfully."); + resolve(); + }); + }); + }.bind(undefined, i)); + }); + document.body.appendChild(webviews[i]); + } + + Promise.all(promises) + .then(() => { + LOG("All searches finished."); + embedder.test.succeed(); + }) + .catch((error) => { + LOG("Failing test."); + embedder.test.fail(error); + }); +} + function testLoadDataAPI() { var webview = new WebView(); webview.src = 'about:blank'; @@ -3165,6 +3203,7 @@ 'testZoomAPI' : testZoomAPI, 'testFindAPI': testFindAPI, 'testFindAPI_findupdate': testFindAPI_findupdate, + 'testFindInMultipleWebViews': testFindInMultipleWebViews, 'testLoadDataAPI': testLoadDataAPI, 'testResizeEvents': testResizeEvents, 'testPerOriginZoomMode': testPerOriginZoomMode,
diff --git a/chrome/test/data/policy/policy_test_cases.json b/chrome/test/data/policy/policy_test_cases.json index 6a2a6b3..d69ca5d 100644 --- a/chrome/test/data/policy/policy_test_cases.json +++ b/chrome/test/data/policy/policy_test_cases.json
@@ -2752,6 +2752,14 @@ ] }, + "InstantTetheringAllowed": { + "os": ["chromeos"], + "test_policy": { "InstantTetheringAllowed": false }, + "pref_mappings": [ + { "pref": "tether.allowed" } + ] + }, + "----- Chrome OS device policies ---------------------------------------": {}, "DevicePolicyRefreshRate": {
diff --git a/chromeos/components/tether/initializer.cc b/chromeos/components/tether/initializer.cc index cc0e788..c0de894 100644 --- a/chromeos/components/tether/initializer.cc +++ b/chromeos/components/tether/initializer.cc
@@ -22,6 +22,7 @@ #include "chromeos/components/tether/wifi_hotspot_connector.h" #include "chromeos/network/managed_network_configuration_handler.h" #include "chromeos/network/network_connect.h" +#include "chromeos/network/network_connection_handler.h" #include "chromeos/network/network_state_handler.h" #include "components/cryptauth/bluetooth_throttler_impl.h" #include "components/cryptauth/cryptauth_service.h" @@ -55,7 +56,8 @@ ProfileOAuth2TokenService* token_service, NetworkStateHandler* network_state_handler, ManagedNetworkConfigurationHandler* managed_network_configuration_handler, - NetworkConnect* network_connect) { + NetworkConnect* network_connect, + NetworkConnectionHandler* network_connection_handler) { if (!device::BluetoothAdapterFactory::IsBluetoothSupported()) { PA_LOG(WARNING) << "Bluetooth is not supported on this device; cannot " << "initialize tether feature."; @@ -72,7 +74,8 @@ instance_ = new Initializer(cryptauth_service, std::move(notification_presenter), pref_service, token_service, network_state_handler, - managed_network_configuration_handler, network_connect); + managed_network_configuration_handler, network_connect, + network_connection_handler); } // static @@ -97,7 +100,8 @@ ProfileOAuth2TokenService* token_service, NetworkStateHandler* network_state_handler, ManagedNetworkConfigurationHandler* managed_network_configuration_handler, - NetworkConnect* network_connect) + NetworkConnect* network_connect, + NetworkConnectionHandler* network_connection_handler) : cryptauth_service_(cryptauth_service), notification_presenter_(std::move(notification_presenter)), pref_service_(pref_service), @@ -106,6 +110,7 @@ managed_network_configuration_handler_( managed_network_configuration_handler), network_connect_(network_connect), + network_connection_handler_(network_connection_handler), weak_ptr_factory_(this) { if (!token_service_->RefreshTokenIsAvailable( cryptauth_service_->GetAccountId())) { @@ -186,9 +191,10 @@ device_id_tether_network_guid_map_ = base::MakeUnique<DeviceIdTetherNetworkGuidMap>(); tether_connector_ = base::MakeUnique<TetherConnector>( - network_connect_, network_state_handler_, wifi_hotspot_connector_.get(), - active_host_.get(), tether_host_fetcher_.get(), - ble_connection_manager_.get(), host_scan_device_prioritizer_.get(), + network_connection_handler_, network_state_handler_, + wifi_hotspot_connector_.get(), active_host_.get(), + tether_host_fetcher_.get(), ble_connection_manager_.get(), + host_scan_device_prioritizer_.get(), device_id_tether_network_guid_map_.get()); network_configuration_remover_ = base::MakeUnique<NetworkConfigurationRemover>(
diff --git a/chromeos/components/tether/initializer.h b/chromeos/components/tether/initializer.h index 60898e8..be2e265 100644 --- a/chromeos/components/tether/initializer.h +++ b/chromeos/components/tether/initializer.h
@@ -27,6 +27,7 @@ class ManagedNetworkConfigurationHandler; class NetworkConnect; +class NetworkConnectionHandler; class NetworkStateHandler; namespace tether { @@ -57,7 +58,8 @@ ProfileOAuth2TokenService* token_service, NetworkStateHandler* network_state_handler, ManagedNetworkConfigurationHandler* managed_network_configuration_handler, - NetworkConnect* network_connect); + NetworkConnect* network_connect, + NetworkConnectionHandler* network_connection_handler); // Shuts down the tether feature, destroying all internal classes. This should // be called before the dependencies passed to Init() are destroyed. @@ -77,7 +79,8 @@ ProfileOAuth2TokenService* token_service, NetworkStateHandler* network_state_handler, ManagedNetworkConfigurationHandler* managed_network_configuration_handler, - NetworkConnect* network_connect); + NetworkConnect* network_connect, + NetworkConnectionHandler* network_connection_handler); ~Initializer() override; // OAuth2TokenService::Observer: @@ -98,6 +101,7 @@ NetworkStateHandler* network_state_handler_; ManagedNetworkConfigurationHandler* managed_network_configuration_handler_; NetworkConnect* network_connect_; + NetworkConnectionHandler* network_connection_handler_; // Declare new objects in the order that they will be created during // initialization to ensure that they are destroyed in the correct order. This
diff --git a/chromeos/components/tether/initializer_unittest.cc b/chromeos/components/tether/initializer_unittest.cc index 21b348e6..e0c276f 100644 --- a/chromeos/components/tether/initializer_unittest.cc +++ b/chromeos/components/tether/initializer_unittest.cc
@@ -16,6 +16,7 @@ #include "chromeos/network/managed_network_configuration_handler.h" #include "chromeos/network/mock_managed_network_configuration_handler.h" #include "chromeos/network/network_connect.h" +#include "chromeos/network/network_connection_handler.h" #include "chromeos/network/network_handler.h" #include "chromeos/network/network_state_test.h" #include "components/cryptauth/cryptauth_device_manager.h" @@ -82,7 +83,12 @@ MOCK_METHOD2(CreateConfigurationAndConnect, void(base::DictionaryValue*, bool)); MOCK_METHOD2(CreateConfiguration, void(base::DictionaryValue*, bool)); - MOCK_METHOD1(SetTetherDelegate, void(NetworkConnect::TetherDelegate*)); +}; + +class TestNetworkConnectionHandler : public NetworkConnectionHandler { + public: + TestNetworkConnectionHandler() : NetworkConnectionHandler() {} + ~TestNetworkConnectionHandler() override {} }; } // namespace @@ -115,11 +121,13 @@ NetworkStateHandler* network_state_handler, ManagedNetworkConfigurationHandler* managed_network_configuration_handler, NetworkConnect* network_connect, + NetworkConnectionHandler* network_connection_handler, scoped_refptr<device::BluetoothAdapter> adapter) { Initializer* initializer = new Initializer(cryptauth_service, std::move(notification_presenter), pref_service, token_service, network_state_handler, - managed_network_configuration_handler, network_connect); + managed_network_configuration_handler, network_connect, + network_connection_handler); initializer->OnBluetoothAdapterAdvertisingIntervalSet(adapter); delete initializer; } @@ -169,18 +177,21 @@ std::unique_ptr<MockNetworkConnect> mock_network_connect = base::WrapUnique(new NiceMock<MockNetworkConnect>); + std::unique_ptr<NetworkConnectionHandler> network_connection_handler_ = + base::MakeUnique<TestNetworkConnectionHandler>(); + scoped_refptr<NiceMock<device::MockBluetoothAdapter>> mock_adapter = make_scoped_refptr(new NiceMock<device::MockBluetoothAdapter>()); // Call an instance method of the test instead of initializing and destroying // here because the friend relationship between Initializer and // InitializerTest only applies to the class itself, not these test functions. - InitializeAndDestroy(fake_cryptauth_service.get(), - base::MakeUnique<FakeNotificationPresenter>(), - test_pref_service_.get(), fake_token_service.get(), - network_state_handler(), - managed_network_configuration_handler.get(), - mock_network_connect.get(), mock_adapter); + InitializeAndDestroy( + fake_cryptauth_service.get(), + base::MakeUnique<FakeNotificationPresenter>(), test_pref_service_.get(), + fake_token_service.get(), network_state_handler(), + managed_network_configuration_handler.get(), mock_network_connect.get(), + network_connection_handler_.get(), mock_adapter); } } // namespace tether
diff --git a/chromeos/components/tether/tether_connector.cc b/chromeos/components/tether/tether_connector.cc index 21da910f..25dfec22 100644 --- a/chromeos/components/tether/tether_connector.cc +++ b/chromeos/components/tether/tether_connector.cc
@@ -18,7 +18,7 @@ namespace tether { TetherConnector::TetherConnector( - NetworkConnect* network_connect, + NetworkConnectionHandler* network_connection_handler, NetworkStateHandler* network_state_handler, WifiHotspotConnector* wifi_hotspot_connector, ActiveHost* active_host, @@ -26,7 +26,7 @@ BleConnectionManager* connection_manager, HostScanDevicePrioritizer* host_scan_device_prioritizer, DeviceIdTetherNetworkGuidMap* device_id_tether_network_guid_map) - : network_connect_(network_connect), + : network_connection_handler_(network_connection_handler), network_state_handler_(network_state_handler), wifi_hotspot_connector_(wifi_hotspot_connector), active_host_(active_host), @@ -35,43 +35,59 @@ host_scan_device_prioritizer_(host_scan_device_prioritizer), device_id_tether_network_guid_map_(device_id_tether_network_guid_map), weak_ptr_factory_(this) { - network_connect_->SetTetherDelegate(this); + network_connection_handler_->SetTetherDelegate(this); } TetherConnector::~TetherConnector() { - network_connect_->SetTetherDelegate(nullptr); + network_connection_handler_->SetTetherDelegate(nullptr); if (connect_tethering_operation_) { connect_tethering_operation_->RemoveObserver(this); } } -void TetherConnector::ConnectToNetwork(const std::string& guid) { - PA_LOG(INFO) << "Attempting to connect to network with GUID " << guid << "."; +void TetherConnector::ConnectToNetwork( + const std::string& tether_network_guid, + const base::Closure& success_callback, + const network_handler::StringResultCallback& error_callback) { + DCHECK(!tether_network_guid.empty()); + DCHECK(!success_callback.is_null()); + DCHECK(!error_callback.is_null()); + + PA_LOG(INFO) << "Attempting to connect to network with GUID " + << tether_network_guid << "."; std::string device_id = - device_id_tether_network_guid_map_->GetDeviceIdForTetherNetworkGuid(guid); + device_id_tether_network_guid_map_->GetDeviceIdForTetherNetworkGuid( + tether_network_guid); - if (device_id_pending_connection_ == device_id) { - PA_LOG(INFO) << "Connection attempt requested for network with GUID " - << guid << ", but a connection attempt is already in " - << "progress. Continuing with the existing attempt."; - return; - } + // If NetworkConnectionHandler receives a connection request for a network + // to which it is already attempting a connection, it should stop the + // duplicate connection request itself before invoking its TetherDelegate. + // Thus, ConnectToNetwork() should never be called for a device which is + // already pending connection. + DCHECK(device_id_pending_connection_ != device_id); - if (connect_tethering_operation_) { - DCHECK(!device_id_pending_connection_.empty()); - + if (!device_id_pending_connection_.empty()) { PA_LOG(INFO) << "A connection attempt was already in progress to device " << "with ID " << device_id_pending_connection_ << ". " << "Canceling that connection attempt before continuing."; - // If a connection to a *different* device is pending, stop the connection - // attempt. - connect_tethering_operation_->RemoveObserver(this); - connect_tethering_operation_.reset(); + if (connect_tethering_operation_) { + // If a ConnectTetheringOperation is in progress, stop it. + connect_tethering_operation_->RemoveObserver(this); + connect_tethering_operation_.reset(); + } + + // Since the previous connection attempt did not complete before the new + // attempt began, call the error callback. + DCHECK(!error_callback_.is_null()); + error_callback_.Run(NetworkConnectionHandler::kErrorConnectCanceled); } device_id_pending_connection_ = device_id; + success_callback_ = success_callback; + error_callback_ = error_callback; + active_host_->SetActiveHostConnecting(device_id, tether_network_guid); tether_host_fetcher_->FetchTetherHost( device_id_pending_connection_, @@ -129,34 +145,32 @@ PA_LOG(WARNING) << "Connection to device with ID " << remote_device.GetTruncatedDeviceIdForLogs() - << " could not connect. Error code: " << error_code; + << " could not complete. Error code: " << error_code; connect_tethering_operation_->RemoveObserver(this); connect_tethering_operation_.reset(); - SetDisconnected(); + SetConnectionFailed(); } void TetherConnector::OnTetherHostToConnectFetched( const std::string& device_id, std::unique_ptr<cryptauth::RemoteDevice> tether_host_to_connect) { - if (!tether_host_to_connect) { - PA_LOG(ERROR) << "Could not fetch tether host with device ID " - << cryptauth::RemoteDevice::TruncateDeviceIdForLogs(device_id) - << ". Cannot connect."; - return; - } - - if (device_id_pending_connection_ != tether_host_to_connect->GetDeviceId()) { + if (device_id_pending_connection_ != device_id) { PA_LOG(INFO) << "Device to connect to has changed while device with ID " << cryptauth::RemoteDevice::TruncateDeviceIdForLogs(device_id) << " was being fetched."; return; } - active_host_->SetActiveHostConnecting( - device_id_pending_connection_, - device_id_tether_network_guid_map_->GetTetherNetworkGuidForDeviceId( - device_id_pending_connection_)); + if (!tether_host_to_connect) { + PA_LOG(ERROR) << "Could not fetch tether host with device ID " + << cryptauth::RemoteDevice::TruncateDeviceIdForLogs(device_id) + << ". Cannot connect."; + SetConnectionFailed(); + return; + } + + DCHECK(device_id == tether_host_to_connect->GetDeviceId()); connect_tethering_operation_ = ConnectTetheringOperation::Factory::NewInstance( @@ -166,14 +180,36 @@ connect_tethering_operation_->Initialize(); } -void TetherConnector::SetDisconnected() { - device_id_pending_connection_ = ""; +void TetherConnector::SetConnectionFailed() { + DCHECK(!device_id_pending_connection_.empty()); + DCHECK(!error_callback_.is_null()); + + // Save a copy of the callback before resetting it below. + network_handler::StringResultCallback error_callback = error_callback_; + + device_id_pending_connection_.clear(); + success_callback_.Reset(); + error_callback_.Reset(); + + error_callback.Run(NetworkConnectionHandler::kErrorConnectFailed); active_host_->SetActiveHostDisconnected(); } -void TetherConnector::SetConnected(const std::string& device_id, - const std::string& wifi_network_guid) { - device_id_pending_connection_ = ""; +void TetherConnector::SetConnectionSucceeded( + const std::string& device_id, + const std::string& wifi_network_guid) { + DCHECK(!device_id_pending_connection_.empty()); + DCHECK(device_id_pending_connection_ == device_id); + DCHECK(!success_callback_.is_null()); + + // Save a copy of the callback before resetting it below. + base::Closure success_callback = success_callback_; + + device_id_pending_connection_.clear(); + success_callback_.Reset(); + error_callback_.Reset(); + + success_callback.Run(); active_host_->SetActiveHostConnected( device_id, device_id_tether_network_guid_map_->GetTetherNetworkGuidForDeviceId( @@ -202,7 +238,7 @@ << cryptauth::RemoteDevice::TruncateDeviceIdForLogs(device_id) << "."; - SetDisconnected(); + SetConnectionFailed(); return; } @@ -223,7 +259,7 @@ << wifi_network_guid << "\"."; } - SetConnected(device_id, wifi_network_guid); + SetConnectionSucceeded(device_id, wifi_network_guid); } } // namespace tether
diff --git a/chromeos/components/tether/tether_connector.h b/chromeos/components/tether/tether_connector.h index d896c45..6bd8ed64 100644 --- a/chromeos/components/tether/tether_connector.h +++ b/chromeos/components/tether/tether_connector.h
@@ -8,7 +8,7 @@ #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "chromeos/components/tether/connect_tethering_operation.h" -#include "chromeos/network/network_connect.h" +#include "chromeos/network/network_connection_handler.h" namespace chromeos { @@ -24,15 +24,15 @@ class WifiHotspotConnector; // Connects to a tether network. When the user initiates a connection via the -// UI, TetherConnector receives a callback from NetworkConnect and initiates a -// connection by starting a ConnectTetheringOperation. When a response has been -// received from the tether host, TetherConnector connects to the associated -// Wi-Fi network. -class TetherConnector : public NetworkConnect::TetherDelegate, +// UI, TetherConnector receives a callback from NetworkConnectionHandler and +// initiates a connection by starting a ConnectTetheringOperation. When a +// response has been received from the tether host, TetherConnector connects to +// the associated Wi-Fi network. +class TetherConnector : public NetworkConnectionHandler::TetherDelegate, public ConnectTetheringOperation::Observer { public: TetherConnector( - NetworkConnect* network_connect, + NetworkConnectionHandler* network_connection_handler, NetworkStateHandler* network_state_handler, WifiHotspotConnector* wifi_hotspot_connector, ActiveHost* active_host, @@ -42,8 +42,11 @@ DeviceIdTetherNetworkGuidMap* device_id_tether_network_guid_map); ~TetherConnector() override; - // NetworkConnect::TetherDelegate: - void ConnectToNetwork(const std::string& guid) override; + // NetworkConnectionHandler::TetherDelegate: + void ConnectToNetwork( + const std::string& tether_network_guid, + const base::Closure& success_callback, + const network_handler::StringResultCallback& error_callback) override; // ConnectTetheringOperation::Observer: void OnSuccessfulConnectTetheringResponse( @@ -57,9 +60,9 @@ private: friend class TetherConnectorTest; - void SetDisconnected(); - void SetConnected(const std::string& device_id, - const std::string& wifi_network_guid); + void SetConnectionFailed(); + void SetConnectionSucceeded(const std::string& device_id, + const std::string& wifi_network_guid); void OnTetherHostToConnectFetched( const std::string& device_id, @@ -67,7 +70,7 @@ void OnWifiConnection(const std::string& device_id, const std::string& wifi_network_guid); - NetworkConnect* network_connect_; + NetworkConnectionHandler* network_connection_handler_; NetworkStateHandler* network_state_handler_; WifiHotspotConnector* wifi_hotspot_connector_; ActiveHost* active_host_; @@ -77,6 +80,8 @@ DeviceIdTetherNetworkGuidMap* device_id_tether_network_guid_map_; std::string device_id_pending_connection_; + base::Closure success_callback_; + network_handler::StringResultCallback error_callback_; std::unique_ptr<ConnectTetheringOperation> connect_tethering_operation_; base::WeakPtrFactory<TetherConnector> weak_ptr_factory_;
diff --git a/chromeos/components/tether/tether_connector_unittest.cc b/chromeos/components/tether/tether_connector_unittest.cc index dc3ce92..beae897e 100644 --- a/chromeos/components/tether/tether_connector_unittest.cc +++ b/chromeos/components/tether/tether_connector_unittest.cc
@@ -15,7 +15,7 @@ #include "chromeos/components/tether/mock_host_scan_device_prioritizer.h" #include "chromeos/components/tether/tether_connector.h" #include "chromeos/dbus/dbus_thread_manager.h" -#include "chromeos/network/network_connect.h" +#include "chromeos/network/network_connection_handler.h" #include "chromeos/network/network_state.h" #include "chromeos/network/network_state_handler.h" #include "chromeos/network/network_state_test.h" @@ -31,6 +31,8 @@ namespace { +const char kSuccessResult[] = "success"; + const char kSsid[] = "ssid"; const char kPassword[] = "password"; @@ -46,41 +48,18 @@ return ss.str(); } -class TestNetworkConnect : public NetworkConnect { +class TestNetworkConnectionHandler : public NetworkConnectionHandler { public: - TestNetworkConnect() : tether_delegate_(nullptr) {} - ~TestNetworkConnect() override {} + TestNetworkConnectionHandler() : NetworkConnectionHandler() {} + ~TestNetworkConnectionHandler() override {} - void CallTetherDelegate(const std::string& tether_network_guid) { - tether_delegate_->ConnectToNetwork(tether_network_guid); + void CallTetherDelegate( + const std::string& tether_network_guid, + const base::Closure& success_callback, + const network_handler::ErrorCallback& error_callback) { + InitiateTetherNetworkConnection(tether_network_guid, success_callback, + error_callback); } - - // NetworkConnect: - void SetTetherDelegate( - NetworkConnect::TetherDelegate* tether_delegate) override { - tether_delegate_ = tether_delegate; - } - - void DisconnectFromNetworkId(const std::string& network_id) override {} - bool MaybeShowConfigureUI(const std::string& network_id, - const std::string& connect_error) override { - return false; - } - void SetTechnologyEnabled(const chromeos::NetworkTypePattern& technology, - bool enabled_state) override {} - void ShowMobileSetup(const std::string& network_id) override {} - void ConfigureNetworkIdAndConnect( - const std::string& network_id, - const base::DictionaryValue& shill_properties, - bool shared) override {} - void CreateConfigurationAndConnect(base::DictionaryValue* shill_properties, - bool shared) override {} - void CreateConfiguration(base::DictionaryValue* shill_properties, - bool shared) override {} - void ConnectToNetworkId(const std::string& network_id) override {} - - private: - NetworkConnect::TetherDelegate* tether_delegate_; }; class FakeConnectTetheringOperation : public ConnectTetheringOperation { @@ -156,7 +135,8 @@ ConnectTetheringOperation::Factory::SetInstanceForTesting( fake_operation_factory_.get()); - test_network_connect_ = base::WrapUnique(new TestNetworkConnect()); + test_network_connection_handler_ = + base::WrapUnique(new TestNetworkConnectionHandler()); fake_wifi_hotspot_connector_ = base::MakeUnique<FakeWifiHotspotConnector>(network_state_handler()); fake_active_host_ = base::MakeUnique<FakeActiveHost>(); @@ -168,8 +148,10 @@ device_id_tether_network_guid_map_ = base::MakeUnique<DeviceIdTetherNetworkGuidMap>(); + result_.clear(); + tether_connector_ = base::WrapUnique(new TetherConnector( - test_network_connect_.get(), network_state_handler(), + test_network_connection_handler_.get(), network_state_handler(), fake_wifi_hotspot_connector_.get(), fake_active_host_.get(), fake_tether_host_fetcher_.get(), fake_ble_connection_manager_.get(), mock_host_scan_device_prioritizer_.get(), @@ -226,11 +208,34 @@ EXPECT_EQ(tether_network_guid, wifi_network_state->tether_guid()); } + void SuccessCallback() { result_ = kSuccessResult; } + + void ErrorCallback(const std::string& error_name, + std::unique_ptr<base::DictionaryValue> error_data) { + result_ = error_name; + } + + void CallTetherDelegate(const std::string& tether_network_guid) { + test_network_connection_handler_->CallTetherDelegate( + tether_network_guid, + base::Bind(&TetherConnectorTest::SuccessCallback, + base::Unretained(this)), + base::Bind(&TetherConnectorTest::ErrorCallback, + base::Unretained(this))); + } + + std::string GetResultAndReset() { + std::string result; + result.swap(result_); + return result; + } + const std::vector<cryptauth::RemoteDevice> test_devices_; const base::MessageLoop message_loop_; std::unique_ptr<FakeConnectTetheringOperationFactory> fake_operation_factory_; - std::unique_ptr<TestNetworkConnect> test_network_connect_; + std::unique_ptr<TestNetworkConnectionHandler> + test_network_connection_handler_; std::unique_ptr<FakeWifiHotspotConnector> fake_wifi_hotspot_connector_; std::unique_ptr<FakeActiveHost> fake_active_host_; std::unique_ptr<FakeTetherHostFetcher> fake_tether_host_fetcher_; @@ -241,6 +246,8 @@ std::unique_ptr<DeviceIdTetherNetworkGuidMap> device_id_tether_network_guid_map_; + std::string result_; + std::unique_ptr<TetherConnector> tether_connector_; private: @@ -248,22 +255,28 @@ }; TEST_F(TetherConnectorTest, TestCannotFetchDevice) { - test_network_connect_->CallTetherDelegate( - GetTetherNetworkGuid("nonexistentDeviceId")); + // Base64-encoded version of "nonexistentDeviceId". + const char kNonexistentDeviceId[] = "bm9uZXhpc3RlbnREZXZpY2VJZA=="; + + CallTetherDelegate(GetTetherNetworkGuid(kNonexistentDeviceId)); + EXPECT_EQ(ActiveHost::ActiveHostStatus::CONNECTING, + fake_active_host_->GetActiveHostStatus()); + EXPECT_EQ(kNonexistentDeviceId, fake_active_host_->GetActiveHostDeviceId()); + EXPECT_EQ(GetTetherNetworkGuid(kNonexistentDeviceId), + fake_active_host_->GetTetherNetworkGuid()); + EXPECT_TRUE(fake_active_host_->GetWifiNetworkGuid().empty()); + fake_tether_host_fetcher_->InvokePendingCallbacks(); // Since an invalid device ID was used, no connection should have been // started. EXPECT_EQ(ActiveHost::ActiveHostStatus::DISCONNECTED, fake_active_host_->GetActiveHostStatus()); + EXPECT_EQ(NetworkConnectionHandler::kErrorConnectFailed, GetResultAndReset()); } TEST_F(TetherConnectorTest, TestConnectTetheringOperationFails) { - test_network_connect_->CallTetherDelegate( - GetTetherNetworkGuid(test_devices_[0].GetDeviceId())); - fake_tether_host_fetcher_->InvokePendingCallbacks(); - - // The connection should have started. + CallTetherDelegate(GetTetherNetworkGuid(test_devices_[0].GetDeviceId())); EXPECT_EQ(ActiveHost::ActiveHostStatus::CONNECTING, fake_active_host_->GetActiveHostStatus()); EXPECT_EQ(test_devices_[0].GetDeviceId(), @@ -272,6 +285,8 @@ fake_active_host_->GetTetherNetworkGuid()); EXPECT_TRUE(fake_active_host_->GetWifiNetworkGuid().empty()); + fake_tether_host_fetcher_->InvokePendingCallbacks(); + // Simulate a failed connection attempt (either the host cannot provide // tethering at this time or a timeout occurs). EXPECT_EQ(1u, fake_operation_factory_->created_operations().size()); @@ -282,14 +297,11 @@ // The failure should have resulted in the host being disconnected. EXPECT_EQ(ActiveHost::ActiveHostStatus::DISCONNECTED, fake_active_host_->GetActiveHostStatus()); + EXPECT_EQ(NetworkConnectionHandler::kErrorConnectFailed, GetResultAndReset()); } TEST_F(TetherConnectorTest, TestConnectingToWifiFails) { - test_network_connect_->CallTetherDelegate( - GetTetherNetworkGuid(test_devices_[0].GetDeviceId())); - fake_tether_host_fetcher_->InvokePendingCallbacks(); - - // The connection should have started. + CallTetherDelegate(GetTetherNetworkGuid(test_devices_[0].GetDeviceId())); EXPECT_EQ(ActiveHost::ActiveHostStatus::CONNECTING, fake_active_host_->GetActiveHostStatus()); EXPECT_EQ(test_devices_[0].GetDeviceId(), @@ -298,6 +310,8 @@ fake_active_host_->GetTetherNetworkGuid()); EXPECT_TRUE(fake_active_host_->GetWifiNetworkGuid().empty()); + fake_tether_host_fetcher_->InvokePendingCallbacks(); + // Receive a successful response. We should still be connecting. EXPECT_EQ(1u, fake_operation_factory_->created_operations().size()); fake_operation_factory_->created_operations()[0]->SendSuccessfulResponse( @@ -315,14 +329,11 @@ // The failure should have resulted in the host being disconnected. EXPECT_EQ(ActiveHost::ActiveHostStatus::DISCONNECTED, fake_active_host_->GetActiveHostStatus()); + EXPECT_EQ(NetworkConnectionHandler::kErrorConnectFailed, GetResultAndReset()); } TEST_F(TetherConnectorTest, TestSuccessfulConnection) { - test_network_connect_->CallTetherDelegate( - GetTetherNetworkGuid(test_devices_[0].GetDeviceId())); - fake_tether_host_fetcher_->InvokePendingCallbacks(); - - // The connection should have started. + CallTetherDelegate(GetTetherNetworkGuid(test_devices_[0].GetDeviceId())); EXPECT_EQ(ActiveHost::ActiveHostStatus::CONNECTING, fake_active_host_->GetActiveHostStatus()); EXPECT_EQ(test_devices_[0].GetDeviceId(), @@ -331,6 +342,8 @@ fake_active_host_->GetTetherNetworkGuid()); EXPECT_TRUE(fake_active_host_->GetWifiNetworkGuid().empty()); + fake_tether_host_fetcher_->InvokePendingCallbacks(); + // Receive a successful response. We should still be connecting. EXPECT_EQ(1u, fake_operation_factory_->created_operations().size()); fake_operation_factory_->created_operations()[0]->SendSuccessfulResponse( @@ -356,32 +369,20 @@ EXPECT_EQ(kWifiNetworkGuid, fake_active_host_->GetWifiNetworkGuid()); VerifyTetherAndWifiNetworkAssociation( GetTetherNetworkGuid(test_devices_[0].GetDeviceId())); -} - -TEST_F(TetherConnectorTest, TestNewConnectionAttemptDuringFetch_SameDevice) { - test_network_connect_->CallTetherDelegate( - GetTetherNetworkGuid(test_devices_[0].GetDeviceId())); - - // Instead of invoking the pending callbacks on |fake_tether_host_fetcher_|, - // attempt another connection attempt. - test_network_connect_->CallTetherDelegate( - GetTetherNetworkGuid(test_devices_[0].GetDeviceId())); - - // Now invoke the callbacks. Only one operation should have been created, - // even though the callback occurred twice. - fake_tether_host_fetcher_->InvokePendingCallbacks(); - EXPECT_EQ(1u, fake_operation_factory_->created_operations().size()); + EXPECT_EQ(kSuccessResult, GetResultAndReset()); } TEST_F(TetherConnectorTest, TestNewConnectionAttemptDuringFetch_DifferentDevice) { - test_network_connect_->CallTetherDelegate( - GetTetherNetworkGuid(test_devices_[0].GetDeviceId())); + CallTetherDelegate(GetTetherNetworkGuid(test_devices_[0].GetDeviceId())); // Instead of invoking the pending callbacks on |fake_tether_host_fetcher_|, // attempt another connection attempt, this time to another device. - test_network_connect_->CallTetherDelegate( - GetTetherNetworkGuid(test_devices_[1].GetDeviceId())); + CallTetherDelegate(GetTetherNetworkGuid(test_devices_[1].GetDeviceId())); + // The first connection attempt should have resulted in a connect canceled + // error. + EXPECT_EQ(NetworkConnectionHandler::kErrorConnectCanceled, + GetResultAndReset()); // Now invoke the callbacks. An operation should have been created for the // device 1, not device 0. @@ -394,11 +395,7 @@ TEST_F(TetherConnectorTest, TestNewConnectionAttemptDuringOperation_DifferentDevice) { - test_network_connect_->CallTetherDelegate( - GetTetherNetworkGuid(test_devices_[0].GetDeviceId())); - fake_tether_host_fetcher_->InvokePendingCallbacks(); - - // The active host should be device 0. + CallTetherDelegate(GetTetherNetworkGuid(test_devices_[0].GetDeviceId())); EXPECT_EQ(ActiveHost::ActiveHostStatus::CONNECTING, fake_active_host_->GetActiveHostStatus()); EXPECT_EQ(test_devices_[0].GetDeviceId(), @@ -407,12 +404,17 @@ fake_active_host_->GetTetherNetworkGuid()); EXPECT_TRUE(fake_active_host_->GetWifiNetworkGuid().empty()); + fake_tether_host_fetcher_->InvokePendingCallbacks(); + // An operation should have been created. EXPECT_EQ(1u, fake_operation_factory_->created_operations().size()); // Before the created operation replies, start a new connection to device 1. - test_network_connect_->CallTetherDelegate( - GetTetherNetworkGuid(test_devices_[1].GetDeviceId())); + CallTetherDelegate(GetTetherNetworkGuid(test_devices_[1].GetDeviceId())); + // The first connection attempt should have resulted in a connect canceled + // error. + EXPECT_EQ(NetworkConnectionHandler::kErrorConnectCanceled, + GetResultAndReset()); fake_tether_host_fetcher_->InvokePendingCallbacks(); // Now, the active host should be the second device. @@ -441,15 +443,15 @@ TEST_F(TetherConnectorTest, TestNewConnectionAttemptDuringWifiConnection_DifferentDevice) { - test_network_connect_->CallTetherDelegate( - GetTetherNetworkGuid(test_devices_[0].GetDeviceId())); - fake_tether_host_fetcher_->InvokePendingCallbacks(); + CallTetherDelegate(GetTetherNetworkGuid(test_devices_[0].GetDeviceId())); EXPECT_EQ(ActiveHost::ActiveHostStatus::CONNECTING, fake_active_host_->GetActiveHostStatus()); EXPECT_EQ(test_devices_[0].GetDeviceId(), fake_active_host_->GetActiveHostDeviceId()); - EXPECT_EQ(1u, fake_operation_factory_->created_operations().size()); + fake_tether_host_fetcher_->InvokePendingCallbacks(); + + EXPECT_EQ(1u, fake_operation_factory_->created_operations().size()); fake_operation_factory_->created_operations()[0]->SendSuccessfulResponse( kSsid, kPassword); EXPECT_EQ(ActiveHost::ActiveHostStatus::CONNECTING, @@ -459,8 +461,11 @@ // While the connection to the Wi-Fi network is in progress, start a new // connection attempt. - test_network_connect_->CallTetherDelegate( - GetTetherNetworkGuid(test_devices_[1].GetDeviceId())); + CallTetherDelegate(GetTetherNetworkGuid(test_devices_[1].GetDeviceId())); + // The first connection attempt should have resulted in a connect canceled + // error. + EXPECT_EQ(NetworkConnectionHandler::kErrorConnectCanceled, + GetResultAndReset()); fake_tether_host_fetcher_->InvokePendingCallbacks(); // Connect successfully to the first Wi-Fi network. Even though a temporary
diff --git a/chromeos/components/tether/wifi_hotspot_connector_unittest.cc b/chromeos/components/tether/wifi_hotspot_connector_unittest.cc index 9fe074a..3eb687d 100644 --- a/chromeos/components/tether/wifi_hotspot_connector_unittest.cc +++ b/chromeos/components/tether/wifi_hotspot_connector_unittest.cc
@@ -52,7 +52,7 @@ public: class TestNetworkConnect : public NetworkConnect { public: - TestNetworkConnect(NetworkStateTest* network_state_test) + explicit TestNetworkConnect(NetworkStateTest* network_state_test) : network_state_test_(network_state_test) {} ~TestNetworkConnect() override {} @@ -81,7 +81,6 @@ bool shared) override {} void CreateConfigurationAndConnect(base::DictionaryValue* shill_properties, bool shared) override {} - void SetTetherDelegate(TetherDelegate* tether_delegate) override {} void CreateConfiguration(base::DictionaryValue* shill_properties, bool shared) override { @@ -381,4 +380,4 @@ } // namespace tether -} // namespace cryptauth +} // namespace chromeos
diff --git a/chromeos/network/network_connect.cc b/chromeos/network/network_connect.cc index ee01867..b4b2b5ba3e 100644 --- a/chromeos/network/network_connect.cc +++ b/chromeos/network/network_connect.cc
@@ -65,7 +65,6 @@ bool shared) override; void CreateConfiguration(base::DictionaryValue* shill_properties, bool shared) override; - void SetTetherDelegate(TetherDelegate* tether_delegate) override; private: void ActivateCellular(const std::string& network_id); @@ -105,14 +104,13 @@ std::unique_ptr<base::DictionaryValue> properties_to_set); Delegate* delegate_; - TetherDelegate* tether_delegate_; base::WeakPtrFactory<NetworkConnectImpl> weak_factory_; DISALLOW_COPY_AND_ASSIGN(NetworkConnectImpl); }; NetworkConnectImpl::NetworkConnectImpl(Delegate* delegate) - : delegate_(delegate), tether_delegate_(nullptr), weak_factory_(this) {} + : delegate_(delegate), weak_factory_(this) {} NetworkConnectImpl::~NetworkConnectImpl() {} @@ -245,17 +243,6 @@ return; } - if (NetworkTypePattern::Tether().MatchesType(network->type())) { - if (tether_delegate_) { - tether_delegate_->ConnectToNetwork(network_id); - } else { - NET_LOG_ERROR( - "Connection to Tether requested but no TetherDelegate exists.", - network_id); - } - return; - } - NetworkHandler::Get()->network_connection_handler()->ConnectToNetwork( network->path(), base::Bind(&NetworkConnectImpl::OnConnectSucceeded, weak_factory_.GetWeakPtr(), network_id), @@ -567,10 +554,6 @@ CallCreateConfiguration(properties, shared, false /* connect_on_configure */); } -void NetworkConnectImpl::SetTetherDelegate(TetherDelegate* tether_delegate) { - tether_delegate_ = tether_delegate; -} - } // namespace static NetworkConnect* g_network_connect = NULL;
diff --git a/chromeos/network/network_connect.h b/chromeos/network/network_connect.h index 0e06698..b5fcfbd 100644 --- a/chromeos/network/network_connect.h +++ b/chromeos/network/network_connect.h
@@ -56,15 +56,6 @@ virtual ~Delegate() {} }; - class CHROMEOS_EXPORT TetherDelegate { - public: - // Connect to the Tether network associated with |guid|. - virtual void ConnectToNetwork(const std::string& guid) = 0; - - protected: - virtual ~TetherDelegate() {} - }; - // Creates the global NetworkConnect object. |delegate| is owned by the // caller. static void Initialize(Delegate* delegate); @@ -120,10 +111,6 @@ virtual void CreateConfiguration(base::DictionaryValue* shill_properties, bool shared) = 0; - // Sets the TetherDelegate to handle Tether actions. |tether_delegate| is - // owned by the caller. - virtual void SetTetherDelegate(TetherDelegate* tether_delegate) = 0; - protected: NetworkConnect();
diff --git a/chromeos/network/network_connect_unittest.cc b/chromeos/network/network_connect_unittest.cc index 2eb4d44..92e5c72 100644 --- a/chromeos/network/network_connect_unittest.cc +++ b/chromeos/network/network_connect_unittest.cc
@@ -40,8 +40,6 @@ const char kCellular1ServicePath[] = "/service/cellular1"; const char kCellular1Guid[] = "cellular1_guid"; -const char kTether1Guid[] = "tether1_guid"; - class MockDelegate : public NetworkConnect::Delegate { public: MockDelegate() {} @@ -58,14 +56,6 @@ MOCK_METHOD1(ShowMobileActivationError, void(const std::string& network_id)); }; -class MockTetherDelegate : public NetworkConnect::TetherDelegate { - public: - MockTetherDelegate() {} - ~MockTetherDelegate() override {} - - MOCK_METHOD1(ConnectToNetwork, void(const std::string& guid)); -}; - } // namespace class NetworkConnectTest : public testing::Test { @@ -84,8 +74,6 @@ mock_delegate_.reset(new MockDelegate()); ON_CALL(*mock_delegate_, ShowEnrollNetwork(_)).WillByDefault(Return(true)); - mock_tether_delegate_.reset(new MockTetherDelegate()); - NetworkConnect::Initialize(mock_delegate_.get()); } @@ -146,7 +134,6 @@ } std::unique_ptr<MockDelegate> mock_delegate_; - std::unique_ptr<MockTetherDelegate> mock_tether_delegate_; base::test::ScopedTaskEnvironment scoped_task_environment_; ShillDeviceClient::TestInterface* device_test_; ShillServiceClient::TestInterface* service_test_; @@ -333,41 +320,4 @@ true); } -TEST_F(NetworkConnectTest, ConnectToTetherNetwork) { - EXPECT_CALL(*mock_tether_delegate_, ConnectToNetwork(kTether1Guid)); - - NetworkHandler::Get()->network_state_handler()->SetTetherTechnologyState( - NetworkStateHandler::TECHNOLOGY_ENABLED); - - NetworkHandler::Get()->network_state_handler()->AddTetherNetworkState( - kTether1Guid, "TetherNetwork", "Carrier", 100 /* battery_percentage */, - 100 /* signal_strength */); - - NetworkConnect::Get()->SetTetherDelegate(mock_tether_delegate_.get()); - NetworkConnect::Get()->ConnectToNetworkId(kTether1Guid); -} - -TEST_F(NetworkConnectTest, ConnectToTetherNetwork_TetherNetworkDoesNotExist) { - EXPECT_CALL(*mock_tether_delegate_, ConnectToNetwork(_)).Times(0); - - NetworkHandler::Get()->network_state_handler()->SetTetherTechnologyState( - NetworkStateHandler::TECHNOLOGY_ENABLED); - - NetworkConnect::Get()->SetTetherDelegate(mock_tether_delegate_.get()); - NetworkConnect::Get()->ConnectToNetworkId(kTether1Guid); -} - -TEST_F(NetworkConnectTest, ConnectToTetherNetwork_TetherDelegateNotSet) { - EXPECT_CALL(*mock_tether_delegate_, ConnectToNetwork(_)).Times(0); - - NetworkHandler::Get()->network_state_handler()->SetTetherTechnologyState( - NetworkStateHandler::TECHNOLOGY_ENABLED); - - NetworkHandler::Get()->network_state_handler()->AddTetherNetworkState( - kTether1Guid, "TetherNetwork", "Carrier", 100 /* battery_percentage */, - 100 /* signal_strength */); - - NetworkConnect::Get()->ConnectToNetworkId(kTether1Guid); -} - } // namespace chromeos
diff --git a/chromeos/network/network_connection_handler.cc b/chromeos/network/network_connection_handler.cc index 7f372d7..2542fd4 100644 --- a/chromeos/network/network_connection_handler.cc +++ b/chromeos/network/network_connection_handler.cc
@@ -118,8 +118,11 @@ const char NetworkConnectionHandler::kErrorUnmanagedNetwork[] = "unmanaged-network"; const char NetworkConnectionHandler::kErrorActivateFailed[] = "activate-failed"; -const char NetworkConnectionHandler::kEnabledOrDisabledWhenNotAvailable[] = +const char NetworkConnectionHandler::kErrorEnabledOrDisabledWhenNotAvailable[] = "not-available"; +const char + NetworkConnectionHandler::kErrorTetherConnectionAttemptWithNoDelegate[] = + "tether-with-no-delegate"; struct NetworkConnectionHandler::ConnectRequest { ConnectRequest(const std::string& service_path, @@ -149,8 +152,8 @@ network_state_handler_(NULL), configuration_handler_(NULL), logged_in_(false), - certificates_loaded_(false) { -} + certificates_loaded_(false), + tether_delegate_(nullptr) {} NetworkConnectionHandler::~NetworkConnectionHandler() { if (network_state_handler_) @@ -223,6 +226,19 @@ ConnectToQueuedNetwork(); } +void NetworkConnectionHandler::InitiateTetherNetworkConnection( + const std::string& tether_network_guid, + const base::Closure& success_callback, + const network_handler::ErrorCallback& error_callback) { + DCHECK(tether_delegate_); + tether_delegate_->ConnectToNetwork( + tether_network_guid, + base::Bind(&NetworkConnectionHandler::InvokeConnectSuccessCallback, + AsWeakPtr(), tether_network_guid, success_callback), + base::Bind(&NetworkConnectionHandler::InvokeConnectErrorCallback, + AsWeakPtr(), tether_network_guid, error_callback)); +} + void NetworkConnectionHandler::ConnectToNetwork( const std::string& service_path, const base::Closure& success_callback, @@ -272,6 +288,19 @@ return; } } + + if (NetworkTypePattern::Tether().MatchesType(network->type())) { + if (tether_delegate_) { + const std::string& tether_network_guid = network->guid(); + DCHECK(!tether_network_guid.empty()); + InitiateTetherNetworkConnection(tether_network_guid, success_callback, + error_callback); + } else { + InvokeConnectErrorCallback(service_path, error_callback, + kErrorTetherConnectionAttemptWithNoDelegate); + } + return; + } } // If the network does not have a profile path, specify the correct default @@ -346,6 +375,11 @@ return pending_requests_.size() > 0; } +void NetworkConnectionHandler::SetTetherDelegate( + TetherDelegate* tether_delegate) { + tether_delegate_ = tether_delegate; +} + void NetworkConnectionHandler::NetworkListChanged() { CheckAllPendingRequests(); }
diff --git a/chromeos/network/network_connection_handler.h b/chromeos/network/network_connection_handler.h index e7e86d47..edbda71 100644 --- a/chromeos/network/network_connection_handler.h +++ b/chromeos/network/network_connection_handler.h
@@ -81,7 +81,8 @@ // Configuration failed during the configure stage of the connect flow. static const char kErrorConfigureFailed[]; - // An unexpected DBus or Shill error occurred while connecting. + // An unexpected DBus, Shill, or Tether communication error occurred while + // connecting. static const char kErrorConnectFailed[]; // An unexpected DBus or Shill error occurred while disconnecting. @@ -103,7 +104,24 @@ static const char kErrorActivateFailed[]; // Network was enabled/disabled when it was not available. - static const char kEnabledOrDisabledWhenNotAvailable[]; + static const char kErrorEnabledOrDisabledWhenNotAvailable[]; + + // Connection to Tether network attempted when no tether delegate present. + static const char kErrorTetherConnectionAttemptWithNoDelegate[]; + + class CHROMEOS_EXPORT TetherDelegate { + public: + // Connects to the Tether network with GUID |tether_network_guid|. On + // success, invokes |success_callback|, and on failure, invokes + // |error_callback|, passing the relevant error code declared above. + virtual void ConnectToNetwork( + const std::string& tether_network_guid, + const base::Closure& success_callback, + const network_handler::StringResultCallback& error_callback) = 0; + + protected: + virtual ~TetherDelegate() {} + }; ~NetworkConnectionHandler() override; @@ -141,6 +159,10 @@ // Returns true if there are any pending connect requests. bool HasPendingConnectRequest(); + // Sets the TetherDelegate to handle Tether actions. |tether_delegate| is + // owned by the caller. + void SetTetherDelegate(TetherDelegate* tether_delegate); + // NetworkStateHandlerObserver void NetworkListChanged() override; void NetworkPropertiesUpdated(const NetworkState* network) override; @@ -152,14 +174,20 @@ void OnCertificatesLoaded(const net::CertificateList& cert_list, bool initial_load) override; + protected: + NetworkConnectionHandler(); + + void InitiateTetherNetworkConnection( + const std::string& tether_network_guid, + const base::Closure& success_callback, + const network_handler::ErrorCallback& error_callback); + private: friend class NetworkHandler; friend class NetworkConnectionHandlerTest; struct ConnectRequest; - NetworkConnectionHandler(); - void Init(NetworkStateHandler* network_state_handler, NetworkConfigurationHandler* network_configuration_handler, ManagedNetworkConfigurationHandler* @@ -257,6 +285,9 @@ bool certificates_loaded_; base::TimeTicks logged_in_time_; + // Delegate used to start a connection to a tether network. + TetherDelegate* tether_delegate_; + DISALLOW_COPY_AND_ASSIGN(NetworkConnectionHandler); };
diff --git a/chromeos/network/network_connection_handler_unittest.cc b/chromeos/network/network_connection_handler_unittest.cc index ffa99d9..30919f3 100644 --- a/chromeos/network/network_connection_handler_unittest.cc +++ b/chromeos/network/network_connection_handler_unittest.cc
@@ -39,7 +39,9 @@ namespace { -const char* kSuccessResult = "success"; +const char kSuccessResult[] = "success"; + +const char kTetherGuid[] = "tether-guid"; class TestNetworkConnectionObserver : public NetworkConnectionObserver { public: @@ -82,6 +84,34 @@ DISALLOW_COPY_AND_ASSIGN(TestNetworkConnectionObserver); }; +class FakeTetherDelegate : public NetworkConnectionHandler::TetherDelegate { + public: + FakeTetherDelegate() {} + ~FakeTetherDelegate() override {} + + void ConnectToNetwork( + const std::string& service_path, + const base::Closure& success_callback, + const network_handler::StringResultCallback& error_callback) override { + last_service_path_ = service_path; + last_success_callback_ = success_callback; + last_error_callback_ = error_callback; + } + + std::string& last_service_path() { return last_service_path_; } + + base::Closure& last_success_callback() { return last_success_callback_; } + + network_handler::StringResultCallback& last_error_callback() { + return last_error_callback_; + } + + private: + std::string last_service_path_; + base::Closure last_success_callback_; + network_handler::StringResultCallback last_error_callback_; +}; + } // namespace class NetworkConnectionHandlerTest : public NetworkStateTest { @@ -130,6 +160,8 @@ network_connection_observer_.get()); base::RunLoop().RunUntilIdle(); + + fake_tether_delegate_.reset(new FakeTetherDelegate()); } void TearDown() override { @@ -262,6 +294,7 @@ std::unique_ptr<net::NSSCertDatabaseChromeOS> test_nsscertdb_; base::MessageLoopForUI message_loop_; std::string result_; + std::unique_ptr<FakeTetherDelegate> fake_tether_delegate_; private: DISALLOW_COPY_AND_ASSIGN(NetworkConnectionHandlerTest); @@ -447,4 +480,61 @@ EXPECT_EQ(NetworkConnectionHandler::kErrorNotConnected, GetResultAndReset()); } +TEST_F(NetworkConnectionHandlerTest, ConnectToTetherNetwork_Success) { + network_state_handler()->SetTetherTechnologyState( + NetworkStateHandler::TECHNOLOGY_ENABLED); + network_state_handler()->AddTetherNetworkState( + kTetherGuid, "TetherNetwork", "Carrier", 100 /* battery_percentage */, + 100 /* signal_strength */); + network_connection_handler_->SetTetherDelegate(fake_tether_delegate_.get()); + + Connect(kTetherGuid /* service_path */); + + EXPECT_EQ(kTetherGuid, fake_tether_delegate_->last_service_path()); + fake_tether_delegate_->last_success_callback().Run(); + EXPECT_EQ(kSuccessResult, GetResultAndReset()); + EXPECT_TRUE(network_connection_observer_->GetRequested(kTetherGuid)); + EXPECT_EQ(kSuccessResult, + network_connection_observer_->GetResult(kTetherGuid)); +} + +TEST_F(NetworkConnectionHandlerTest, ConnectToTetherNetwork_Failure) { + network_state_handler()->SetTetherTechnologyState( + NetworkStateHandler::TECHNOLOGY_ENABLED); + network_state_handler()->AddTetherNetworkState( + kTetherGuid, "TetherNetwork", "Carrier", 100 /* battery_percentage */, + 100 /* signal_strength */); + network_connection_handler_->SetTetherDelegate(fake_tether_delegate_.get()); + + Connect(kTetherGuid /* service_path */); + + EXPECT_EQ(kTetherGuid, fake_tether_delegate_->last_service_path()); + fake_tether_delegate_->last_error_callback().Run( + NetworkConnectionHandler::kErrorConnectFailed); + EXPECT_EQ(NetworkConnectionHandler::kErrorConnectFailed, GetResultAndReset()); + EXPECT_TRUE(network_connection_observer_->GetRequested(kTetherGuid)); + EXPECT_EQ(NetworkConnectionHandler::kErrorConnectFailed, + network_connection_observer_->GetResult(kTetherGuid)); +} + +TEST_F(NetworkConnectionHandlerTest, ConnectToTetherNetwork_NoTetherDelegate) { + network_state_handler()->SetTetherTechnologyState( + NetworkStateHandler::TECHNOLOGY_ENABLED); + network_state_handler()->AddTetherNetworkState( + kTetherGuid, "TetherNetwork", "Carrier", 100 /* battery_percentage */, + 100 /* signal_strength */); + + // Do not set a tether delegate. + + Connect(kTetherGuid /* service_path */); + + EXPECT_EQ( + NetworkConnectionHandler::kErrorTetherConnectionAttemptWithNoDelegate, + GetResultAndReset()); + EXPECT_TRUE(network_connection_observer_->GetRequested(kTetherGuid)); + EXPECT_EQ( + NetworkConnectionHandler::kErrorTetherConnectionAttemptWithNoDelegate, + network_connection_observer_->GetResult(kTetherGuid)); +} + } // namespace chromeos
diff --git a/chromeos/network/network_handler_callbacks.h b/chromeos/network/network_handler_callbacks.h index 9401aac..83d5d3b 100644 --- a/chromeos/network/network_handler_callbacks.h +++ b/chromeos/network/network_handler_callbacks.h
@@ -36,8 +36,8 @@ void(const std::string& service_path, const base::DictionaryValue& dictionary)> DictionaryResultCallback; -typedef base::Callback< - void(const std::string& service_path)> StringResultCallback; +typedef base::Callback<void(const std::string& string_result)> + StringResultCallback; typedef base::Callback<void(const std::string& service_path, const std::string& guid)>
diff --git a/chromeos/network/network_state_handler.cc b/chromeos/network/network_state_handler.cc index f424c97..6aeacbe 100644 --- a/chromeos/network/network_state_handler.cc +++ b/chromeos/network/network_state_handler.cc
@@ -162,7 +162,8 @@ << "TECHNOLOGY_ENABLED or TECHNOLOGY_AVAILABLE."; network_handler::RunErrorCallback( error_callback, kTetherDevicePath, - NetworkConnectionHandler::kEnabledOrDisabledWhenNotAvailable, ""); + NetworkConnectionHandler::kErrorEnabledOrDisabledWhenNotAvailable, + ""); continue; }
diff --git a/components/error_page/common/localized_error.cc b/components/error_page/common/localized_error.cc index 32cb9e9..580d3d7 100644 --- a/components/error_page/common/localized_error.cc +++ b/components/error_page/common/localized_error.cc
@@ -1049,6 +1049,7 @@ if (!is_post && !reload_visible && !show_saved_copy_visible && !is_incognito && failed_url.is_valid() && failed_url.SchemeIsHTTPOrHTTPS() && + IsSuggested(options.suggestions, SUGGEST_OFFLINE_CHECKS) && offline_pages::IsOfflinePagesAsyncDownloadEnabled()) { std::unique_ptr<base::DictionaryValue> download_button = base::MakeUnique<base::DictionaryValue>();
diff --git a/components/feature_engagement_tracker/internal/feature_constants.cc b/components/feature_engagement_tracker/internal/feature_constants.cc index 570ff107..581600e 100644 --- a/components/feature_engagement_tracker/internal/feature_constants.cc +++ b/components/feature_engagement_tracker/internal/feature_constants.cc
@@ -11,7 +11,7 @@ const base::Feature kIPHDemoMode{"IPH_DemoMode", base::FEATURE_DISABLED_BY_DEFAULT}; -const base::Feature kIPHDummyFeature{"IPH_DummyFeature", - base::FEATURE_DISABLED_BY_DEFAULT}; +const base::Feature kIPHDownloadPageFeature{"IPH_DownloadPage", + base::FEATURE_DISABLED_BY_DEFAULT}; } // namespace feature_engagement_tracker
diff --git a/components/feature_engagement_tracker/internal/feature_list.cc b/components/feature_engagement_tracker/internal/feature_list.cc index ebdef0a0..1cedb6b 100644 --- a/components/feature_engagement_tracker/internal/feature_list.cc +++ b/components/feature_engagement_tracker/internal/feature_list.cc
@@ -11,7 +11,7 @@ namespace { -const base::Feature* kAllFeatures[] = {&kIPHDummyFeature}; +const base::Feature* kAllFeatures[] = {&kIPHDownloadPageFeature}; } // namespace
diff --git a/components/feature_engagement_tracker/public/BUILD.gn b/components/feature_engagement_tracker/public/BUILD.gn index 62a0f4ae..c69469b2 100644 --- a/components/feature_engagement_tracker/public/BUILD.gn +++ b/components/feature_engagement_tracker/public/BUILD.gn
@@ -26,6 +26,7 @@ if (is_android) { android_library("public_java") { java_files = [ + "android/java/src/org/chromium/components/feature_engagement_tracker/EventConstants.java", "android/java/src/org/chromium/components/feature_engagement_tracker/FeatureConstants.java", "android/java/src/org/chromium/components/feature_engagement_tracker/FeatureEngagementTracker.java", ]
diff --git a/components/feature_engagement_tracker/public/android/java/src/org/chromium/components/feature_engagement_tracker/EventConstants.java b/components/feature_engagement_tracker/public/android/java/src/org/chromium/components/feature_engagement_tracker/EventConstants.java new file mode 100644 index 0000000..6c54c7b --- /dev/null +++ b/components/feature_engagement_tracker/public/android/java/src/org/chromium/components/feature_engagement_tracker/EventConstants.java
@@ -0,0 +1,25 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.components.feature_engagement_tracker; + +/** + * EventConstants contains the String name of all in-product help events. + */ +public final class EventConstants { + /** + * The page load has failed and user has landed on an offline dino page. + */ + public static final String USER_HAS_SEEN_DINO = "user_has_seen_dino"; + + /** + * The user has started downloading a page. + */ + public static final String DOWNLOAD_PAGE_STARTED = "download_page_started"; + + /** + * Do not instantiate. + */ + private EventConstants() {} +}
diff --git a/components/feature_engagement_tracker/public/android/java/src/org/chromium/components/feature_engagement_tracker/FeatureConstants.java b/components/feature_engagement_tracker/public/android/java/src/org/chromium/components/feature_engagement_tracker/FeatureConstants.java index 7e01b25..cf1ab1a8 100644 --- a/components/feature_engagement_tracker/public/android/java/src/org/chromium/components/feature_engagement_tracker/FeatureConstants.java +++ b/components/feature_engagement_tracker/public/android/java/src/org/chromium/components/feature_engagement_tracker/FeatureConstants.java
@@ -9,7 +9,7 @@ * in //components/feature_engagement_tracker/public/feature_constants.h. */ public final class FeatureConstants { - public static final String DUMMY_FEATURE = "IPH_DummyFeature"; + public static final String DOWNLOAD_PAGE_FEATURE = "IPH_DownloadPage"; /** * Do not instantiate.
diff --git a/components/feature_engagement_tracker/public/feature_constants.h b/components/feature_engagement_tracker/public/feature_constants.h index c26608a..2bc24c5 100644 --- a/components/feature_engagement_tracker/public/feature_constants.h +++ b/components/feature_engagement_tracker/public/feature_constants.h
@@ -15,8 +15,7 @@ // All the features declared below should also be declared in the Java // version: org.chromium.components.feature_engagement_tracker.FeatureConstants. -// A dummy feature until real features start using the backend. -extern const base::Feature kIPHDummyFeature; +extern const base::Feature kIPHDownloadPageFeature; } // namespace feature_engagement_tracker
diff --git a/components/guest_view/browser/guest_view_base.cc b/components/guest_view/browser/guest_view_base.cc index 4a260c6..71747bd5 100644 --- a/components/guest_view/browser/guest_view_base.cc +++ b/components/guest_view/browser/guest_view_base.cc
@@ -445,26 +445,6 @@ Destroy(true); } -bool GuestViewBase::HandleFindForEmbedder( - int request_id, - const base::string16& search_text, - const blink::WebFindOptions& options) { - if (ShouldHandleFindRequestsForEmbedder()) { - web_contents()->Find(request_id, search_text, options); - return true; - } - return false; -} - -bool GuestViewBase::HandleStopFindingForEmbedder( - content::StopFindAction action) { - if (ShouldHandleFindRequestsForEmbedder()) { - web_contents()->StopFinding(action); - return true; - } - return false; -} - WebContents* GuestViewBase::GetOwnerWebContents() const { return owner_web_contents_; } @@ -570,10 +550,6 @@ callback.Run(); } -bool GuestViewBase::ShouldHandleFindRequestsForEmbedder() const { - return false; -} - int GuestViewBase::LogicalPixelsToPhysicalPixels(double logical_pixels) const { DCHECK(logical_pixels >= 0); double zoom_factor = GetEmbedderZoomFactor(); @@ -726,23 +702,6 @@ return false; } -void GuestViewBase::FindReply(WebContents* source, - int request_id, - int number_of_matches, - const gfx::Rect& selection_rect, - int active_match_ordinal, - bool final_update) { - if (ShouldHandleFindRequestsForEmbedder() && - attached() && embedder_web_contents()->GetDelegate()) { - embedder_web_contents()->GetDelegate()->FindReply(embedder_web_contents(), - request_id, - number_of_matches, - selection_rect, - active_match_ordinal, - final_update); - } -} - content::RenderWidgetHost* GuestViewBase::GetOwnerRenderWidgetHost() { // We assume guests live inside an owner RenderFrame but the RenderFrame may // not be cross-process. In case a type of guest should be allowed to be
diff --git a/components/guest_view/browser/guest_view_base.h b/components/guest_view/browser/guest_view_base.h index c900a11..5354d87 100644 --- a/components/guest_view/browser/guest_view_base.h +++ b/components/guest_view/browser/guest_view_base.h
@@ -222,12 +222,6 @@ const content::NativeWebKeyboardEvent& event) override; bool PreHandleGestureEvent(content::WebContents* source, const blink::WebGestureEvent& event) override; - void FindReply(content::WebContents* source, - int request_id, - int number_of_matches, - const gfx::Rect& selection_rect, - int active_match_ordinal, - bool final_update) override; // WebContentsObserver implementation. void DidFinishNavigation( @@ -296,11 +290,6 @@ // asynchronous setup. virtual void SignalWhenReady(const base::Closure& callback); - // Returns true if this guest should handle find requests for its - // embedder. This should generally be true for guests that make up the - // entirety of the embedder's content. - virtual bool ShouldHandleFindRequestsForEmbedder() const; - // This method is called immediately before suspended resource loads have been // resumed on attachment to an embedder. // @@ -345,10 +334,6 @@ void DidAttach(int guest_proxy_routing_id) final; void DidDetach() final; content::WebContents* GetOwnerWebContents() const final; - bool HandleFindForEmbedder(int request_id, - const base::string16& search_text, - const blink::WebFindOptions& options) final; - bool HandleStopFindingForEmbedder(content::StopFindAction action) final; void GuestSizeChanged(const gfx::Size& new_size) final; void SetGuestHost(content::GuestHost* guest_host) final; void WillAttach(content::WebContents* embedder_web_contents,
diff --git a/components/policy/resources/policy_templates.json b/components/policy/resources/policy_templates.json index cc7b3fc4..dd542b6 100644 --- a/components/policy/resources/policy_templates.json +++ b/components/policy/resources/policy_templates.json
@@ -143,9 +143,9 @@ # persistent IDs for all fields (but not for groups!) are needed. These are # specified by the 'id' keys of each policy. NEVER CHANGE EXISTING IDs, # because doing so would break the deployed wire format! -# For your editing convenience: highest ID currently used: 366 +# For your editing convenience: highest ID currently used: 367 # And don't forget to also update the EnterprisePolicies enum of -# histograms.xml (run tools/metrics/histograms/update_policies.py). +# histograms.xml (run 'python tools/metrics/histograms/update_policies.py'). # # Placeholders: # The following placeholder strings are automatically substituted: @@ -9478,6 +9478,26 @@ If this policy is set to a list of input method identifiers, the given input methods will be available on the sign-in screen. The first given input method will be preselected. While a user pod is focused on the sign-in screen, the user's last used input method will be available in addition to the input methods given by this policy. If this policy is not set, the input methods on the sign-in screen will be derived from the locale in which the sign-in screen is displayed. Values which are not valid input method identifiers will be ignored.''', }, + { + 'name': 'InstantTetheringAllowed', + 'type': 'main', + 'schema': { 'type': 'boolean' }, + 'supported_on': ['chrome_os:60-'], + 'features': { + 'dynamic_refresh': False, + 'per_profile': True, + }, + 'example_value': True, + 'default_for_enterprise_users': False, + 'id': 367, + 'caption': '''Allows Instant Tethering to be used.''', + 'tags': ['local-data-access', 'google-sharing'], + 'desc': '''If this setting is enabled, users will be allowed to use Instant Tethering, which allows their Google phone to share its mobile data with their device. + + If this setting is disabled, users will not be allowed to use Instant Tethering. + + If this policy is left not set, the default is not allowed for enterprise-managed users and allowed for non-managed users.''', + }, ], 'messages': { # Messages that are not associated to any policies.
diff --git a/components/wallpaper/wallpaper_color_calculator.cc b/components/wallpaper/wallpaper_color_calculator.cc index fdab3d8..499fdd5 100644 --- a/components/wallpaper/wallpaper_color_calculator.cc +++ b/components/wallpaper/wallpaper_color_calculator.cc
@@ -15,6 +15,40 @@ namespace wallpaper { +namespace { + +// The largest image size, in pixels, to synchronously calculate the prominent +// color. This is a simple heuristic optimization because extraction on images +// smaller than this should run very quickly, and offloading the task to another +// thread would actually take longer. +const int kMaxPixelsForSynchronousCalculation = 100; + +// Wrapper for color_utils::CalculateProminentColorOfBitmap() that records +// wallpaper specific metrics. +// +// NOTE: |image| is intentionally a copy to ensure it exists for the duration of +// the calculation. +SkColor CalculateWallpaperColor(const gfx::ImageSkia image, + color_utils::LumaRange luma, + color_utils::SaturationRange saturation) { + base::TimeTicks start_time = base::TimeTicks::Now(); + const SkColor prominent_color = color_utils::CalculateProminentColorOfBitmap( + *image.bitmap(), luma, saturation); + + UMA_HISTOGRAM_TIMES("Ash.Wallpaper.ColorExtraction.Durations", + base::TimeTicks::Now() - start_time); + UMA_HISTOGRAM_BOOLEAN("Ash.Wallpaper.ColorExtractionResult", + prominent_color != SK_ColorTRANSPARENT); + + return prominent_color; +} + +bool ShouldCalculateSync(const gfx::ImageSkia& image) { + return image.width() * image.height() <= kMaxPixelsForSynchronousCalculation; +} + +} // namespace + WallpaperColorCalculator::WallpaperColorCalculator( const gfx::ImageSkia& image, color_utils::LumaRange luma, @@ -39,15 +73,19 @@ } bool WallpaperColorCalculator::StartCalculation() { - start_calculation_time_ = base::Time::Now(); + if (ShouldCalculateSync(image_)) { + const SkColor prominent_color = + CalculateWallpaperColor(image_, luma_, saturation_); + NotifyCalculationComplete(prominent_color); + return true; + } image_.MakeThreadSafe(); if (base::PostTaskAndReplyWithResult( task_runner_.get(), FROM_HERE, - base::Bind(&color_utils::CalculateProminentColorOfBitmap, - *image_.bitmap(), luma_, saturation_), - base::Bind(&WallpaperColorCalculator::NotifyCalculationComplete, - weak_ptr_factory_.GetWeakPtr()))) { + base::Bind(&CalculateWallpaperColor, image_, luma_, saturation_), + base::Bind(&WallpaperColorCalculator::OnAsyncCalculationComplete, + weak_ptr_factory_.GetWeakPtr(), base::TimeTicks::Now()))) { return true; } @@ -63,14 +101,16 @@ task_runner_ = task_runner; } +void WallpaperColorCalculator::OnAsyncCalculationComplete( + base::TimeTicks async_start_time, + SkColor prominent_color) { + UMA_HISTOGRAM_TIMES("Ash.Wallpaper.ColorExtraction.UserDelay", + base::TimeTicks::Now() - async_start_time); + NotifyCalculationComplete(prominent_color); +} + void WallpaperColorCalculator::NotifyCalculationComplete( SkColor prominent_color) { - UMA_HISTOGRAM_MEDIUM_TIMES("Ash.Wallpaper.TimeSpentExtractingColors", - base::Time::Now() - start_calculation_time_); - - UMA_HISTOGRAM_BOOLEAN("Ash.Wallpaper.ColorExtractionResult", - prominent_color != SK_ColorTRANSPARENT); - prominent_color_ = prominent_color; for (auto& observer : observers_) observer.OnColorCalculationComplete();
diff --git a/components/wallpaper/wallpaper_color_calculator.h b/components/wallpaper/wallpaper_color_calculator.h index e282098d..c59c12e 100644 --- a/components/wallpaper/wallpaper_color_calculator.h +++ b/components/wallpaper/wallpaper_color_calculator.h
@@ -22,7 +22,7 @@ namespace wallpaper { class WallpaperColorCalculatorObserver; -// Asynchronously calculates colors based on a wallpaper image. +// Calculates colors based on a wallpaper image. class WALLPAPER_EXPORT WallpaperColorCalculator { public: // |image|, |luma| and |saturation| are the input parameters to the color @@ -38,7 +38,8 @@ void RemoveObserver(WallpaperColorCalculatorObserver* observer); // Initiates the calculation and returns false if the calculation fails to be - // initiated. Callers should be aware that this will make |image_| read-only. + // initiated. Observers may be notified synchronously or asynchronously. + // Callers should be aware that this will make |image_| read-only. bool StartCalculation() WARN_UNUSED_RESULT; SkColor prominent_color() const { return prominent_color_; } @@ -51,6 +52,11 @@ void SetTaskRunnerForTest(scoped_refptr<base::TaskRunner> task_runner); private: + // Handles asynchronous calculation results. |async_start_time| is used to + // record duration metrics. + void OnAsyncCalculationComplete(base::TimeTicks async_start_time, + SkColor prominent_color); + // Notifies observers that a color calulation has completed. Called on the // same thread that constructed |this|. void NotifyCalculationComplete(SkColor prominent_color); @@ -70,10 +76,6 @@ // The task runner to run the calculation on. scoped_refptr<base::TaskRunner> task_runner_; - // The time that StartCalculation() was last called. Used for recording - // timing metrics. - base::Time start_calculation_time_; - base::ObserverList<WallpaperColorCalculatorObserver> observers_; base::WeakPtrFactory<WallpaperColorCalculator> weak_ptr_factory_;
diff --git a/components/wallpaper/wallpaper_color_calculator_unittest.cc b/components/wallpaper/wallpaper_color_calculator_unittest.cc index 31268f7..938ec5e 100644 --- a/components/wallpaper/wallpaper_color_calculator_unittest.cc +++ b/components/wallpaper/wallpaper_color_calculator_unittest.cc
@@ -8,6 +8,7 @@ #include "base/macros.h" #include "base/memory/ptr_util.h" +#include "base/test/histogram_tester.h" #include "base/test/null_task_runner.h" #include "base/test/test_mock_time_task_runner.h" #include "base/threading/thread_task_runner_handle.h" @@ -27,6 +28,18 @@ const SkColor kDefaultColor = SK_ColorTRANSPARENT; +const SkColor kGray = SkColorSetRGB(10, 10, 10); + +const SkColor kVibrantGreen = SkColorSetRGB(25, 200, 25); + +// Image size that causes the WallpaperColorCalculator to synchronously extract +// the prominent color. +constexpr gfx::Size kSyncImageSize = gfx::Size(5, 5); + +// Image size that causes the WallpaperColorCalculator to asynchronously extract +// the prominent color. +constexpr gfx::Size kAsyncImageSize = gfx::Size(50, 50); + class TestWallpaperColorCalculatorObserver : public WallpaperColorCalculatorObserver { public: @@ -45,6 +58,24 @@ DISALLOW_COPY_AND_ASSIGN(TestWallpaperColorCalculatorObserver); }; +// Returns an image that will yield a color when processing it with +// color_utils::CalculateProminentColorOfBitmap() using the LumaRange::NORMAL +// and SaturationRange::VIBRANT values. +gfx::ImageSkia CreateColorProducingImage(const gfx::Size& size) { + gfx::Canvas canvas(size, 1.0f, true); + canvas.DrawColor(kGray); + canvas.FillRect(gfx::Rect(0, 1, size.height(), 1), kVibrantGreen); + return gfx::ImageSkia::CreateFrom1xBitmap(canvas.GetBitmap()); +} + +// Returns an image that will not yield a color when processing it with +// color_utils::CalculateProminentColorOfBitmap(). +gfx::ImageSkia CreateNonColorProducingImage(const gfx::Size& size) { + gfx::Canvas canvas(size, 1.0f, true); + canvas.DrawColor(kGray); + return gfx::ImageSkia::CreateFrom1xBitmap(canvas.GetBitmap()); +} + } // namespace class WallPaperColorCalculatorTest : public testing::Test { @@ -53,19 +84,26 @@ ~WallPaperColorCalculatorTest() override; protected: + // Installs the given |task_runner| globally and on the |calculator_| instance + // if it exists. void InstallTaskRunner( scoped_refptr<base::SingleThreadTaskRunner> task_runner); - gfx::ImageSkia image_; + // Creates a new |calculator_| for the given |image| and installs the current + // |task_runner_|. + void CreateCalculator(const gfx::ImageSkia& image); std::unique_ptr<WallpaperColorCalculator> calculator_; + // Required for asynchronous calculations. scoped_refptr<base::TestMockTimeTaskRunner> task_runner_; TestWallpaperColorCalculatorObserver observer_; + base::HistogramTester histograms_; + private: - // Required by PostTaskAndReplyImpl. + // Required for asynchronous calculations, e.g. by PostTaskAndReplyImpl. std::unique_ptr<base::ThreadTaskRunnerHandle> task_runner_handle_; DISALLOW_COPY_AND_ASSIGN(WallPaperColorCalculatorTest); @@ -73,22 +111,7 @@ WallPaperColorCalculatorTest::WallPaperColorCalculatorTest() : task_runner_(new base::TestMockTimeTaskRunner()) { - // Creates an |image_| that will yield a non-default prominent color. - const gfx::Size kImageSize(300, 200); - const SkColor kGray = SkColorSetRGB(10, 10, 10); - const SkColor kVibrantGreen = SkColorSetRGB(25, 200, 25); - - gfx::Canvas canvas(kImageSize, 1.0f, true); - canvas.FillRect(gfx::Rect(kImageSize), kGray); - canvas.FillRect(gfx::Rect(0, 1, 300, 1), kVibrantGreen); - - image_ = gfx::ImageSkia::CreateFrom1xBitmap(canvas.GetBitmap()); - - calculator_ = base::MakeUnique<WallpaperColorCalculator>( - image_, color_utils::LumaRange::NORMAL, - color_utils::SaturationRange::VIBRANT, nullptr); - calculator_->AddObserver(&observer_); - + CreateCalculator(CreateColorProducingImage(kAsyncImageSize)); InstallTaskRunner(task_runner_); } @@ -99,20 +122,55 @@ task_runner_handle_.reset(); task_runner_handle_ = base::MakeUnique<base::ThreadTaskRunnerHandle>(task_runner); - calculator_->SetTaskRunnerForTest(task_runner); + if (calculator_) + calculator_->SetTaskRunnerForTest(task_runner); } -TEST_F(WallPaperColorCalculatorTest, - StartCalculationReturnsFalseWhenPostingTaskFails) { +void WallPaperColorCalculatorTest::CreateCalculator( + const gfx::ImageSkia& image) { + calculator_ = base::MakeUnique<WallpaperColorCalculator>( + image, color_utils::LumaRange::NORMAL, + color_utils::SaturationRange::VIBRANT, task_runner_); + calculator_->AddObserver(&observer_); +} + +// Used to group the asynchronous calculation tests. +typedef WallPaperColorCalculatorTest WallPaperColorCalculatorAsyncTest; + +TEST_F(WallPaperColorCalculatorAsyncTest, MetricsForSuccessfulExtraction) { + histograms_.ExpectTotalCount("Ash.Wallpaper.ColorExtractionResult", 0); + histograms_.ExpectTotalCount("Ash.Wallpaper.ColorExtraction.Durations", 0); + histograms_.ExpectTotalCount("Ash.Wallpaper.ColorExtraction.UserDelay", 0); + + EXPECT_TRUE(calculator_->StartCalculation()); + task_runner_->RunUntilIdle(); + + histograms_.ExpectUniqueSample("Ash.Wallpaper.ColorExtractionResult", true, + 1); + histograms_.ExpectTotalCount("Ash.Wallpaper.ColorExtraction.Durations", 1); + histograms_.ExpectTotalCount("Ash.Wallpaper.ColorExtraction.UserDelay", 1); +} + +TEST_F(WallPaperColorCalculatorAsyncTest, MetricsWhenPostingTaskFails) { scoped_refptr<base::NullTaskRunner> task_runner = new base::NullTaskRunner(); InstallTaskRunner(task_runner); - calculator_->set_prominent_color_for_test(SK_ColorBLACK); + + histograms_.ExpectTotalCount("Ash.Wallpaper.ColorExtractionResult", 0); + histograms_.ExpectTotalCount("Ash.Wallpaper.ColorExtraction.Durations", 0); + histograms_.ExpectTotalCount("Ash.Wallpaper.ColorExtraction.UserDelay", 0); EXPECT_FALSE(calculator_->StartCalculation()); + task_runner_->RunUntilIdle(); + + histograms_.ExpectTotalCount("Ash.Wallpaper.ColorExtractionResult", 0); + histograms_.ExpectTotalCount("Ash.Wallpaper.ColorExtraction.Durations", 0); + histograms_.ExpectTotalCount("Ash.Wallpaper.ColorExtraction.UserDelay", 0); + EXPECT_EQ(kDefaultColor, calculator_->prominent_color()); } -TEST_F(WallPaperColorCalculatorTest, ObserverNotifiedOnSuccessfulCalculation) { +TEST_F(WallPaperColorCalculatorAsyncTest, + ObserverNotifiedOnSuccessfulCalculation) { EXPECT_FALSE(observer_.WasNotified()); EXPECT_TRUE(calculator_->StartCalculation()); @@ -122,7 +180,7 @@ EXPECT_TRUE(observer_.WasNotified()); } -TEST_F(WallPaperColorCalculatorTest, ColorUpdatedOnSuccessfulCalculation) { +TEST_F(WallPaperColorCalculatorAsyncTest, ColorUpdatedOnSuccessfulCalculation) { calculator_->set_prominent_color_for_test(kDefaultColor); EXPECT_TRUE(calculator_->StartCalculation()); @@ -132,7 +190,7 @@ EXPECT_NE(kDefaultColor, calculator_->prominent_color()); } -TEST_F(WallPaperColorCalculatorTest, +TEST_F(WallPaperColorCalculatorAsyncTest, NoCrashWhenCalculatorDestroyedBeforeTaskProcessing) { EXPECT_TRUE(calculator_->StartCalculation()); calculator_.reset(); @@ -144,4 +202,38 @@ EXPECT_FALSE(task_runner_->HasPendingTask()); } +// Used to group the synchronous calculation tests. +typedef WallPaperColorCalculatorTest WallPaperColorCalculatorSyncTest; + +TEST_F(WallPaperColorCalculatorSyncTest, MetricsForSuccessfulExtraction) { + CreateCalculator(CreateColorProducingImage(kSyncImageSize)); + calculator_->SetTaskRunnerForTest(nullptr); + + histograms_.ExpectTotalCount("Ash.Wallpaper.ColorExtractionResult", 0); + histograms_.ExpectTotalCount("Ash.Wallpaper.ColorExtraction.Durations", 0); + histograms_.ExpectTotalCount("Ash.Wallpaper.ColorExtraction.UserDelay", 0); + + EXPECT_TRUE(calculator_->StartCalculation()); + + histograms_.ExpectUniqueSample("Ash.Wallpaper.ColorExtractionResult", true, + 1); + histograms_.ExpectTotalCount("Ash.Wallpaper.ColorExtraction.Durations", 1); + histograms_.ExpectTotalCount("Ash.Wallpaper.ColorExtraction.UserDelay", 0); +} + +TEST_F(WallPaperColorCalculatorSyncTest, MetricsForFailedExctraction) { + CreateCalculator(CreateNonColorProducingImage(kSyncImageSize)); + + histograms_.ExpectTotalCount("Ash.Wallpaper.ColorExtractionResult", 0); + histograms_.ExpectTotalCount("Ash.Wallpaper.ColorExtraction.Durations", 0); + histograms_.ExpectTotalCount("Ash.Wallpaper.ColorExtraction.UserDelay", 0); + + EXPECT_TRUE(calculator_->StartCalculation()); + + histograms_.ExpectUniqueSample("Ash.Wallpaper.ColorExtractionResult", false, + 1); + histograms_.ExpectTotalCount("Ash.Wallpaper.ColorExtraction.Durations", 1); + histograms_.ExpectTotalCount("Ash.Wallpaper.ColorExtraction.UserDelay", 0); +} + } // namespace wallpaper
diff --git a/content/browser/browser_plugin/browser_plugin_embedder.cc b/content/browser/browser_plugin/browser_plugin_embedder.cc index fc54c87..6e0a3d4f 100644 --- a/content/browser/browser_plugin/browser_plugin_embedder.cc +++ b/content/browser/browser_plugin/browser_plugin_embedder.cc
@@ -13,7 +13,6 @@ #include "content/public/browser/browser_plugin_guest_manager.h" #include "content/public/browser/native_web_keyboard_event.h" #include "content/public/browser/render_view_host.h" -#include "third_party/WebKit/public/web/WebFindOptions.h" #include "ui/events/keycodes/keyboard_codes.h" namespace content { @@ -187,23 +186,6 @@ return event_consumed; } -bool BrowserPluginEmbedder::Find(int request_id, - const base::string16& search_text, - const blink::WebFindOptions& options) { - return GetBrowserPluginGuestManager()->ForEachGuest( - web_contents(), - base::Bind(&BrowserPluginEmbedder::FindInGuest, - request_id, - search_text, - options)); -} - -bool BrowserPluginEmbedder::StopFinding(StopFindAction action) { - return GetBrowserPluginGuestManager()->ForEachGuest( - web_contents(), - base::Bind(&BrowserPluginEmbedder::StopFindingInGuest, action)); -} - BrowserPluginGuest* BrowserPluginEmbedder::GetFullPageGuest() { WebContentsImpl* guest_contents = static_cast<WebContentsImpl*>( GetBrowserPluginGuestManager()->GetFullPageGuest(web_contents())); @@ -235,32 +217,4 @@ return false; } -// static -bool BrowserPluginEmbedder::FindInGuest(int request_id, - const base::string16& search_text, - const blink::WebFindOptions& options, - WebContents* guest) { - if (static_cast<WebContentsImpl*>(guest) - ->GetBrowserPluginGuest() - ->HandleFindForEmbedder(request_id, search_text, options)) { - // There can only ever currently be one browser plugin that handles find so - // we can break the iteration at this point. - return true; - } - return false; -} - -// static -bool BrowserPluginEmbedder::StopFindingInGuest(StopFindAction action, - WebContents* guest) { - if (static_cast<WebContentsImpl*>(guest) - ->GetBrowserPluginGuest() - ->HandleStopFindingForEmbedder(action)) { - // There can only ever currently be one browser plugin that handles find so - // we can break the iteration at this point. - return true; - } - return false; -} - } // namespace content
diff --git a/content/browser/browser_plugin/browser_plugin_embedder.h b/content/browser/browser_plugin/browser_plugin_embedder.h index 5e4026c..68d02bc 100644 --- a/content/browser/browser_plugin/browser_plugin_embedder.h +++ b/content/browser/browser_plugin/browser_plugin_embedder.h
@@ -74,13 +74,6 @@ // Used to handle special keyboard events. bool HandleKeyboardEvent(const NativeWebKeyboardEvent& event); - // Find the given |search_text| in the page. Returns true if the find request - // is handled by this browser plugin embedder. - bool Find(int request_id, - const base::string16& search_text, - const blink::WebFindOptions& options); - bool StopFinding(StopFindAction action); - // Returns the "full page" guest if there is one. That is, if there is a // single BrowserPlugin in the embedder which takes up the full page, then it // is returned. @@ -108,12 +101,6 @@ static bool UnlockMouseIfNecessaryCallback(bool* mouse_unlocked, WebContents* guest); - static bool FindInGuest(int request_id, - const base::string16& search_text, - const blink::WebFindOptions& options, - WebContents* guest); - static bool StopFindingInGuest(StopFindAction action, WebContents* guest); - static bool GuestRecentlyAudibleCallback(WebContents* guest); // Message handlers.
diff --git a/content/browser/browser_plugin/browser_plugin_guest.cc b/content/browser/browser_plugin/browser_plugin_guest.cc index e6baddc7..cdc1381a 100644 --- a/content/browser/browser_plugin/browser_plugin_guest.cc +++ b/content/browser/browser_plugin/browser_plugin_guest.cc
@@ -147,6 +147,8 @@ // create a RenderFrameProxyHost for the reverse path, or implement // MimeHandlerViewGuest using OOPIF (https://crbug.com/659750). SiteInstance* owner_site_instance = delegate_->GetOwnerSiteInstance(); + if (!owner_site_instance) + return MSG_ROUTING_NONE; int proxy_routing_id = GetWebContents() ->GetFrameTree() ->root() @@ -178,8 +180,12 @@ void BrowserPluginGuest::WillDestroy() { is_in_destruction_ = true; - owner_web_contents_ = nullptr; + + // It is important that the WebContents is notified before detaching. + GetWebContents()->BrowserPluginGuestWillDetach(); + attached_ = false; + owner_web_contents_ = nullptr; } RenderWidgetHostImpl* BrowserPluginGuest::GetOwnerRenderWidgetHost() const { @@ -430,17 +436,6 @@ GetSurfaceManager()->RequireSequence(id, sequence); } -bool BrowserPluginGuest::HandleFindForEmbedder( - int request_id, - const base::string16& search_text, - const blink::WebFindOptions& options) { - return delegate_->HandleFindForEmbedder(request_id, search_text, options); -} - -bool BrowserPluginGuest::HandleStopFindingForEmbedder(StopFindAction action) { - return delegate_->HandleStopFindingForEmbedder(action); -} - void BrowserPluginGuest::ResendEventToEmbedder( const blink::WebInputEvent& event) { if (!attached() || !owner_web_contents_) @@ -823,6 +818,9 @@ if (!attached()) return; + // It is important that the WebContents is notified before detaching. + GetWebContents()->BrowserPluginGuestWillDetach(); + // This tells BrowserPluginGuest to queue up all IPCs to BrowserPlugin until // it's attached again. attached_ = false;
diff --git a/content/browser/browser_plugin/browser_plugin_guest.h b/content/browser/browser_plugin/browser_plugin_guest.h index fedd4a7..b204278 100644 --- a/content/browser/browser_plugin/browser_plugin_guest.h +++ b/content/browser/browser_plugin/browser_plugin_guest.h
@@ -241,13 +241,6 @@ virtual void SetChildFrameSurface(const cc::SurfaceInfo& surface_info, const cc::SurfaceSequence& sequence); - // Find the given |search_text| in the page. Returns true if the find request - // is handled by this browser plugin guest. - bool HandleFindForEmbedder(int request_id, - const base::string16& search_text, - const blink::WebFindOptions& options); - bool HandleStopFindingForEmbedder(StopFindAction action); - void ResendEventToEmbedder(const blink::WebInputEvent& event); // TODO(ekaramad): Remove this once https://crbug.com/642826 is resolved.
diff --git a/content/browser/find_request_manager.cc b/content/browser/find_request_manager.cc index a9bf7f53..de2783c 100644 --- a/content/browser/find_request_manager.cc +++ b/content/browser/find_request_manager.cc
@@ -4,19 +4,70 @@ #include "content/browser/find_request_manager.h" +#include <algorithm> + #include "content/browser/frame_host/render_frame_host_impl.h" #include "content/browser/web_contents/web_contents_impl.h" #include "content/common/frame_messages.h" #include "content/common/input_messages.h" +#include "content/public/browser/guest_mode.h" namespace content { namespace { +// The following functions allow traversal over all frames, including those +// across WebContentses. +// +// Note that there are currently two different ways in which an inner +// WebContents may be embedded in an outer WebContents: +// +// 1) As a guest of the outer WebContents's BrowserPluginEmbedder. +// 2) Within an inner WebContentsTreeNode of the outer WebContents's +// WebContentsTreeNode. + +// Returns all child frames of |node|. +std::vector<FrameTreeNode*> GetChildren(FrameTreeNode* node) { + std::vector<FrameTreeNode*> children(node->child_count()); + for (size_t i = 0; i != node->child_count(); ++i) + children[i] = node->child_at(i); + + if (auto* inner_contents = WebContentsImpl::FromOuterFrameTreeNode(node)) { + children.push_back(inner_contents->GetMainFrame()->frame_tree_node()); + } else { + auto* contents = WebContentsImpl::FromFrameTreeNode(node); + if (node->IsMainFrame() && contents->GetBrowserPluginEmbedder()) { + for (auto* inner_contents : contents->GetInnerWebContents()) { + children.push_back(inner_contents->GetMainFrame()->frame_tree_node()); + } + } + } + + return children; +} + +// Returns the first child FrameTreeNode under |node|, if |node| has a child, or +// nullptr otherwise. +FrameTreeNode* GetFirstChild(FrameTreeNode* node) { + auto children = GetChildren(node); + if (!children.empty()) + return children.front(); + return nullptr; +} + +// Returns the last child FrameTreeNode under |node|, if |node| has a child, or +// nullptr otherwise. +FrameTreeNode* GetLastChild(FrameTreeNode* node) { + auto children = GetChildren(node); + if (!children.empty()) + return children.back(); + return nullptr; +} + // Returns the deepest last child frame under |node|/|rfh| in the frame tree. FrameTreeNode* GetDeepestLastChild(FrameTreeNode* node) { - while (node->child_count()) - node = node->child_at(node->child_count() - 1); + while (FrameTreeNode* last_child = GetLastChild(node)) + node = last_child; return node; } RenderFrameHost* GetDeepestLastChild(RenderFrameHost* rfh) { @@ -25,20 +76,82 @@ return GetDeepestLastChild(node)->current_frame_host(); } +// Returns the parent FrameTreeNode of |node|, if |node| has a parent, or +// nullptr otherwise. +FrameTreeNode* GetParent(FrameTreeNode* node) { + if (node->parent()) + return node->parent(); + + // The parent frame may be in another WebContents. + if (node->IsMainFrame()) { + auto* contents = WebContentsImpl::FromFrameTreeNode(node); + if (GuestMode::IsCrossProcessFrameGuest(contents)) { + int node_id = contents->GetOuterDelegateFrameTreeNodeId(); + if (node_id != FrameTreeNode::kFrameTreeNodeInvalidId) + return FrameTreeNode::GloballyFindByID(node_id); + } else if (auto* outer_contents = contents->GetOuterWebContents()) { + return outer_contents->GetMainFrame()->frame_tree_node(); + } + } + + return nullptr; +} + +// Returns the previous sibling FrameTreeNode of |node|, if one exists, or +// nullptr otherwise. +FrameTreeNode* GetPreviousSibling(FrameTreeNode* node) { + if (FrameTreeNode* previous_sibling = node->PreviousSibling()) + return previous_sibling; + + // The previous sibling may be in another WebContents. + if (FrameTreeNode* parent = GetParent(node)) { + auto children = GetChildren(parent); + auto it = std::find(children.begin(), children.end(), node); + // It is odd that this node may not be a child of its parent, but this is + // actually possible during teardown, hence the need for the check for + // "it != children.end()". + if (it != children.end() && it != children.begin()) + return *--it; + } + + return nullptr; +} + +// Returns the next sibling FrameTreeNode of |node|, if one exists, or nullptr +// otherwise. +FrameTreeNode* GetNextSibling(FrameTreeNode* node) { + if (FrameTreeNode* next_sibling = node->NextSibling()) + return next_sibling; + + // The next sibling may be in another WebContents. + if (FrameTreeNode* parent = GetParent(node)) { + auto children = GetChildren(parent); + auto it = std::find(children.begin(), children.end(), node); + // It is odd that this node may not be a child of its parent, but this is + // actually possible during teardown, hence the need for the check for + // "it != children.end()". + if (it != children.end() && ++it != children.end()) + return *it; + } + + return nullptr; +} + // Returns the FrameTreeNode directly after |node| in the frame tree in search // order, or nullptr if one does not exist. If |wrap| is set, then wrapping // between the first and last frames is permitted. Note that this traversal // follows the same ordering as in blink::FrameTree::traverseNextWithWrap(). FrameTreeNode* TraverseNext(FrameTreeNode* node, bool wrap) { - if (node->child_count()) - return node->child_at(0); + if (FrameTreeNode* first_child = GetFirstChild(node)) + return first_child; - FrameTreeNode* sibling = node->NextSibling(); + FrameTreeNode* sibling = GetNextSibling(node); while (!sibling) { - if (!node->parent()) + FrameTreeNode* parent = GetParent(node); + if (!parent) return wrap ? node : nullptr; - node = node->parent(); - sibling = node->NextSibling(); + node = parent; + sibling = GetNextSibling(node); } return sibling; } @@ -48,14 +161,14 @@ // between the first and last frames is permitted. Note that this traversal // follows the same ordering as in blink::FrameTree::traversePreviousWithWrap(). FrameTreeNode* TraversePrevious(FrameTreeNode* node, bool wrap) { - if (FrameTreeNode* previous_sibling = node->PreviousSibling()) + if (FrameTreeNode* previous_sibling = GetPreviousSibling(node)) return GetDeepestLastChild(previous_sibling); - if (node->parent()) - return node->parent(); + if (FrameTreeNode* parent = GetParent(node)) + return parent; return wrap ? GetDeepestLastChild(node) : nullptr; } -// The same as either TraverseNext() or TraversePrevious() depending on +// The same as either TraverseNext() or TraversePrevious(), depending on // |forward|. FrameTreeNode* TraverseNode(FrameTreeNode* node, bool forward, bool wrap) { return forward ? TraverseNext(node, wrap) : TraversePrevious(node, wrap); @@ -63,6 +176,43 @@ } // namespace +// Observes searched WebContentses for frame changes, including deletion, +// creation, and navigation. +class FindRequestManager::FrameObserver : public WebContentsObserver { + public: + FrameObserver(WebContentsImpl* web_contents, FindRequestManager* manager) + : WebContentsObserver(web_contents), manager_(manager) {} + + ~FrameObserver() override {} + + void DidFinishLoad(RenderFrameHost* rfh, const GURL& validated_url) override { + if (manager_->current_session_id_ == kInvalidId) + return; + + manager_->RemoveFrame(rfh); + manager_->AddFrame(rfh, true /* force */); + } + + void RenderFrameDeleted(RenderFrameHost* rfh) override { + manager_->RemoveFrame(rfh); + } + + void RenderFrameHostChanged(RenderFrameHost* old_host, + RenderFrameHost* new_host) override { + manager_->RemoveFrame(old_host); + } + + void FrameDeleted(RenderFrameHost* rfh) override { + manager_->RemoveFrame(rfh); + } + + private: + // The FindRequestManager that owns this FrameObserver. + FindRequestManager* const manager_; + + DISALLOW_COPY_AND_ASSIGN(FrameObserver); +}; + #if defined(OS_ANDROID) FindRequestManager::ActivateNearestFindResultState:: ActivateNearestFindResultState() = default; @@ -88,8 +238,7 @@ const int FindRequestManager::kInvalidId = -1; FindRequestManager::FindRequestManager(WebContentsImpl* web_contents) - : WebContentsObserver(web_contents), - contents_(web_contents), + : contents_(web_contents), current_session_id_(kInvalidId), pending_find_next_reply_(nullptr), pending_active_match_ordinal_(false), @@ -120,8 +269,10 @@ } void FindRequestManager::StopFinding(StopFindAction action) { - contents_->SendToAllFrames( - new FrameMsg_StopFinding(MSG_ROUTING_NONE, action)); + for (WebContentsImpl* contents : contents_->GetWebContentsAndAllInner()) { + contents->SendToAllFrames( + new FrameMsg_StopFinding(MSG_ROUTING_NONE, action)); + } current_session_id_ = kInvalidId; #if defined(OS_ANDROID) @@ -293,16 +444,18 @@ // Request from each frame the distance to the nearest find result (in that // frame) from the point (x, y), defined in find-in-page coordinates. - for (FrameTreeNode* node : contents_->GetFrameTree()->Nodes()) { - RenderFrameHost* rfh = node->current_frame_host(); + for (WebContentsImpl* contents : contents_->GetWebContentsAndAllInner()) { + for (FrameTreeNode* node : contents->GetFrameTree()->Nodes()) { + RenderFrameHost* rfh = node->current_frame_host(); - if (!CheckFrame(rfh) || !rfh->IsRenderFrameLive()) - continue; + if (!CheckFrame(rfh) || !rfh->IsRenderFrameLive()) + continue; - activate_.pending_replies.insert(rfh); - rfh->Send(new FrameMsg_GetNearestFindResult( - rfh->GetRoutingID(), activate_.current_request_id, - activate_.x, activate_.y)); + activate_.pending_replies.insert(rfh); + rfh->Send(new FrameMsg_GetNearestFindResult(rfh->GetRoutingID(), + activate_.current_request_id, + activate_.x, activate_.y)); + } } } @@ -328,17 +481,19 @@ match_rects_.request_version = current_version; // Request the latest find match rects from each frame. - for (FrameTreeNode* node : contents_->GetFrameTree()->Nodes()) { - RenderFrameHost* rfh = node->current_frame_host(); + for (WebContentsImpl* contents : contents_->GetWebContentsAndAllInner()) { + for (FrameTreeNode* node : contents->GetFrameTree()->Nodes()) { + RenderFrameHost* rfh = node->current_frame_host(); - if (!CheckFrame(rfh) || !rfh->IsRenderFrameLive()) - continue; + if (!CheckFrame(rfh) || !rfh->IsRenderFrameLive()) + continue; - match_rects_.pending_replies.insert(rfh); - auto it = match_rects_.frame_rects.find(rfh); - int version = (it != match_rects_.frame_rects.end()) - ? it->second.version : kInvalidId; - rfh->Send(new FrameMsg_FindMatchRects(rfh->GetRoutingID(), version)); + match_rects_.pending_replies.insert(rfh); + auto it = match_rects_.frame_rects.find(rfh); + int version = (it != match_rects_.frame_rects.end()) ? it->second.version + : kInvalidId; + rfh->Send(new FrameMsg_FindMatchRects(rfh->GetRoutingID(), version)); + } } } @@ -359,28 +514,6 @@ } #endif -void FindRequestManager::DidFinishLoad(RenderFrameHost* rfh, - const GURL& validated_url) { - if (current_session_id_ == kInvalidId) - return; - - RemoveFrame(rfh); - AddFrame(rfh, true /* force */); -} - -void FindRequestManager::RenderFrameDeleted(RenderFrameHost* rfh) { - RemoveFrame(rfh); -} - -void FindRequestManager::RenderFrameHostChanged(RenderFrameHost* old_host, - RenderFrameHost* new_host) { - RemoveFrame(old_host); -} - -void FindRequestManager::FrameDeleted(RenderFrameHost* rfh) { - RemoveFrame(rfh); -} - void FindRequestManager::Reset(const FindRequest& initial_request) { current_session_id_ = initial_request.id; current_request_ = initial_request; @@ -394,6 +527,7 @@ active_match_ordinal_ = 0; selection_rect_ = gfx::Rect(); last_reported_id_ = kInvalidId; + frame_observers_.clear(); #if defined(OS_ANDROID) activate_ = ActivateNearestFindResultState(); match_rects_.pending_replies.clear(); @@ -414,7 +548,8 @@ // The find next request will be directed at the focused frame if there is // one, or the first frame with matches otherwise. - RenderFrameHost* target_rfh = contents_->GetFocusedFrame(); + RenderFrameHost* target_rfh = + contents_->GetFocusedWebContents()->GetFocusedFrame(); if (!target_rfh || !CheckFrame(target_rfh)) target_rfh = GetInitialFrame(request.options.forward); @@ -426,8 +561,12 @@ // This is an initial find operation. Reset(request); - for (FrameTreeNode* node : contents_->GetFrameTree()->Nodes()) - AddFrame(node->current_frame_host(), false /* force */); + for (WebContentsImpl* contents : contents_->GetWebContentsAndAllInner()) { + frame_observers_.push_back(base::MakeUnique<FrameObserver>(contents, this)); + for (FrameTreeNode* node : contents->GetFrameTree()->Nodes()) { + AddFrame(node->current_frame_host(), false /* force */); + } + } } void FindRequestManager::AdvanceQueue(int request_id) { @@ -485,6 +624,7 @@ bool forward, bool matches_only, bool wrap) const { + DCHECK(from_rfh); FrameTreeNode* node = static_cast<RenderFrameHostImpl*>(from_rfh)->frame_tree_node(); @@ -572,7 +712,9 @@ current_request_.options.forward, true /* matches_only */, true /* wrap */); - } else if ((target_rfh = contents_->GetFocusedFrame()) != nullptr) { + } else if ((target_rfh = + contents_->GetFocusedWebContents()->GetFocusedFrame()) != + nullptr) { // Otherwise, if there is a focused frame, then the active match will be in // the next frame with matches after that one. target_rfh = Traverse(target_rfh,
diff --git a/content/browser/find_request_manager.h b/content/browser/find_request_manager.h index 5a6b3988..245ab69 100644 --- a/content/browser/find_request_manager.h +++ b/content/browser/find_request_manager.h
@@ -27,11 +27,12 @@ // initiated/received through a WebContents. It coordinates searching across // multiple (potentially out-of-process) frames, handles the aggregation of find // results from each frame, and facilitates active match traversal. It is -// instantiated once per WebContents, and is owned by that WebContents. -class CONTENT_EXPORT FindRequestManager : public WebContentsObserver { +// instantiated once per top-level WebContents, and is owned by that +// WebContents. +class CONTENT_EXPORT FindRequestManager { public: explicit FindRequestManager(WebContentsImpl* web_contents); - ~FindRequestManager() override; + ~FindRequestManager(); // Initiates a find operation for |search_text| with the options specified in // |options|. |request_id| uniquely identifies the find request. @@ -84,6 +85,8 @@ // frame ID, find request ID, or find match rects version number. static const int kInvalidId; + class FrameObserver; + // The request data for a single find request. struct FindRequest { // The find request ID that uniquely identifies this find request. @@ -102,13 +105,6 @@ : id(id), search_text(search_text), options(options) {} }; - // WebContentsObserver implementation. - void DidFinishLoad(RenderFrameHost* rfh, const GURL& validated_url) override; - void RenderFrameDeleted(RenderFrameHost* rfh) override; - void RenderFrameHostChanged(RenderFrameHost* old_host, - RenderFrameHost* new_host) override; - void FrameDeleted(RenderFrameHost* rfh) override; - // Resets all of the per-session state for a new find-in-page session. void Reset(const FindRequest& initial_request); @@ -248,7 +244,9 @@ } match_rects_; #endif - // The WebContents that owns this FindRequestManager. + // The WebContents that owns this FindRequestManager. This also defines the + // scope of all find sessions. Only frames in |contents_| and any inner + // WebContentses within it will be searched. WebContentsImpl* const contents_; // The request ID of the initial find request in the current find-in-page @@ -306,6 +304,12 @@ // Keeps track of the find request ID of the last find reply reported via // NotifyFindReply(). int last_reported_id_; + + // WebContentsObservers to observe frame changes in |contents_| and its inner + // WebContentses. + std::vector<std::unique_ptr<FrameObserver>> frame_observers_; + + DISALLOW_COPY_AND_ASSIGN(FindRequestManager); }; } // namespace content
diff --git a/content/browser/indexed_db/indexed_db_database.cc b/content/browser/indexed_db/indexed_db_database.cc index 19b79ce..8f4367c 100644 --- a/content/browser/indexed_db/indexed_db_database.cc +++ b/content/browser/indexed_db/indexed_db_database.cc
@@ -100,6 +100,9 @@ // Called when the upgrade transaction has finished. virtual void UpgradeTransactionFinished(bool committed) = 0; + // Called for pending tasks that we need to clear for a force close. + virtual void AbortForForceClose() = 0; + protected: scoped_refptr<IndexedDBDatabase> db_; @@ -269,6 +272,12 @@ db_->RequestComplete(this); } + void AbortForForceClose() override { + DCHECK(!connection_); + pending_->database_callbacks->OnForcedClose(); + pending_.reset(); + } + private: std::unique_ptr<IndexedDBPendingConnection> pending_; @@ -344,6 +353,13 @@ void UpgradeTransactionFinished(bool committed) override { NOTREACHED(); } + void AbortForForceClose() override { + IndexedDBDatabaseError error(blink::kWebIDBDatabaseExceptionUnknownError, + "The request could not be completed."); + callbacks_->OnError(error); + callbacks_ = nullptr; + } + private: scoped_refptr<IndexedDBCallbacks> callbacks_; @@ -802,6 +818,12 @@ transaction->AddPendingObserver(observer_id, options); } +void IndexedDBDatabase::CallUpgradeTransactionStartedForTesting( + int64_t old_version) { + DCHECK(active_request_); + active_request_->UpgradeTransactionStarted(old_version); +} + void IndexedDBDatabase::FilterObservation(IndexedDBTransaction* transaction, int64_t object_store_id, blink::WebIDBOperationType type, @@ -1846,12 +1868,21 @@ void IndexedDBDatabase::ForceClose() { // IndexedDBConnection::ForceClose() may delete this database, so hold ref. scoped_refptr<IndexedDBDatabase> protect(this); + + while (!pending_requests_.empty()) { + std::unique_ptr<ConnectionRequest> request = + std::move(pending_requests_.front()); + pending_requests_.pop(); + request->AbortForForceClose(); + } + auto it = connections_.begin(); while (it != connections_.end()) { IndexedDBConnection* connection = *it++; connection->ForceClose(); } DCHECK(connections_.empty()); + DCHECK(!active_request_); } void IndexedDBDatabase::VersionChangeIgnored() {
diff --git a/content/browser/indexed_db/indexed_db_database.h b/content/browser/indexed_db/indexed_db_database.h index 73478a42..1203e8b 100644 --- a/content/browser/indexed_db/indexed_db_database.h +++ b/content/browser/indexed_db/indexed_db_database.h
@@ -17,6 +17,7 @@ #include <utility> #include <vector> +#include "base/gtest_prod_util.h" #include "base/macros.h" #include "base/memory/ref_counted.h" #include "content/browser/indexed_db/indexed_db.h" @@ -290,6 +291,10 @@ friend class base::RefCounted<IndexedDBDatabase>; friend class IndexedDBClassFactory; + FRIEND_TEST_ALL_PREFIXES(IndexedDBDatabaseTest, OpenDeleteClear); + + void CallUpgradeTransactionStartedForTesting(int64_t old_version); + class ConnectionRequest; class OpenRequest; class DeleteRequest;
diff --git a/content/browser/indexed_db/indexed_db_database_unittest.cc b/content/browser/indexed_db/indexed_db_database_unittest.cc index d1cfeb9..de1db36 100644 --- a/content/browser/indexed_db/indexed_db_database_unittest.cc +++ b/content/browser/indexed_db/indexed_db_database_unittest.cc
@@ -40,41 +40,35 @@ namespace content { class IndexedDBDatabaseTest : public ::testing::Test { + public: + void SetUp() override { + backing_store_ = new IndexedDBFakeBackingStore(); + factory_ = new MockIndexedDBFactory(); + EXPECT_TRUE(backing_store_->HasOneRef()); + leveldb::Status s; + std::tie(db_, s) = IndexedDBDatabase::Create( + ASCIIToUTF16("db"), backing_store_.get(), factory_.get(), + IndexedDBDatabase::Identifier()); + ASSERT_TRUE(s.ok()); + EXPECT_FALSE(backing_store_->HasOneRef()); // local and db + } + + protected: + scoped_refptr<IndexedDBFakeBackingStore> backing_store_; + scoped_refptr<MockIndexedDBFactory> factory_; + scoped_refptr<IndexedDBDatabase> db_; + private: TestBrowserThreadBundle thread_bundle_; }; TEST_F(IndexedDBDatabaseTest, BackingStoreRetention) { - scoped_refptr<IndexedDBFakeBackingStore> backing_store = - new IndexedDBFakeBackingStore(); - EXPECT_TRUE(backing_store->HasOneRef()); - - scoped_refptr<MockIndexedDBFactory> factory = new MockIndexedDBFactory(); - scoped_refptr<IndexedDBDatabase> db; - leveldb::Status s; - std::tie(db, s) = - IndexedDBDatabase::Create(ASCIIToUTF16("db"), backing_store.get(), - factory.get(), IndexedDBDatabase::Identifier()); - ASSERT_TRUE(s.ok()); - EXPECT_FALSE(backing_store->HasOneRef()); // local and db - db = NULL; - EXPECT_TRUE(backing_store->HasOneRef()); // local + EXPECT_FALSE(backing_store_->HasOneRef()); // local and db + db_ = NULL; + EXPECT_TRUE(backing_store_->HasOneRef()); // local } TEST_F(IndexedDBDatabaseTest, ConnectionLifecycle) { - scoped_refptr<IndexedDBFakeBackingStore> backing_store = - new IndexedDBFakeBackingStore(); - EXPECT_TRUE(backing_store->HasOneRef()); // local - - scoped_refptr<MockIndexedDBFactory> factory = new MockIndexedDBFactory(); - scoped_refptr<IndexedDBDatabase> db; - leveldb::Status s; - std::tie(db, s) = - IndexedDBDatabase::Create(ASCIIToUTF16("db"), backing_store.get(), - factory.get(), IndexedDBDatabase::Identifier()); - ASSERT_TRUE(s.ok()); - EXPECT_FALSE(backing_store->HasOneRef()); // local and db - scoped_refptr<MockIndexedDBCallbacks> request1(new MockIndexedDBCallbacks()); scoped_refptr<MockIndexedDBDatabaseCallbacks> callbacks1( new MockIndexedDBDatabaseCallbacks()); @@ -83,9 +77,9 @@ base::MakeUnique<IndexedDBPendingConnection>( request1, callbacks1, kFakeChildProcessId, transaction_id1, IndexedDBDatabaseMetadata::DEFAULT_VERSION)); - db->OpenConnection(std::move(connection1)); + db_->OpenConnection(std::move(connection1)); - EXPECT_FALSE(backing_store->HasOneRef()); // db, connection count > 0 + EXPECT_FALSE(backing_store_->HasOneRef()); // db, connection count > 0 scoped_refptr<MockIndexedDBCallbacks> request2(new MockIndexedDBCallbacks()); scoped_refptr<MockIndexedDBDatabaseCallbacks> callbacks2( @@ -95,38 +89,25 @@ base::MakeUnique<IndexedDBPendingConnection>( request2, callbacks2, kFakeChildProcessId, transaction_id2, IndexedDBDatabaseMetadata::DEFAULT_VERSION)); - db->OpenConnection(std::move(connection2)); + db_->OpenConnection(std::move(connection2)); - EXPECT_FALSE(backing_store->HasOneRef()); // local and connection + EXPECT_FALSE(backing_store_->HasOneRef()); // local and connection request1->connection()->ForceClose(); EXPECT_FALSE(request1->connection()->IsConnected()); - EXPECT_FALSE(backing_store->HasOneRef()); // local and connection + EXPECT_FALSE(backing_store_->HasOneRef()); // local and connection request2->connection()->ForceClose(); EXPECT_FALSE(request2->connection()->IsConnected()); - EXPECT_TRUE(backing_store->HasOneRef()); - EXPECT_FALSE(db->backing_store()); + EXPECT_TRUE(backing_store_->HasOneRef()); + EXPECT_FALSE(db_->backing_store()); - db = NULL; + db_ = NULL; } TEST_F(IndexedDBDatabaseTest, ForcedClose) { - scoped_refptr<IndexedDBFakeBackingStore> backing_store = - new IndexedDBFakeBackingStore(); - EXPECT_TRUE(backing_store->HasOneRef()); - - scoped_refptr<MockIndexedDBFactory> factory = new MockIndexedDBFactory(); - scoped_refptr<IndexedDBDatabase> database; - leveldb::Status s; - std::tie(database, s) = - IndexedDBDatabase::Create(ASCIIToUTF16("db"), backing_store.get(), - factory.get(), IndexedDBDatabase::Identifier()); - ASSERT_TRUE(s.ok()); - EXPECT_FALSE(backing_store->HasOneRef()); // local and db - scoped_refptr<MockIndexedDBDatabaseCallbacks> callbacks( new MockIndexedDBDatabaseCallbacks()); scoped_refptr<MockIndexedDBCallbacks> request(new MockIndexedDBCallbacks()); @@ -135,17 +116,17 @@ base::MakeUnique<IndexedDBPendingConnection>( request, callbacks, kFakeChildProcessId, upgrade_transaction_id, IndexedDBDatabaseMetadata::DEFAULT_VERSION)); - database->OpenConnection(std::move(connection)); - EXPECT_EQ(database.get(), request->connection()->database()); + db_->OpenConnection(std::move(connection)); + EXPECT_EQ(db_.get(), request->connection()->database()); const int64_t transaction_id = 123; const std::vector<int64_t> scope; - database->CreateTransaction(transaction_id, request->connection(), scope, - blink::kWebIDBTransactionModeReadOnly); + db_->CreateTransaction(transaction_id, request->connection(), scope, + blink::kWebIDBTransactionModeReadOnly); request->connection()->ForceClose(); - EXPECT_TRUE(backing_store->HasOneRef()); // local + EXPECT_TRUE(backing_store_->HasOneRef()); // local EXPECT_TRUE(callbacks->abort_called()); } @@ -178,19 +159,6 @@ }; TEST_F(IndexedDBDatabaseTest, PendingDelete) { - scoped_refptr<IndexedDBFakeBackingStore> backing_store = - new IndexedDBFakeBackingStore(); - EXPECT_TRUE(backing_store->HasOneRef()); // local - - scoped_refptr<MockIndexedDBFactory> factory = new MockIndexedDBFactory(); - scoped_refptr<IndexedDBDatabase> db; - leveldb::Status s; - std::tie(db, s) = - IndexedDBDatabase::Create(ASCIIToUTF16("db"), backing_store.get(), - factory.get(), IndexedDBDatabase::Identifier()); - ASSERT_TRUE(s.ok()); - EXPECT_FALSE(backing_store->HasOneRef()); // local and db - scoped_refptr<MockIndexedDBCallbacks> request1(new MockIndexedDBCallbacks()); scoped_refptr<MockIndexedDBDatabaseCallbacks> callbacks1( new MockIndexedDBDatabaseCallbacks()); @@ -199,52 +167,108 @@ base::MakeUnique<IndexedDBPendingConnection>( request1, callbacks1, kFakeChildProcessId, transaction_id1, IndexedDBDatabaseMetadata::DEFAULT_VERSION)); - db->OpenConnection(std::move(connection)); + db_->OpenConnection(std::move(connection)); - EXPECT_EQ(db->ConnectionCount(), 1UL); - EXPECT_EQ(db->ActiveOpenDeleteCount(), 0UL); - EXPECT_EQ(db->PendingOpenDeleteCount(), 0UL); - EXPECT_FALSE(backing_store->HasOneRef()); // local and db + EXPECT_EQ(db_->ConnectionCount(), 1UL); + EXPECT_EQ(db_->ActiveOpenDeleteCount(), 0UL); + EXPECT_EQ(db_->PendingOpenDeleteCount(), 0UL); + EXPECT_FALSE(backing_store_->HasOneRef()); // local and db scoped_refptr<MockCallbacks> request2(new MockCallbacks()); - db->DeleteDatabase(request2, false /* force_delete */); - EXPECT_EQ(db->ConnectionCount(), 1UL); - EXPECT_EQ(db->ActiveOpenDeleteCount(), 1UL); - EXPECT_EQ(db->PendingOpenDeleteCount(), 0UL); + db_->DeleteDatabase(request2, false /* force_delete */); + EXPECT_EQ(db_->ConnectionCount(), 1UL); + EXPECT_EQ(db_->ActiveOpenDeleteCount(), 1UL); + EXPECT_EQ(db_->PendingOpenDeleteCount(), 0UL); EXPECT_FALSE(request2->blocked_called()); - db->VersionChangeIgnored(); + db_->VersionChangeIgnored(); EXPECT_TRUE(request2->blocked_called()); - EXPECT_EQ(db->ConnectionCount(), 1UL); - EXPECT_EQ(db->ActiveOpenDeleteCount(), 1UL); - EXPECT_EQ(db->PendingOpenDeleteCount(), 0UL); + EXPECT_EQ(db_->ConnectionCount(), 1UL); + EXPECT_EQ(db_->ActiveOpenDeleteCount(), 1UL); + EXPECT_EQ(db_->PendingOpenDeleteCount(), 0UL); - EXPECT_FALSE(backing_store->HasOneRef()); // local and db + EXPECT_FALSE(backing_store_->HasOneRef()); // local and db - db->Close(request1->connection(), true /* forced */); - EXPECT_EQ(db->ConnectionCount(), 0UL); - EXPECT_EQ(db->ActiveOpenDeleteCount(), 0UL); - EXPECT_EQ(db->PendingOpenDeleteCount(), 0UL); + db_->Close(request1->connection(), true /* forced */); + EXPECT_EQ(db_->ConnectionCount(), 0UL); + EXPECT_EQ(db_->ActiveOpenDeleteCount(), 0UL); + EXPECT_EQ(db_->PendingOpenDeleteCount(), 0UL); - EXPECT_FALSE(db->backing_store()); - EXPECT_TRUE(backing_store->HasOneRef()); // local + EXPECT_FALSE(db_->backing_store()); + EXPECT_TRUE(backing_store_->HasOneRef()); // local EXPECT_TRUE(request2->success_called()); } +TEST_F(IndexedDBDatabaseTest, OpenDeleteClear) { + const int64_t kDatabaseVersion = 1; + + scoped_refptr<MockIndexedDBCallbacks> request1( + new MockIndexedDBCallbacks(true)); + scoped_refptr<MockIndexedDBDatabaseCallbacks> callbacks1( + new MockIndexedDBDatabaseCallbacks()); + const int64_t transaction_id1 = 1; + std::unique_ptr<IndexedDBPendingConnection> connection1( + base::MakeUnique<IndexedDBPendingConnection>( + request1, callbacks1, kFakeChildProcessId, transaction_id1, + kDatabaseVersion)); + db_->OpenConnection(std::move(connection1)); + + EXPECT_EQ(db_->ConnectionCount(), 1UL); + EXPECT_EQ(db_->ActiveOpenDeleteCount(), 1UL); + EXPECT_EQ(db_->PendingOpenDeleteCount(), 0UL); + EXPECT_FALSE(backing_store_->HasOneRef()); // local and db + + scoped_refptr<MockIndexedDBCallbacks> request2( + new MockIndexedDBCallbacks(false)); + scoped_refptr<MockIndexedDBDatabaseCallbacks> callbacks2( + new MockIndexedDBDatabaseCallbacks()); + const int64_t transaction_id2 = 2; + std::unique_ptr<IndexedDBPendingConnection> connection2( + base::MakeUnique<IndexedDBPendingConnection>( + request2, callbacks2, kFakeChildProcessId, transaction_id2, + kDatabaseVersion)); + db_->OpenConnection(std::move(connection2)); + + EXPECT_EQ(db_->ConnectionCount(), 1UL); + EXPECT_EQ(db_->ActiveOpenDeleteCount(), 1UL); + EXPECT_EQ(db_->PendingOpenDeleteCount(), 1UL); + EXPECT_FALSE(backing_store_->HasOneRef()); // local and db + + scoped_refptr<MockIndexedDBCallbacks> request3( + new MockIndexedDBCallbacks(false)); + scoped_refptr<MockIndexedDBDatabaseCallbacks> callbacks3( + new MockIndexedDBDatabaseCallbacks()); + const int64_t transaction_id3 = 3; + std::unique_ptr<IndexedDBPendingConnection> connection3( + base::MakeUnique<IndexedDBPendingConnection>( + request3, callbacks3, kFakeChildProcessId, transaction_id3, + kDatabaseVersion)); + db_->OpenConnection(std::move(connection3)); + + // This causes the active request to call OnUpgradeNeeded on its callbacks. + // The Abort() triggered by ForceClose() assumes that the transaction was + // started and passed the connection along to the front end. + db_->CallUpgradeTransactionStartedForTesting( + IndexedDBDatabaseMetadata::DEFAULT_VERSION); + EXPECT_TRUE(request1->upgrade_called()); + + EXPECT_EQ(db_->ConnectionCount(), 1UL); + EXPECT_EQ(db_->ActiveOpenDeleteCount(), 1UL); + EXPECT_EQ(db_->PendingOpenDeleteCount(), 2UL); + EXPECT_FALSE(backing_store_->HasOneRef()); + + db_->ForceClose(); + + EXPECT_TRUE(backing_store_->HasOneRef()); // local + EXPECT_TRUE(callbacks1->forced_close_called()); + EXPECT_TRUE(request1->error_called()); + EXPECT_TRUE(callbacks2->forced_close_called()); + EXPECT_FALSE(request2->error_called()); + EXPECT_TRUE(callbacks3->forced_close_called()); + EXPECT_FALSE(request3->error_called()); +} + TEST_F(IndexedDBDatabaseTest, ForceDelete) { - scoped_refptr<IndexedDBFakeBackingStore> backing_store = - new IndexedDBFakeBackingStore(); - EXPECT_TRUE(backing_store->HasOneRef()); // local - - scoped_refptr<MockIndexedDBFactory> factory = new MockIndexedDBFactory(); - scoped_refptr<IndexedDBDatabase> db; - leveldb::Status s; - std::tie(db, s) = - IndexedDBDatabase::Create(ASCIIToUTF16("db"), backing_store.get(), - factory.get(), IndexedDBDatabase::Identifier()); - ASSERT_TRUE(s.ok()); - EXPECT_FALSE(backing_store->HasOneRef()); // local and db - scoped_refptr<MockIndexedDBCallbacks> request1(new MockIndexedDBCallbacks()); scoped_refptr<MockIndexedDBDatabaseCallbacks> callbacks1( new MockIndexedDBDatabaseCallbacks()); @@ -253,22 +277,22 @@ base::MakeUnique<IndexedDBPendingConnection>( request1, callbacks1, kFakeChildProcessId, transaction_id1, IndexedDBDatabaseMetadata::DEFAULT_VERSION)); - db->OpenConnection(std::move(connection)); + db_->OpenConnection(std::move(connection)); - EXPECT_EQ(db->ConnectionCount(), 1UL); - EXPECT_EQ(db->ActiveOpenDeleteCount(), 0UL); - EXPECT_EQ(db->PendingOpenDeleteCount(), 0UL); - EXPECT_FALSE(backing_store->HasOneRef()); // local and db + EXPECT_EQ(db_->ConnectionCount(), 1UL); + EXPECT_EQ(db_->ActiveOpenDeleteCount(), 0UL); + EXPECT_EQ(db_->PendingOpenDeleteCount(), 0UL); + EXPECT_FALSE(backing_store_->HasOneRef()); // local and db scoped_refptr<MockCallbacks> request2(new MockCallbacks()); - db->DeleteDatabase(request2, true /* force_delete */); - EXPECT_EQ(db->ConnectionCount(), 0UL); - EXPECT_EQ(db->ActiveOpenDeleteCount(), 0UL); - EXPECT_EQ(db->PendingOpenDeleteCount(), 0UL); + db_->DeleteDatabase(request2, true /* force_delete */); + EXPECT_EQ(db_->ConnectionCount(), 0UL); + EXPECT_EQ(db_->ActiveOpenDeleteCount(), 0UL); + EXPECT_EQ(db_->PendingOpenDeleteCount(), 0UL); EXPECT_FALSE(request2->blocked_called()); - EXPECT_FALSE(db->backing_store()); - EXPECT_TRUE(backing_store->HasOneRef()); // local + EXPECT_FALSE(db_->backing_store()); + EXPECT_TRUE(backing_store_->HasOneRef()); // local EXPECT_TRUE(request2->success_called()); }
diff --git a/content/browser/indexed_db/mock_indexed_db_callbacks.cc b/content/browser/indexed_db/mock_indexed_db_callbacks.cc index af55ca19..fe8a6a1 100644 --- a/content/browser/indexed_db/mock_indexed_db_callbacks.cc +++ b/content/browser/indexed_db/mock_indexed_db_callbacks.cc
@@ -11,8 +11,7 @@ namespace content { MockIndexedDBCallbacks::MockIndexedDBCallbacks() - : IndexedDBCallbacks(nullptr, url::Origin(), nullptr, nullptr), - expect_connection_(true) {} + : IndexedDBCallbacks(nullptr, url::Origin(), nullptr, nullptr) {} MockIndexedDBCallbacks::MockIndexedDBCallbacks(bool expect_connection) : IndexedDBCallbacks(nullptr, url::Origin(), nullptr, nullptr), expect_connection_(expect_connection) {} @@ -21,6 +20,10 @@ EXPECT_EQ(expect_connection_, !!connection_); } +void MockIndexedDBCallbacks::OnError(const IndexedDBDatabaseError& error) { + error_called_ = true; +} + void MockIndexedDBCallbacks::OnSuccess() {} void MockIndexedDBCallbacks::OnSuccess(int64_t result) {} @@ -35,4 +38,13 @@ connection_ = std::move(connection); } +void MockIndexedDBCallbacks::OnUpgradeNeeded( + int64_t old_version, + std::unique_ptr<IndexedDBConnection> connection, + const content::IndexedDBDatabaseMetadata& metadata, + const IndexedDBDataLossInfo& data_loss_info) { + connection_ = std::move(connection); + upgrade_called_ = true; +} + } // namespace content
diff --git a/content/browser/indexed_db/mock_indexed_db_callbacks.h b/content/browser/indexed_db/mock_indexed_db_callbacks.h index 4ba45a8..10fa56e 100644 --- a/content/browser/indexed_db/mock_indexed_db_callbacks.h +++ b/content/browser/indexed_db/mock_indexed_db_callbacks.h
@@ -20,6 +20,8 @@ MockIndexedDBCallbacks(); explicit MockIndexedDBCallbacks(bool expect_connection); + void OnError(const IndexedDBDatabaseError& error) override; + void OnSuccess() override; void OnSuccess(int64_t result) override; void OnSuccess(const std::vector<base::string16>& result) override; @@ -28,13 +30,23 @@ const IndexedDBDatabaseMetadata& metadata) override; IndexedDBConnection* connection() { return connection_.get(); } + void OnUpgradeNeeded(int64_t old_version, + std::unique_ptr<IndexedDBConnection> connection, + const content::IndexedDBDatabaseMetadata& metadata, + const IndexedDBDataLossInfo& data_loss_info) override; + + bool error_called() { return error_called_; } + bool upgrade_called() { return upgrade_called_; } + protected: ~MockIndexedDBCallbacks() override; std::unique_ptr<IndexedDBConnection> connection_; private: - bool expect_connection_; + bool expect_connection_ = true; + bool error_called_ = false; + bool upgrade_called_ = false; DISALLOW_COPY_AND_ASSIGN(MockIndexedDBCallbacks); };
diff --git a/content/browser/renderer_host/render_widget_host_impl.cc b/content/browser/renderer_host/render_widget_host_impl.cc index 51978c4..a0e5792 100644 --- a/content/browser/renderer_host/render_widget_host_impl.cc +++ b/content/browser/renderer_host/render_widget_host_impl.cc
@@ -1926,13 +1926,6 @@ } void RenderWidgetHostImpl::BeginFrameDidNotSwap(const cc::BeginFrameAck& ack) { - if (ack.sequence_number < cc::BeginFrameArgs::kStartingFrameNumber) { - // Received an invalid ack, renderer misbehaved. - bad_message::ReceivedBadMessage( - GetProcess(), bad_message::RWH_INVALID_BEGIN_FRAME_ACK_DID_NOT_SWAP); - return; - } - // |has_damage| is not transmitted. cc::BeginFrameAck modified_ack = ack; modified_ack.has_damage = false; @@ -2581,14 +2574,6 @@ last_received_content_source_id_ = frame.metadata.content_source_id; - if (frame.metadata.begin_frame_ack.sequence_number < - cc::BeginFrameArgs::kStartingFrameNumber) { - // Received an invalid ack, renderer misbehaved. - bad_message::ReceivedBadMessage( - GetProcess(), - bad_message::RWH_INVALID_BEGIN_FRAME_ACK_COMPOSITOR_FRAME); - return; - } // |has_damage| is not transmitted. frame.metadata.begin_frame_ack.has_damage = true;
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc index 661b4db..2509f35 100644 --- a/content/browser/web_contents/web_contents_impl.cc +++ b/content/browser/web_contents/web_contents_impl.cc
@@ -257,6 +257,14 @@ AXTreeSnapshotCallback callback_; }; +// Helper for GetInnerWebContents(). +bool GetInnerWebContentsHelper( + std::vector<WebContentsImpl*>* all_guest_contents, + WebContents* guest_contents) { + all_guest_contents->push_back(static_cast<WebContentsImpl*>(guest_contents)); + return false; +} + } // namespace WebContents* WebContents::Create(const WebContents::CreateParams& params) { @@ -381,6 +389,9 @@ WebContentsImpl::WebContentsTreeNode::~WebContentsTreeNode() { if (OuterContentsFrameTreeNode()) OuterContentsFrameTreeNode()->RemoveObserver(this); + + if (outer_web_contents_) + outer_web_contents_->node_.DetachInnerWebContents(current_web_contents_); } void WebContentsImpl::WebContentsTreeNode::ConnectToOuterWebContents( @@ -391,9 +402,25 @@ outer_contents_frame_tree_node_id_ = outer_contents_frame->frame_tree_node()->frame_tree_node_id(); + outer_web_contents_->node_.AttachInnerWebContents(current_web_contents_); outer_contents_frame->frame_tree_node()->AddObserver(this); } +void WebContentsImpl::WebContentsTreeNode::AttachInnerWebContents( + WebContentsImpl* inner_web_contents) { + inner_web_contents_.push_back(inner_web_contents); +} + +void WebContentsImpl::WebContentsTreeNode::DetachInnerWebContents( + WebContentsImpl* inner_web_contents) { + DCHECK(std::find(inner_web_contents_.begin(), inner_web_contents_.end(), + inner_web_contents) != inner_web_contents_.end()); + inner_web_contents_.erase( + std::remove(inner_web_contents_.begin(), inner_web_contents_.end(), + inner_web_contents), + inner_web_contents_.end()); +} + FrameTreeNode* WebContentsImpl::WebContentsTreeNode::OuterContentsFrameTreeNode() const { return FrameTreeNode::GloballyFindByID(outer_contents_frame_tree_node_id_); @@ -414,6 +441,23 @@ focused_web_contents_ = web_contents; } +WebContentsImpl* +WebContentsImpl::WebContentsTreeNode::GetInnerWebContentsInFrame( + const FrameTreeNode* frame) { + auto ftn_id = frame->frame_tree_node_id(); + for (WebContentsImpl* contents : inner_web_contents_) { + if (contents->node_.outer_contents_frame_tree_node_id() == ftn_id) { + return contents; + } + } + return nullptr; +} + +const std::vector<WebContentsImpl*>& +WebContentsImpl::WebContentsTreeNode::inner_web_contents() const { + return inner_web_contents_; +} + // WebContentsImpl ------------------------------------------------------------- WebContentsImpl::WebContentsImpl(BrowserContext* browser_context) @@ -664,7 +708,7 @@ // static WebContentsImpl* WebContentsImpl::FromFrameTreeNode( - FrameTreeNode* frame_tree_node) { + const FrameTreeNode* frame_tree_node) { return static_cast<WebContentsImpl*>( WebContents::FromRenderFrameHost(frame_tree_node->current_frame_host())); } @@ -681,6 +725,13 @@ return WebContents::FromRenderFrameHost(render_frame_host); } +// static +WebContentsImpl* WebContentsImpl::FromOuterFrameTreeNode( + const FrameTreeNode* frame_tree_node) { + return WebContentsImpl::FromFrameTreeNode(frame_tree_node) + ->node_.GetInnerWebContentsInFrame(frame_tree_node); +} + RenderFrameHostManager* WebContentsImpl::GetRenderManagerForTesting() { return GetRenderManager(); } @@ -1038,6 +1089,29 @@ return it->second; } +std::vector<WebContentsImpl*> WebContentsImpl::GetInnerWebContents() { + if (browser_plugin_embedder_) { + std::vector<WebContentsImpl*> inner_contents; + GetBrowserContext()->GetGuestManager()->ForEachGuest( + this, base::Bind(&GetInnerWebContentsHelper, &inner_contents)); + return inner_contents; + } + + return node_.inner_web_contents(); +} + +std::vector<WebContentsImpl*> WebContentsImpl::GetWebContentsAndAllInner() { + std::vector<WebContentsImpl*> all_contents(1, this); + + for (size_t i = 0; i != all_contents.size(); ++i) { + for (auto* inner_contents : all_contents[i]->GetInnerWebContents()) { + all_contents.push_back(inner_contents); + } + } + + return all_contents; +} + void WebContentsImpl::UpdateDeviceScaleFactor(double device_scale_factor) { SendPageMessage( new PageMsg_SetDeviceScaleFactor(MSG_ROUTING_NONE, device_scale_factor)); @@ -1859,8 +1933,15 @@ ->GetRenderWidgetHost(); } - FrameTreeNode* focused_frame = - focused_contents->frame_tree_.GetFocusedFrame(); + // If the focused WebContents is a guest WebContents, then get the focused + // frame in the embedder WebContents instead. + FrameTreeNode* focused_frame = nullptr; + if (focused_contents->browser_plugin_guest_ && + !GuestMode::IsCrossProcessFrameGuest(focused_contents)) { + focused_frame = frame_tree_.GetFocusedFrame(); + } else { + focused_frame = GetFocusedWebContents()->frame_tree_.GetFocusedFrame(); + } if (!focused_frame) return receiving_widget; @@ -3323,25 +3404,12 @@ return; } - // See if a top level browser plugin handles the find request first. - // TODO(paulmeyer): Remove this after find-in-page works across GuestViews. - if (browser_plugin_embedder_ && - browser_plugin_embedder_->Find(request_id, search_text, options)) { - return; - } - GetOrCreateFindRequestManager()->Find(request_id, search_text, options); } void WebContentsImpl::StopFinding(StopFindAction action) { - // See if a top level browser plugin handles the stop finding request first. - // TODO(paulmeyer): Remove this after find-in-page works across GuestViews. - if (browser_plugin_embedder_ && - browser_plugin_embedder_->StopFinding(action)) { - return; - } - - GetOrCreateFindRequestManager()->StopFinding(action); + if (FindRequestManager* manager = GetFindRequestManager()) + manager->StopFinding(action); } bool WebContentsImpl::WasRecentlyAudible() { @@ -3796,6 +3864,9 @@ const gfx::Rect& selection_rect, int active_match_ordinal, bool final_update) { + if (active_match_ordinal > 0) + SetFocusedFrame(source->frame_tree_node(), source->GetSiteInstance()); + // Forward the find reply to the FindRequestManager, along with the // RenderFrameHost associated with the frame that the reply came from. GetOrCreateFindRequestManager()->OnFindReply( @@ -4800,6 +4871,11 @@ if (old_contents == this) return; + GetOutermostWebContents()->node_.SetFocusedWebContents(this); + + if (!GuestMode::IsCrossProcessFrameGuest(this) && browser_plugin_guest_) + return; + // Send a page level blur to the old contents so that it displays inactive UI // and focus this contents to activate it. if (old_contents) @@ -4819,20 +4895,11 @@ } else { GetMainFrame()->GetRenderWidgetHost()->SetPageFocus(true); } - GetOutermostWebContents()->node_.SetFocusedWebContents(this); } void WebContentsImpl::SetFocusedFrame(FrameTreeNode* node, SiteInstance* source) { - // The PDF plugin still runs as a BrowserPlugin and must go through the - // input redirection mechanism. It must not become focused direcly. - if (!GuestMode::IsCrossProcessFrameGuest(this) && browser_plugin_guest_) { - frame_tree_.SetFocusedFrame(node, source); - return; - } - SetAsFocusedWebContentsIfNecessary(); - frame_tree_.SetFocusedFrame(node, source); } @@ -5275,12 +5342,34 @@ return nullptr; } +FindRequestManager* WebContentsImpl::GetFindRequestManager() { + for (WebContentsImpl* contents = this; contents; + contents = contents->GetOuterWebContents()) { + if (contents->find_request_manager_) + return contents->find_request_manager_.get(); + } + + return nullptr; +} + FindRequestManager* WebContentsImpl::GetOrCreateFindRequestManager() { - // TODO(paulmeyer): This method will need to access (or potentially create) - // the FindRequestManager in the outermost WebContents once find-in-page - // across GuestViews is implemented. - if (!find_request_manager_) - find_request_manager_.reset(new FindRequestManager(this)); + if (FindRequestManager* manager = GetFindRequestManager()) + return manager; + + // No existing FindRequestManager found, so one must be created. + find_request_manager_.reset(new FindRequestManager(this)); + + // Concurrent find sessions must not overlap, so destroy any existing + // FindRequestManagers in any inner WebContentses. + for (WebContentsImpl* contents : GetWebContentsAndAllInner()) { + if (contents == this) + continue; + if (contents->find_request_manager_) { + contents->find_request_manager_->StopFinding( + content::STOP_FIND_ACTION_CLEAR_SELECTION); + contents->find_request_manager_.release(); + } + } return find_request_manager_.get(); } @@ -5332,6 +5421,12 @@ media_web_contents_observer()->RequestPersistentVideo(has_persistent_video); } +void WebContentsImpl::BrowserPluginGuestWillDetach() { + WebContentsImpl* outermost = GetOutermostWebContents(); + if (this != outermost && ContainsOrIsFocusedWebContents()) + outermost->SetAsFocusedWebContentsIfNecessary(); +} + #if defined(OS_ANDROID) void WebContentsImpl::NotifyFindMatchRectsReply( int version,
diff --git a/content/browser/web_contents/web_contents_impl.h b/content/browser/web_contents/web_contents_impl.h index 7a5368a..927e4b41 100644 --- a/content/browser/web_contents/web_contents_impl.h +++ b/content/browser/web_contents/web_contents_impl.h
@@ -132,10 +132,13 @@ static std::vector<WebContentsImpl*> GetAllWebContents(); - static WebContentsImpl* FromFrameTreeNode(FrameTreeNode* frame_tree_node); + static WebContentsImpl* FromFrameTreeNode( + const FrameTreeNode* frame_tree_node); static WebContents* FromRenderFrameHostID(int render_process_host_id, int render_frame_host_id); static WebContents* FromFrameTreeNodeId(int frame_tree_node_id); + static WebContentsImpl* FromOuterFrameTreeNode( + const FrameTreeNode* frame_tree_node); // Complex initialization here. Specifically needed to avoid having // members call back into our virtual functions in the constructor. @@ -268,6 +271,24 @@ // interface. WebContentsBindingSet* GetBindingSet(const std::string& interface_name); + // Returns the focused WebContents. + // If there are multiple inner/outer WebContents (when embedding <webview>, + // <guestview>, ...) returns the single one containing the currently focused + // frame. Otherwise, returns this WebContents. + WebContentsImpl* GetFocusedWebContents(); + + // TODO(paulmeyer): Once GuestViews are no longer implemented as + // BrowserPluginGuests, frame traversal across WebContents should be moved to + // be handled by FrameTreeNode, and |GetInnerWebContents| and + // |GetWebContentsAndAllInner| can be removed. + + // Returns a vector to the inner WebContents within this WebContents. + std::vector<WebContentsImpl*> GetInnerWebContents(); + + // Returns a vector containing this WebContents and all inner WebContents + // within it (recursively). + std::vector<WebContentsImpl*> GetWebContentsAndAllInner(); + // WebContents ------------------------------------------------------ WebContentsDelegate* GetDelegate() override; void SetDelegate(WebContentsDelegate* delegate) override; @@ -820,6 +841,10 @@ // deactivated. void SetAsFocusedWebContentsIfNecessary(); + // Called by this WebContents's BrowserPluginGuest (if one exists) to indicate + // that the guest will be detached. + void BrowserPluginGuestWillDetach(); + #if defined(OS_ANDROID) // Called by FindRequestManager when all of the find match rects are in. void NotifyFindMatchRectsReply(int version, @@ -895,7 +920,16 @@ WebContentsImpl* focused_web_contents() { return focused_web_contents_; } void SetFocusedWebContents(WebContentsImpl* web_contents); + // Returns the inner WebContents within |frame|, if one exists, or nullptr + // otherwise. + WebContentsImpl* GetInnerWebContentsInFrame(const FrameTreeNode* frame); + + const std::vector<WebContentsImpl*>& inner_web_contents() const; + private: + void AttachInnerWebContents(WebContentsImpl* inner_web_contents); + void DetachInnerWebContents(WebContentsImpl* inner_web_contents); + // FrameTreeNode::Observer implementation. void OnFrameTreeNodeDestroyed(FrameTreeNode* node) final; @@ -910,6 +944,9 @@ // |current_web_contents_| as an inner WebContents. int outer_contents_frame_tree_node_id_; + // List of inner WebContents that we host. + std::vector<WebContentsImpl*> inner_web_contents_; + // Only the root node should have this set. This indicates the WebContents // whose frame tree has the focused frame. The WebContents tree could be // arbitrarily deep. @@ -1087,12 +1124,6 @@ // receive page focus and blur events when the containing window changes focus // state. - // Returns the focused WebContents. - // If there are multiple inner/outer WebContents (when embedding <webview>, - // <guestview>, ...) returns the single one containing the currently focused - // frame. Otherwise, returns this WebContents. - WebContentsImpl* GetFocusedWebContents(); - // Returns true if |this| is the focused WebContents or an ancestor of the // focused WebContents. bool ContainsOrIsFocusedWebContents(); @@ -1193,7 +1224,11 @@ void SetJavaScriptDialogManagerForTesting( JavaScriptDialogManager* dialog_manager); - // Returns the FindRequestManager, or creates one if it doesn't already exist. + // Returns the FindRequestManager, which may be found in an outer WebContents. + FindRequestManager* GetFindRequestManager(); + + // Returns the FindRequestManager, or creates one if it doesn't already + // exist. The FindRequestManager may be found in an outer WebContents. FindRequestManager* GetOrCreateFindRequestManager(); // Removes a registered WebContentsBindingSet by interface name.
diff --git a/content/child/child_thread_impl.cc b/content/child/child_thread_impl.cc index 7500a8f..ea0b322 100644 --- a/content/child/child_thread_impl.cc +++ b/content/child/child_thread_impl.cc
@@ -70,7 +70,6 @@ #include "services/service_manager/public/cpp/connector.h" #include "services/service_manager/public/cpp/interface_factory.h" #include "services/service_manager/public/cpp/interface_provider.h" -#include "services/service_manager/public/cpp/interface_registry.h" #include "services/service_manager/runner/common/client_util.h" #if defined(OS_POSIX) @@ -451,13 +450,6 @@ service_manager_connection_ = ServiceManagerConnection::Create( mojo::MakeRequest<service_manager::mojom::Service>(std::move(handle)), GetIOTaskRunner()); - - // TODO(rockot): Remove this once all child-to-browser interface connections - // are made via a Connector rather than directly through an - // InterfaceProvider, and all exposed interfaces are exposed via a - // ConnectionFilter. - service_manager_connection_->SetupInterfaceRequestProxies( - GetInterfaceRegistry(), nullptr); } sync_message_filter_ = channel_->CreateSyncMessageFilter(); @@ -637,14 +629,6 @@ return service_manager_connection_.get(); } -service_manager::InterfaceRegistry* ChildThreadImpl::GetInterfaceRegistry() { - if (!interface_registry_.get()) { - interface_registry_ = base::MakeUnique<service_manager::InterfaceRegistry>( - service_manager::mojom::kServiceManager_ConnectorSpec); - } - return interface_registry_.get(); -} - service_manager::Connector* ChildThreadImpl::GetConnector() { return service_manager_connection_->GetConnector(); }
diff --git a/content/child/child_thread_impl.h b/content/child/child_thread_impl.h index d2f57d5..af17dac 100644 --- a/content/child/child_thread_impl.h +++ b/content/child/child_thread_impl.h
@@ -92,7 +92,6 @@ void RecordAction(const base::UserMetricsAction& action) override; void RecordComputedAction(const std::string& action) override; ServiceManagerConnection* GetServiceManagerConnection() override; - service_manager::InterfaceRegistry* GetInterfaceRegistry() override; service_manager::Connector* GetConnector() override; // Returns the service_manager::ServiceInfo for the child process & the @@ -246,7 +245,6 @@ const service_manager::ServiceInfo& remote_info); std::unique_ptr<mojo::edk::ScopedIPCSupport> mojo_ipc_support_; - std::unique_ptr<service_manager::InterfaceRegistry> interface_registry_; std::unique_ptr<ServiceManagerConnection> service_manager_connection_; bool connected_to_browser_ = false;
diff --git a/content/child/v8_value_converter_impl.cc b/content/child/v8_value_converter_impl.cc index ad5f6dd..89b3fc7 100644 --- a/content/child/v8_value_converter_impl.cc +++ b/content/child/v8_value_converter_impl.cc
@@ -342,8 +342,9 @@ const base::Value* value) const { DCHECK(creation_context->CreationContext() == isolate->GetCurrentContext()); v8::Local<v8::ArrayBuffer> buffer = - v8::ArrayBuffer::New(isolate, value->GetSize()); - memcpy(buffer->GetContents().Data(), value->GetBuffer(), value->GetSize()); + v8::ArrayBuffer::New(isolate, value->GetBlob().size()); + memcpy(buffer->GetContents().Data(), value->GetBlob().data(), + value->GetBlob().size()); return buffer; }
diff --git a/content/common/BUILD.gn b/content/common/BUILD.gn index 9e280290..10424ed 100644 --- a/content/common/BUILD.gn +++ b/content/common/BUILD.gn
@@ -367,6 +367,7 @@ "//components/tracing:startup_tracing", "//content:resources", "//content/app/resources", + "//content/public/common:service_names", "//device/base/synchronization", "//device/bluetooth", "//gpu",
diff --git a/content/common/android/gin_java_bridge_value.cc b/content/common/android/gin_java_bridge_value.cc index e745ce8..46d412d 100644 --- a/content/common/android/gin_java_bridge_value.cc +++ b/content/common/android/gin_java_bridge_value.cc
@@ -57,9 +57,9 @@ bool GinJavaBridgeValue::ContainsGinJavaBridgeValue(const base::Value* value) { if (!value->IsType(base::Value::Type::BINARY)) return false; - if (value->GetSize() < sizeof(Header)) + if (value->GetBlob().size() < sizeof(Header)) return false; - base::Pickle pickle(value->GetBuffer(), value->GetSize()); + base::Pickle pickle(value->GetBlob().data(), value->GetBlob().size()); // Broken binary value: payload or header size is wrong if (!pickle.data() || pickle.size() - pickle.payload_size() != sizeof(Header)) return false; @@ -112,7 +112,7 @@ } GinJavaBridgeValue::GinJavaBridgeValue(const base::Value* value) - : pickle_(value->GetBuffer(), value->GetSize()) { + : pickle_(value->GetBlob().data(), value->GetBlob().size()) { DCHECK(ContainsGinJavaBridgeValue(value)); }
diff --git a/content/common/service_manager/service_manager_connection_impl.cc b/content/common/service_manager/service_manager_connection_impl.cc index 9e81238..24e96620 100644 --- a/content/common/service_manager/service_manager_connection_impl.cc +++ b/content/common/service_manager/service_manager_connection_impl.cc
@@ -19,9 +19,9 @@ #include "content/common/child.mojom.h" #include "content/common/service_manager/embedded_service_runner.h" #include "content/public/common/connection_filter.h" +#include "content/public/common/service_names.mojom.h" #include "mojo/public/cpp/bindings/binding_set.h" #include "mojo/public/cpp/system/message_pipe.h" -#include "services/service_manager/public/cpp/interface_registry.h" #include "services/service_manager/public/cpp/service.h" #include "services/service_manager/public/cpp/service_context.h" #include "services/service_manager/public/interfaces/constants.mojom.h" @@ -112,15 +112,6 @@ filter_id)); } - // Safe to call any time before Start() is called. - void SetDefaultBinderForBrowserConnection( - const service_manager::InterfaceRegistry::Binder& binder) { - DCHECK(!started_); - default_browser_binder_ = base::Bind( - &IOThreadContext::CallBinderOnTaskRunner, - base::ThreadTaskRunnerHandle::Get(), binder); - } - void AddEmbeddedService(const std::string& name, const ServiceInfo& info) { io_task_runner_->PostTask( FROM_HERE, base::Bind(&ServiceManagerConnectionImpl::IOThreadContext:: @@ -232,11 +223,6 @@ connection_filters_.erase(it); } - void OnBrowserConnectionLost() { - DCHECK(io_thread_checker_.CalledOnValidThread()); - has_browser_connection_ = false; - } - void AddEmbeddedServiceRequestHandlerOnIoThread(const std::string& name, const ServiceInfo& info) { DCHECK(io_thread_checker_.CalledOnValidThread()); @@ -276,18 +262,22 @@ const std::string& interface_name, mojo::ScopedMessagePipeHandle interface_pipe) override { DCHECK(io_thread_checker_.CalledOnValidThread()); - - std::string remote_service = source_info.identity.name(); - // Only expose the ServiceFactory interface to the Service Manager. - if (remote_service == service_manager::mojom::kServiceName && + if (source_info.identity.name() == service_manager::mojom::kServiceName && interface_name == service_manager::mojom::ServiceFactory::Name_) { factory_bindings_.AddBinding( this, mojo::MakeRequest<service_manager::mojom::ServiceFactory>( std::move(interface_pipe))); - return; - } + } else if (source_info.identity.name() == mojom::kBrowserServiceName && + interface_name == mojom::Child::Name_) { + DCHECK(!child_binding_.is_bound()); + child_binding_.Bind( + mojo::MakeRequest<mojom::Child>(std::move(interface_pipe))); - { + InitializeCallback handler = + base::ResetAndReturn(&browser_info_available_callback_); + callback_task_runner_->PostTask(FROM_HERE, + base::Bind(handler, source_info)); + } else { base::AutoLock lock(lock_); for (auto& entry : connection_filters_) { entry.second->OnBindInterface(source_info, interface_name, @@ -298,22 +288,6 @@ return; } } - - if (remote_service == "content_browser") { - if (interface_name == mojom::Child::Name_ && !has_browser_connection_) { - has_browser_connection_ = true; - InitializeCallback handler = - base::ResetAndReturn(&browser_info_available_callback_); - callback_task_runner_->PostTask(FROM_HERE, - base::Bind(handler, source_info)); - - child_binding_.Bind(std::move(interface_pipe)); - child_binding_.set_connection_error_handler( - base::Bind(&IOThreadContext::OnBrowserConnectionLost, this)); - } else { - default_browser_binder_.Run(interface_name, std::move(interface_pipe)); - } - } } bool OnServiceManagerConnectionLost() override { @@ -323,7 +297,7 @@ } ///////////////////////////////////////////////////////////////////////////// - // service_manager::mojom::ServiceFactory implementation + // service_manager::mojom::ServiceFactory: void CreateService(service_manager::mojom::ServiceRequest request, const std::string& name) override { @@ -334,15 +308,6 @@ it->second.Run(std::move(request)); } - static void CallBinderOnTaskRunner( - scoped_refptr<base::SequencedTaskRunner> task_runner, - const service_manager::InterfaceRegistry::Binder& binder, - const std::string& interface_name, - mojo::ScopedMessagePipeHandle request_handle) { - task_runner->PostTask(FROM_HERE, base::Bind(binder, interface_name, - base::Passed(&request_handle))); - } - base::ThreadChecker io_thread_checker_; bool started_ = false; @@ -364,19 +329,8 @@ // Callback to run if the service is stopped by the service manager. base::Closure stop_callback_; - // Called once a connection has been received from the browser process & the - // default binder (below) has been set up. - bool has_browser_connection_ = false; - service_manager::ServiceInfo local_info_; - // Default binder callback used for the browser connection's - // InterfaceRegistry. - // - // TODO(rockot): Remove this once all interfaces exposed to the browser are - // exposed via a ConnectionFilter. - service_manager::InterfaceRegistry::Binder default_browser_binder_; - std::unique_ptr<service_manager::ServiceContext> service_context_; mojo::BindingSet<service_manager::mojom::ServiceFactory> factory_bindings_; int next_filter_id_ = kInvalidConnectionFilterId; @@ -491,18 +445,6 @@ connection_lost_handler_ = closure; } -void ServiceManagerConnectionImpl::SetupInterfaceRequestProxies( - service_manager::InterfaceRegistry* registry, - service_manager::InterfaceProvider* provider) { - // It's safe to bind |registry| as a raw pointer because the caller must - // guarantee that it outlives |this|, and |this| is bound as a weak ptr here. - context_->SetDefaultBinderForBrowserConnection( - base::Bind(&ServiceManagerConnectionImpl::GetInterface, - weak_factory_.GetWeakPtr(), registry)); - - // TODO(beng): remove provider parameter. -} - int ServiceManagerConnectionImpl::AddConnectionFilter( std::unique_ptr<ConnectionFilter> filter) { return context_->AddConnectionFilter(std::move(filter));
diff --git a/content/common/service_manager/service_manager_connection_impl.h b/content/common/service_manager/service_manager_connection_impl.h index c950283..6ef897e 100644 --- a/content/common/service_manager/service_manager_connection_impl.h +++ b/content/common/service_manager/service_manager_connection_impl.h
@@ -40,9 +40,6 @@ const service_manager::ServiceInfo& GetLocalInfo() const override; const service_manager::ServiceInfo& GetBrowserInfo() const override; void SetConnectionLostClosure(const base::Closure& closure) override; - void SetupInterfaceRequestProxies( - service_manager::InterfaceRegistry* registry, - service_manager::InterfaceProvider* provider) override; int AddConnectionFilter(std::unique_ptr<ConnectionFilter> filter) override; void RemoveConnectionFilter(int filter_id) override; void AddEmbeddedService(const std::string& name,
diff --git a/content/network/manifest.json b/content/network/manifest.json index daa39ec..41af5e80 100644 --- a/content/network/manifest.json +++ b/content/network/manifest.json
@@ -4,6 +4,9 @@ "interface_provider_specs": { "service_manager:connector": { "provides": { + "test": [ + "content::mojom::NetworkServiceTest" + ], "url_loader": [ "content::mojom::URLLoaderFactory" ]
diff --git a/content/network/network_service.cc b/content/network/network_service.cc index bd04eb8..e6a1880f 100644 --- a/content/network/network_service.cc +++ b/content/network/network_service.cc
@@ -11,24 +11,20 @@ namespace content { -NetworkService::NetworkService() { - registry_.AddInterface<mojom::URLLoaderFactory>(this); +NetworkService::NetworkService( + std::unique_ptr<service_manager::BinderRegistry> registry) + : registry_(std::move(registry)) { + registry_->AddInterface<mojom::URLLoaderFactory>(this); } NetworkService::~NetworkService() = default; -// static -std::unique_ptr<service_manager::Service> -NetworkService::CreateNetworkService() { - return base::MakeUnique<NetworkService>(); -} - void NetworkService::OnBindInterface( const service_manager::ServiceInfo& source_info, const std::string& interface_name, mojo::ScopedMessagePipeHandle interface_pipe) { - registry_.BindInterface(source_info.identity, interface_name, - std::move(interface_pipe)); + registry_->BindInterface(source_info.identity, interface_name, + std::move(interface_pipe)); } void NetworkService::Create(const service_manager::Identity& remote_identity,
diff --git a/content/network/network_service.h b/content/network/network_service.h index 754878b..ec165b5 100644 --- a/content/network/network_service.h +++ b/content/network/network_service.h
@@ -21,11 +21,10 @@ : public service_manager::Service, public service_manager::InterfaceFactory<mojom::URLLoaderFactory> { public: - NetworkService(); + explicit NetworkService( + std::unique_ptr<service_manager::BinderRegistry> registry); ~NetworkService() override; - static std::unique_ptr<service_manager::Service> CreateNetworkService(); - private: // service_manager::Service implementation. void OnBindInterface(const service_manager::ServiceInfo& source_info, @@ -36,7 +35,7 @@ void Create(const service_manager::Identity& remote_identity, mojom::URLLoaderFactoryRequest request) override; - service_manager::BinderRegistry registry_; + std::unique_ptr<service_manager::BinderRegistry> registry_; NetworkContext context_;
diff --git a/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java b/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java index 300bb7f..a63e57a1 100644 --- a/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java +++ b/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java
@@ -1307,35 +1307,19 @@ /** * @see View#onHoverEvent(MotionEvent) - * Mouse move events are sent on hover enter, hover move and hover exit. - * They are sent on hover exit because sometimes it acts as both a hover - * move and hover exit. + * Mouse move events are sent on hover move. */ public boolean onHoverEvent(MotionEvent event) { TraceEvent.begin("onHoverEvent"); - int eventAction = event.getActionMasked(); - - // Ignore ACTION_HOVER_ENTER & ACTION_HOVER_EXIT: every mouse-down on - // Android follows a hover-exit and is followed by a hover-enter. The - // MotionEvent spec seems to support this behavior indirectly. - if (eventAction == MotionEvent.ACTION_HOVER_ENTER - || eventAction == MotionEvent.ACTION_HOVER_EXIT) { - return false; - } - MotionEvent offset = createOffsetMotionEvent(event); try { - if (mBrowserAccessibilityManager != null && !mIsObscuredByAnotherView) { - return mBrowserAccessibilityManager.onHoverEvent(offset); + if (mBrowserAccessibilityManager != null && !mIsObscuredByAnotherView + && mBrowserAccessibilityManager.onHoverEvent(offset)) { + return true; } - getEventForwarder().sendMouseEvent(event.getEventTime(), eventAction, offset.getX(), - offset.getY(), event.getPointerId(0), event.getPressure(0), - event.getOrientation(0), event.getAxisValue(MotionEvent.AXIS_TILT, 0), - 0 /* changedButton */, event.getButtonState(), event.getMetaState(), - event.getToolType(0)); - return true; + return getEventForwarder().onMouseEvent(event); } finally { offset.recycle(); TraceEvent.end("onHoverEvent");
diff --git a/content/public/app/mojo/content_browser_manifest.json b/content/public/app/mojo/content_browser_manifest.json index f7cfe7be..697613f 100644 --- a/content/public/app/mojo/content_browser_manifest.json +++ b/content/public/app/mojo/content_browser_manifest.json
@@ -62,7 +62,10 @@ "device": [ "device:wake_lock" ], "file": [ "file:filesystem", "file:leveldb" ], "media": [ "media:media" ], - "network": [ "url_loader" ], + "network": [ + "test", + "url_loader" + ], "ui": [ "display_output_protection" ], "service_manager": [ "service_manager:client_process",
diff --git a/content/public/browser/browser_plugin_guest_delegate.cc b/content/public/browser/browser_plugin_guest_delegate.cc index 8d691ef..663a7fe 100644 --- a/content/public/browser/browser_plugin_guest_delegate.cc +++ b/content/public/browser/browser_plugin_guest_delegate.cc
@@ -20,18 +20,6 @@ return nullptr; } -bool BrowserPluginGuestDelegate::HandleFindForEmbedder( - int request_id, - const base::string16& search_text, - const blink::WebFindOptions& options) { - return false; -} - -bool BrowserPluginGuestDelegate::HandleStopFindingForEmbedder( - StopFindAction action) { - return false; -} - bool BrowserPluginGuestDelegate::CanUseCrossProcessFrames() { return true; }
diff --git a/content/public/browser/browser_plugin_guest_delegate.h b/content/public/browser/browser_plugin_guest_delegate.h index a32205c..61662f4 100644 --- a/content/public/browser/browser_plugin_guest_delegate.h +++ b/content/public/browser/browser_plugin_guest_delegate.h
@@ -74,13 +74,6 @@ bool last_unlocked_by_target, const base::Callback<void(bool)>& callback) {} - // Find the given |search_text| in the page. Returns true if the find request - // is handled by this browser plugin guest delegate. - virtual bool HandleFindForEmbedder(int request_id, - const base::string16& search_text, - const blink::WebFindOptions& options); - virtual bool HandleStopFindingForEmbedder(StopFindAction action); - // Provides the delegate with an interface with which to communicate with the // content module. virtual void SetGuestHost(GuestHost* guest_host) {}
diff --git a/content/public/child/child_thread.h b/content/public/child/child_thread.h index 9287ee8a..575ee80 100644 --- a/content/public/child/child_thread.h +++ b/content/public/child/child_thread.h
@@ -22,7 +22,6 @@ namespace service_manager { class Connector; -class InterfaceRegistry; } namespace content { @@ -71,10 +70,6 @@ // service_manager::Connector can be obtained). virtual ServiceManagerConnection* GetServiceManagerConnection() = 0; - // Returns the InterfaceRegistry that this process uses to expose interfaces - // to the browser. - virtual service_manager::InterfaceRegistry* GetInterfaceRegistry() = 0; - // Returns a connector that can be used to bind interfaces exposed by other // services. virtual service_manager::Connector* GetConnector() = 0;
diff --git a/content/public/common/BUILD.gn b/content/public/common/BUILD.gn index d553b2a9..16edb0c5 100644 --- a/content/public/common/BUILD.gn +++ b/content/public/common/BUILD.gn
@@ -335,6 +335,7 @@ mojom("interfaces") { sources = [ + "network_service_test.mojom", "window_container_type.mojom", ] }
diff --git a/content/public/common/network_service_test.mojom b/content/public/common/network_service_test.mojom new file mode 100644 index 0000000..451c15f --- /dev/null +++ b/content/public/common/network_service_test.mojom
@@ -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. + +module content.mojom; + +struct Rule { + string host_pattern; + string replacement; +}; + +// Testing interface to the network service. +interface NetworkServiceTest { + // Adds the given host resolver rules in the process where the network + // service is running. + AddRules(array<Rule> rules); +};
diff --git a/content/public/common/service_manager_connection.h b/content/public/common/service_manager_connection.h index 5e5378cd..674cf2d 100644 --- a/content/public/common/service_manager_connection.h +++ b/content/public/common/service_manager_connection.h
@@ -15,10 +15,7 @@ #include "services/service_manager/public/interfaces/service.mojom.h" namespace service_manager { -class Connection; class Connector; -class InterfaceProvider; -class InterfaceRegistry; } namespace content { @@ -92,22 +89,6 @@ // run immediately before returning from this function. virtual void SetConnectionLostClosure(const base::Closure& closure) = 0; - // Provides an InterfaceRegistry to forward incoming interface requests to - // on the ServiceManagerConnection's own thread if they aren't bound by the - // connection's internal InterfaceRegistry on the IO thread. - // - // Also configures |interface_provider| to forward all of its outgoing - // interface requests to the connection's internal remote interface provider. - // - // Note that neither |interface_registry| or |interface_provider| is owned - // and both MUST outlive the ServiceManagerConnection. - // - // TODO(rockot): Remove this. It's a temporary solution to avoid porting all - // relevant code to ConnectionFilters at once. - virtual void SetupInterfaceRequestProxies( - service_manager::InterfaceRegistry* registry, - service_manager::InterfaceProvider* provider) = 0; - static const int kInvalidConnectionFilterId = 0; // Allows the caller to filter inbound connections and/or expose interfaces
diff --git a/content/public/test/browser_test_base.cc b/content/public/test/browser_test_base.cc index 20b2bff..69afea6 100644 --- a/content/public/test/browser_test_base.cc +++ b/content/public/test/browser_test_base.cc
@@ -26,13 +26,15 @@ #include "content/public/browser/browser_thread.h" #include "content/public/common/content_switches.h" #include "content/public/common/main_function_params.h" +#include "content/public/common/network_service_test.mojom.h" +#include "content/public/common/service_manager_connection.h" +#include "content/public/common/service_names.mojom.h" #include "content/public/test/test_launcher.h" #include "content/public/test/test_utils.h" #include "content/test/content_browser_sanity_checker.h" -#include "net/base/net_errors.h" -#include "net/base/network_interfaces.h" #include "net/dns/mock_host_resolver.h" #include "net/test/embedded_test_server/embedded_test_server.h" +#include "services/service_manager/public/cpp/connector.h" #include "ui/base/platform_window_defaults.h" #include "ui/base/test/material_design_controller_test_api.h" #include "ui/compositor/compositor_switches.h" @@ -87,51 +89,6 @@ BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, quit_task); } -// In many cases it may be not obvious that a test makes a real DNS lookup. -// We generally don't want to rely on external DNS servers for our tests, -// so this host resolver procedure catches external queries and returns a failed -// lookup result. -class LocalHostResolverProc : public net::HostResolverProc { - public: - LocalHostResolverProc() : HostResolverProc(NULL) {} - - int Resolve(const std::string& host, - net::AddressFamily address_family, - net::HostResolverFlags host_resolver_flags, - net::AddressList* addrlist, - int* os_error) override { - const char* kLocalHostNames[] = {"localhost", "127.0.0.1", "::1"}; - bool local = false; - - if (host == net::GetHostName()) { - local = true; - } else { - for (size_t i = 0; i < arraysize(kLocalHostNames); i++) - if (host == kLocalHostNames[i]) { - local = true; - break; - } - } - - // To avoid depending on external resources and to reduce (if not preclude) - // network interactions from tests, we simulate failure for non-local DNS - // queries, rather than perform them. - // If you really need to make an external DNS query, use - // net::RuleBasedHostResolverProc and its AllowDirectLookup method. - if (!local) { - DVLOG(1) << "To avoid external dependencies, simulating failure for " - "external DNS lookup of " << host; - return net::ERR_NOT_IMPLEMENTED; - } - - return ResolveUsingPrevious(host, address_family, host_resolver_flags, - addrlist, os_error); - } - - private: - ~LocalHostResolverProc() override {} -}; - void TraceStopTracingComplete(const base::Closure& quit, const base::FilePath& file_path) { LOG(ERROR) << "Tracing written to: " << file_path.value(); @@ -269,13 +226,7 @@ if (use_software_gl && !use_software_compositing_) command_line->AppendSwitch(switches::kOverrideUseSoftwareGLForTests); - scoped_refptr<net::HostResolverProc> local_resolver = - new LocalHostResolverProc(); - rule_based_resolver_ = - new net::RuleBasedHostResolverProc(local_resolver.get()); - rule_based_resolver_->AddSimulatedFailure("wpad"); - net::ScopedDefaultHostResolverProc scoped_local_host_resolver_proc( - rule_based_resolver_.get()); + test_host_resolver_.reset(new TestHostResolver); ContentBrowserSanityChecker scoped_enable_sanity_checks; @@ -347,6 +298,11 @@ base::MessageLoop::current()); PreRunTestOnMainThread(); SetUpOnMainThread(); + + // Tests would have added their host_resolver() rules by now, so copy them + // to the network process if it's in use. + InitializeNetworkProcess(); + bool old_io_allowed_value = false; if (!disable_io_checks_) base::ThreadRestrictions::SetIOAllowed(false); @@ -416,4 +372,39 @@ gl::GetGLImplementationName(gl::GetSoftwareGLImplementation()); } +void BrowserTestBase::InitializeNetworkProcess() { + if (!base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kEnableNetworkService)) + return; + + net::RuleBasedHostResolverProc::RuleList rules = host_resolver()->GetRules(); + std::vector<mojom::RulePtr> mojo_rules; + for (const auto& rule : rules) { + // For now, this covers all the rules used in content's tests. + // TODO(jam: expand this when we try to make browser_tests and + // components_browsertests work. + if (rule.resolver_type != + net::RuleBasedHostResolverProc::Rule::kResolverTypeSystem || + rule.address_family != net::AddressFamily::ADDRESS_FAMILY_UNSPECIFIED || + !!rule.latency_ms || rule.replacement.empty()) + continue; + mojom::RulePtr mojo_rule = mojom::Rule::New(); + mojo_rule->host_pattern = rule.host_pattern; + mojo_rule->replacement = rule.replacement; + mojo_rules.push_back(std::move(mojo_rule)); + } + + if (mojo_rules.empty()) + return; + + mojom::NetworkServiceTestPtr network_service_test; + ServiceManagerConnection::GetForProcess()->GetConnector()->BindInterface( + mojom::kNetworkServiceName, &network_service_test); + network_service_test->AddRules(std::move(mojo_rules)); + + // TODO(jam): enable this once all access to host_resolver() is in + // SetUpOnMainThread or before. http://crbug.com/713847 + // host_resolver()->DisableModifications(); +} + } // namespace content
diff --git a/content/public/test/browser_test_base.h b/content/public/test/browser_test_base.h index a404d0f5..30f7f0a 100644 --- a/content/public/test/browser_test_base.h +++ b/content/public/test/browser_test_base.h
@@ -9,6 +9,7 @@ #include "base/compiler_specific.h" #include "base/threading/thread.h" #include "build/build_config.h" +#include "content/public/test/test_host_resolver.h" #include "net/test/embedded_test_server/embedded_test_server.h" #include "net/test/spawned_test_server/spawned_test_server.h" #include "testing/gtest/include/gtest/gtest.h" @@ -18,10 +19,6 @@ class FilePath; } -namespace net { -class RuleBasedHostResolverProc; -} // namespace net - namespace content { class BrowserTestBase : public testing::Test { @@ -51,7 +48,7 @@ // Returns the host resolver being used for the tests. Subclasses might want // to configure it inside tests. net::RuleBasedHostResolverProc* host_resolver() { - return rule_based_resolver_.get(); + return test_host_resolver_->host_resolver(); } protected: @@ -138,6 +135,10 @@ private: void ProxyRunTestOnMainThreadLoop(); + // When using the network process, update the host resolver rules that were + // added in SetUpOnMainThread. + void InitializeNetworkProcess(); + // Testing server, started on demand. std::unique_ptr<net::SpawnedTestServer> spawned_test_server_; @@ -145,7 +146,7 @@ std::unique_ptr<net::EmbeddedTestServer> embedded_test_server_; // Host resolver used during tests. - scoped_refptr<net::RuleBasedHostResolverProc> rule_based_resolver_; + std::unique_ptr<TestHostResolver> test_host_resolver_; // Expected exit code (default is 0). int expected_exit_code_;
diff --git a/content/public/test/mock_render_thread.cc b/content/public/test/mock_render_thread.cc index f2f9b42..99ff137b 100644 --- a/content/public/test/mock_render_thread.cc +++ b/content/public/test/mock_render_thread.cc
@@ -19,9 +19,6 @@ #include "ipc/ipc_sync_message.h" #include "ipc/message_filter.h" #include "services/service_manager/public/cpp/connector.h" -#include "services/service_manager/public/cpp/interface_provider.h" -#include "services/service_manager/public/cpp/interface_registry.h" -#include "services/service_manager/public/interfaces/interface_provider_spec.mojom.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/WebKit/public/web/WebScriptController.h" @@ -253,14 +250,6 @@ return nullptr; } -service_manager::InterfaceRegistry* MockRenderThread::GetInterfaceRegistry() { - if (!interface_registry_) { - interface_registry_ = base::MakeUnique<service_manager::InterfaceRegistry>( - service_manager::mojom::kServiceManager_ConnectorSpec); - } - return interface_registry_.get(); -} - service_manager::Connector* MockRenderThread::GetConnector() { if (!connector_) { connector_ =
diff --git a/content/public/test/mock_render_thread.h b/content/public/test/mock_render_thread.h index f6cca73..3a00754 100644 --- a/content/public/test/mock_render_thread.h +++ b/content/public/test/mock_render_thread.h
@@ -17,7 +17,6 @@ #include "ipc/ipc_test_sink.h" #include "ipc/message_filter.h" #include "services/service_manager/public/interfaces/connector.mojom.h" -#include "services/service_manager/public/interfaces/interface_provider.mojom.h" #include "third_party/WebKit/public/web/WebPopupType.h" struct FrameHostMsg_CreateChildFrame_Params; @@ -89,7 +88,6 @@ void ReleaseCachedFonts() override; #endif ServiceManagerConnection* GetServiceManagerConnection() override; - service_manager::InterfaceRegistry* GetInterfaceRegistry() override; service_manager::Connector* GetConnector() override; void SetFieldTrialGroup(const std::string& trial_name, const std::string& group_name) override; @@ -167,7 +165,6 @@ base::ObserverList<RenderThreadObserver> observers_; cc::TestSharedBitmapManager shared_bitmap_manager_; - std::unique_ptr<service_manager::InterfaceRegistry> interface_registry_; std::unique_ptr<service_manager::Connector> connector_; service_manager::mojom::ConnectorRequest pending_connector_request_;
diff --git a/content/public/test/test_host_resolver.cc b/content/public/test/test_host_resolver.cc new file mode 100644 index 0000000..da2bfd0 --- /dev/null +++ b/content/public/test/test_host_resolver.cc
@@ -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. + +#include "content/public/test/test_host_resolver.h" + +#include "base/macros.h" +#include "base/message_loop/message_loop.h" +#include "base/threading/thread.h" +#include "content/browser/browser_thread_impl.h" +#include "content/browser/notification_service_impl.h" +#include "net/base/net_errors.h" +#include "net/base/network_interfaces.h" +#include "net/dns/mock_host_resolver.h" + +namespace content { + +namespace { +// In many cases it may be not obvious that a test makes a real DNS lookup. +// We generally don't want to rely on external DNS servers for our tests, +// so this host resolver procedure catches external queries and returns a failed +// lookup result. +class LocalHostResolverProc : public net::HostResolverProc { + public: + LocalHostResolverProc() : HostResolverProc(NULL) {} + + int Resolve(const std::string& host, + net::AddressFamily address_family, + net::HostResolverFlags host_resolver_flags, + net::AddressList* addrlist, + int* os_error) override { + const char* kLocalHostNames[] = {"localhost", "127.0.0.1", "::1"}; + bool local = false; + + if (host == net::GetHostName()) { + local = true; + } else { + for (size_t i = 0; i < arraysize(kLocalHostNames); i++) + if (host == kLocalHostNames[i]) { + local = true; + break; + } + } + + // To avoid depending on external resources and to reduce (if not preclude) + // network interactions from tests, we simulate failure for non-local DNS + // queries, rather than perform them. + // If you really need to make an external DNS query, use + // net::RuleBasedHostResolverProc and its AllowDirectLookup method. + if (!local) { + DVLOG(1) << "To avoid external dependencies, simulating failure for " + "external DNS lookup of " + << host; + return net::ERR_NOT_IMPLEMENTED; + } + + return ResolveUsingPrevious(host, address_family, host_resolver_flags, + addrlist, os_error); + } + + private: + ~LocalHostResolverProc() override {} +}; +} + +TestHostResolver::TestHostResolver() + : local_resolver_(new LocalHostResolverProc()), + rule_based_resolver_( + new net::RuleBasedHostResolverProc(local_resolver_.get())), + scoped_local_host_resolver_proc_( + new net::ScopedDefaultHostResolverProc(rule_based_resolver_.get())) { + rule_based_resolver_->AddSimulatedFailure("wpad"); +} + +TestHostResolver::~TestHostResolver() {} + +} // namespace content
diff --git a/content/public/test/test_host_resolver.h b/content/public/test/test_host_resolver.h new file mode 100644 index 0000000..1278970f0 --- /dev/null +++ b/content/public/test/test_host_resolver.h
@@ -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. + +#ifndef CONTENT_PUBLIC_TEST_TEST_HOST_RESOLVER_H_ +#define CONTENT_PUBLIC_TEST_TEST_HOST_RESOLVER_H_ + +#include "base/macros.h" +#include "base/memory/ref_counted.h" + +namespace net { +class HostResolverProc; +class RuleBasedHostResolverProc; +class ScopedDefaultHostResolverProc; +} + +namespace content { +class TestHostResolver { + public: + TestHostResolver(); + ~TestHostResolver(); + + net::RuleBasedHostResolverProc* host_resolver() { + return rule_based_resolver_.get(); + } + + private: + // Host resolver used during tests. + scoped_refptr<net::HostResolverProc> local_resolver_; + scoped_refptr<net::RuleBasedHostResolverProc> rule_based_resolver_; + std::unique_ptr<net::ScopedDefaultHostResolverProc> + scoped_local_host_resolver_proc_; + + DISALLOW_COPY_AND_ASSIGN(TestHostResolver); +}; + +} // namespace content + +#endif // CONTENT_PUBLIC_TEST_TEST_HOST_RESOLVER_H_
diff --git a/content/public/utility/content_utility_client.h b/content/public/utility/content_utility_client.h index 6d2d41a..0d552bf 100644 --- a/content/public/utility/content_utility_client.h +++ b/content/public/utility/content_utility_client.h
@@ -13,6 +13,7 @@ #include "content/public/common/service_info.h" namespace service_manager { +class BinderRegistry; class InterfaceRegistry; } @@ -37,6 +38,9 @@ service_manager::InterfaceRegistry* registry) {} virtual void RegisterServices(StaticServiceMap* services) {} + + virtual void RegisterNetworkBinders( + service_manager::BinderRegistry* registry) {} }; } // namespace content
diff --git a/content/renderer/media/cdm/render_cdm_factory.cc b/content/renderer/media/cdm/render_cdm_factory.cc index ab428ad..11431eb5 100644 --- a/content/renderer/media/cdm/render_cdm_factory.cc +++ b/content/renderer/media/cdm/render_cdm_factory.cc
@@ -57,9 +57,9 @@ if (media::CanUseAesDecryptor(key_system)) { DCHECK(!cdm_config.allow_distinctive_identifier); DCHECK(!cdm_config.allow_persistent_state); - scoped_refptr<media::ContentDecryptionModule> cdm( - new media::AesDecryptor(security_origin, session_message_cb, - session_closed_cb, session_keys_change_cb)); + scoped_refptr<media::ContentDecryptionModule> cdm(new media::AesDecryptor( + security_origin, session_message_cb, session_closed_cb, + session_keys_change_cb, session_expiration_update_cb)); base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::Bind(cdm_created_cb, cdm, "")); return;
diff --git a/content/shell/BUILD.gn b/content/shell/BUILD.gn index ccf57ca3..ab8ee75a 100644 --- a/content/shell/BUILD.gn +++ b/content/shell/BUILD.gn
@@ -231,6 +231,7 @@ "//content/app/resources", "//content/app/strings", "//content/gpu", + "//content/public/common:interfaces", "//content/public/common:service_names", "//content/shell/test_runner:test_runner", "//content/test:content_test_mojo_bindings", @@ -248,6 +249,7 @@ "//mojo/edk/js", "//net", "//net:net_resources", + "//net:test_support", "//ppapi/features", "//sandbox", "//services/service_manager/public/cpp",
diff --git a/content/shell/utility/shell_content_utility_client.cc b/content/shell/utility/shell_content_utility_client.cc index b9b5fb7..1ac9f8d 100644 --- a/content/shell/utility/shell_content_utility_client.cc +++ b/content/shell/utility/shell_content_utility_client.cc
@@ -14,10 +14,14 @@ #include "content/public/child/child_thread.h" #include "content/public/common/service_manager_connection.h" #include "content/public/common/simple_connection_filter.h" +#include "content/public/test/test_host_resolver.h" #include "content/public/test/test_service.h" #include "content/public/test/test_service.mojom.h" #include "mojo/public/cpp/bindings/strong_binding.h" #include "mojo/public/cpp/system/buffer.h" +#include "net/base/net_errors.h" +#include "net/base/network_interfaces.h" +#include "net/dns/mock_host_resolver.h" #include "services/service_manager/public/cpp/binder_registry.h" namespace content { @@ -74,8 +78,36 @@ return std::unique_ptr<service_manager::Service>(new TestService); } +class NetworkServiceTestImpl : public mojom::NetworkServiceTest { + public: + static void Create(mojom::NetworkServiceTestRequest request) { + // Leak this. + new NetworkServiceTestImpl(std::move(request)); + } + explicit NetworkServiceTestImpl(mojom::NetworkServiceTestRequest request) + : binding_(this, std::move(request)) {} + ~NetworkServiceTestImpl() override = default; + + // mojom::NetworkServiceTest implementation. + void AddRules(std::vector<mojom::RulePtr> rules) override { + for (const auto& rule : rules) { + test_host_resolver_.host_resolver()->AddRule(rule->host_pattern, + rule->replacement); + } + } + + private: + mojo::Binding<mojom::NetworkServiceTest> binding_; + + TestHostResolver test_host_resolver_; + + DISALLOW_COPY_AND_ASSIGN(NetworkServiceTestImpl); +}; + } // namespace +ShellContentUtilityClient::ShellContentUtilityClient() {} + ShellContentUtilityClient::~ShellContentUtilityClient() { } @@ -95,4 +127,17 @@ services->insert(std::make_pair(kTestServiceUrl, info)); } +void ShellContentUtilityClient::RegisterNetworkBinders( + service_manager::BinderRegistry* registry) { + registry->AddInterface<mojom::NetworkServiceTest>( + base::Bind(&ShellContentUtilityClient::Create, base::Unretained(this))); +} + +void ShellContentUtilityClient::Create( + mojom::NetworkServiceTestRequest request) { + DCHECK(!network_service_test_); + network_service_test_ = + base::MakeUnique<NetworkServiceTestImpl>(std::move(request)); +} + } // namespace content
diff --git a/content/shell/utility/shell_content_utility_client.h b/content/shell/utility/shell_content_utility_client.h index 3ab2f82b..afb566ae 100644 --- a/content/shell/utility/shell_content_utility_client.h +++ b/content/shell/utility/shell_content_utility_client.h
@@ -5,17 +5,29 @@ #ifndef CONTENT_SHELL_UTILITY_SHELL_CONTENT_UTILITY_CLIENT_H_ #define CONTENT_SHELL_UTILITY_SHELL_CONTENT_UTILITY_CLIENT_H_ +#include "base/macros.h" +#include "content/public/common/network_service_test.mojom.h" #include "content/public/utility/content_utility_client.h" namespace content { class ShellContentUtilityClient : public ContentUtilityClient { public: + ShellContentUtilityClient(); ~ShellContentUtilityClient() override; // ContentUtilityClient: void UtilityThreadStarted() override; void RegisterServices(StaticServiceMap* services) override; + void RegisterNetworkBinders( + service_manager::BinderRegistry* registry) override; + + private: + void Create(mojom::NetworkServiceTestRequest request); + + std::unique_ptr<mojom::NetworkServiceTest> network_service_test_; + + DISALLOW_COPY_AND_ASSIGN(ShellContentUtilityClient); }; } // namespace content
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn index be422b5..dfa827f 100644 --- a/content/test/BUILD.gn +++ b/content/test/BUILD.gn
@@ -106,6 +106,8 @@ "../public/test/test_fileapi_operation_waiter.h", "../public/test/test_frame_navigation_observer.cc", "../public/test/test_frame_navigation_observer.h", + "../public/test/test_host_resolver.cc", + "../public/test/test_host_resolver.h", "../public/test/test_launcher.cc", "../public/test/test_launcher.h", "../public/test/test_navigation_observer.cc", @@ -243,6 +245,8 @@ "//content/gpu", "//content/public/browser", "//content/public/child", + "//content/public/common:interfaces", + "//content/public/common:service_names", "//content/public/renderer", "//content/public/utility", "//content/renderer:for_content_tests",
diff --git a/content/test/data/find_in_embedded_pdf_page.html b/content/test/data/find_in_embedded_pdf_page.html new file mode 100644 index 0000000..a874860 --- /dev/null +++ b/content/test/data/find_in_embedded_pdf_page.html
@@ -0,0 +1,13 @@ +<!DOCTYPE html> +<html> +<head> +<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" /> +</head> +<body> +This a test page for find-in-page with two embedded PDFs. This page should contain 13 matches total for "result".</br> +<iframe src="find_in_pdf_page.pdf"></iframe></br> +result</br> +<iframe src="find_in_pdf_page.pdf"></iframe></br> +result</br> +</body> +</html>
diff --git a/content/utility/utility_service_factory.cc b/content/utility/utility_service_factory.cc index 73c2cf8..734fdeb 100644 --- a/content/utility/utility_service_factory.cc +++ b/content/utility/utility_service_factory.cc
@@ -34,7 +34,8 @@ } // namespace -UtilityServiceFactory::UtilityServiceFactory() {} +UtilityServiceFactory::UtilityServiceFactory() + : network_registry_(base::MakeUnique<service_manager::BinderRegistry>()) {} UtilityServiceFactory::~UtilityServiceFactory() {} @@ -59,8 +60,11 @@ if (base::CommandLine::ForCurrentProcess()->HasSwitch( switches::kEnableNetworkService)) { + GetContentClient()->utility()->RegisterNetworkBinders( + network_registry_.get()); ServiceInfo network_info; - network_info.factory = base::Bind(&NetworkService::CreateNetworkService); + network_info.factory = base::Bind( + &UtilityServiceFactory::CreateNetworkService, base::Unretained(this)); network_info.task_runner = ChildProcess::current()->io_task_runner(); services->insert( std::make_pair(content::mojom::kNetworkServiceName, network_info)); @@ -78,4 +82,9 @@ utility_thread->ReleaseProcessIfNeeded(); } +std::unique_ptr<service_manager::Service> +UtilityServiceFactory::CreateNetworkService() { + return base::MakeUnique<NetworkService>(std::move(network_registry_)); +} + } // namespace content
diff --git a/content/utility/utility_service_factory.h b/content/utility/utility_service_factory.h index 0e561bd..ed4363a5 100644 --- a/content/utility/utility_service_factory.h +++ b/content/utility/utility_service_factory.h
@@ -7,6 +7,7 @@ #include "base/macros.h" #include "content/child/service_factory.h" +#include "services/service_manager/public/cpp/binder_registry.h" namespace content { @@ -24,6 +25,12 @@ private: void OnLoadFailed() override; + std::unique_ptr<service_manager::Service> CreateNetworkService(); + + // Allows embedders to register their interface implementations before the + // network service is created. + std::unique_ptr<service_manager::BinderRegistry> network_registry_; + DISALLOW_COPY_AND_ASSIGN(UtilityServiceFactory); };
diff --git a/device/u2f/mock_u2f_device.cc b/device/u2f/mock_u2f_device.cc index 4f8bdc4..e833bbf6 100644 --- a/device/u2f/mock_u2f_device.cc +++ b/device/u2f/mock_u2f_device.cc
@@ -6,7 +6,7 @@ namespace device { -MockU2fDevice::MockU2fDevice() {} +MockU2fDevice::MockU2fDevice() : weak_factory_(this) {} MockU2fDevice::~MockU2fDevice() {} @@ -50,4 +50,8 @@ cb.Run(); } +base::WeakPtr<U2fDevice> MockU2fDevice::GetWeakPtr() { + return weak_factory_.GetWeakPtr(); +} + } // namespace device
diff --git a/device/u2f/mock_u2f_device.h b/device/u2f/mock_u2f_device.h index f4e65da..fcd7b27 100644 --- a/device/u2f/mock_u2f_device.h +++ b/device/u2f/mock_u2f_device.h
@@ -29,6 +29,7 @@ void(U2fApduCommand* command, const DeviceCallback& cb)); void DeviceTransact(std::unique_ptr<U2fApduCommand> command, const DeviceCallback& cb) override; + base::WeakPtr<U2fDevice> GetWeakPtr() override; static void TransactNoError(std::unique_ptr<U2fApduCommand> command, const DeviceCallback& cb); static void NotSatisfied(U2fApduCommand* cmd, const DeviceCallback& cb); @@ -36,6 +37,9 @@ static void NoErrorSign(U2fApduCommand* cmd, const DeviceCallback& cb); static void NoErrorRegister(U2fApduCommand* cmd, const DeviceCallback& cb); static void WinkDoNothing(const WinkCallback& cb); + + private: + base::WeakPtrFactory<U2fDevice> weak_factory_; }; } // namespace device
diff --git a/device/u2f/u2f_device.cc b/device/u2f/u2f_device.cc index 1b2f2b7..2545cc1 100644 --- a/device/u2f/u2f_device.cc +++ b/device/u2f/u2f_device.cc
@@ -10,8 +10,7 @@ namespace device { -U2fDevice::U2fDevice() - : channel_id_(kBroadcastChannel), capabilities_(0), weak_factory_(this) {} +U2fDevice::U2fDevice() : channel_id_(kBroadcastChannel), capabilities_(0) {} U2fDevice::~U2fDevice() {} @@ -24,9 +23,9 @@ callback.Run(U2fReturnCode::INVALID_PARAMS, std::vector<uint8_t>()); return; } - DeviceTransact(std::move(register_cmd), - base::Bind(&U2fDevice::OnRegisterComplete, - weak_factory_.GetWeakPtr(), callback)); + DeviceTransact( + std::move(register_cmd), + base::Bind(&U2fDevice::OnRegisterComplete, GetWeakPtr(), callback)); } void U2fDevice::Sign(const std::vector<uint8_t>& app_param, @@ -39,9 +38,8 @@ callback.Run(U2fReturnCode::INVALID_PARAMS, std::vector<uint8_t>()); return; } - DeviceTransact(std::move(sign_cmd), - base::Bind(&U2fDevice::OnSignComplete, - weak_factory_.GetWeakPtr(), callback)); + DeviceTransact(std::move(sign_cmd), base::Bind(&U2fDevice::OnSignComplete, + GetWeakPtr(), callback)); } void U2fDevice::Version(const VersionCallback& callback) { @@ -50,9 +48,9 @@ callback.Run(false, ProtocolVersion::UNKNOWN); return; } - DeviceTransact(std::move(version_cmd), - base::Bind(&U2fDevice::OnVersionComplete, - weak_factory_.GetWeakPtr(), callback)); + DeviceTransact( + std::move(version_cmd), + base::Bind(&U2fDevice::OnVersionComplete, GetWeakPtr(), callback)); } void U2fDevice::OnRegisterComplete(
diff --git a/device/u2f/u2f_device.h b/device/u2f/u2f_device.h index 77c8133..9537d44b 100644 --- a/device/u2f/u2f_device.h +++ b/device/u2f/u2f_device.h
@@ -60,6 +60,7 @@ // the device communication transaction. virtual void DeviceTransact(std::unique_ptr<U2fApduCommand> command, const DeviceCallback& callback) = 0; + virtual base::WeakPtr<U2fDevice> GetWeakPtr() = 0; uint32_t channel_id_; uint8_t capabilities_; @@ -82,8 +83,6 @@ bool success, std::unique_ptr<U2fApduResponse> response); - base::WeakPtrFactory<U2fDevice> weak_factory_; - DISALLOW_COPY_AND_ASSIGN(U2fDevice); };
diff --git a/device/u2f/u2f_hid_device.cc b/device/u2f/u2f_hid_device.cc index 27e1f7b..e54cf9a 100644 --- a/device/u2f/u2f_hid_device.cc +++ b/device/u2f/u2f_hid_device.cc
@@ -342,4 +342,8 @@ return command_line->HasSwitch(switches::kEnableU2fHidTest); } +base::WeakPtr<U2fDevice> U2fHidDevice::GetWeakPtr() { + return weak_factory_.GetWeakPtr(); +} + } // namespace device
diff --git a/device/u2f/u2f_hid_device.h b/device/u2f/u2f_hid_device.h index 84694f4b..64bc0f2 100644 --- a/device/u2f/u2f_hid_device.h +++ b/device/u2f/u2f_hid_device.h
@@ -90,6 +90,7 @@ void OnTimeout(const DeviceCallback& callback); void OnDeviceTransact(bool success, std::unique_ptr<U2fApduResponse> response); + base::WeakPtr<U2fDevice> GetWeakPtr() override; State state_; base::CancelableClosure timeout_callback_;
diff --git a/docs/android_build_instructions.md b/docs/android_build_instructions.md index c16d2751..1a729fea0 100644 --- a/docs/android_build_instructions.md +++ b/docs/android_build_instructions.md
@@ -214,8 +214,7 @@ ``` this will build and install an Android apk under -`out/Default/apks/ContentShell.apk`. (Where `Release` is the name of your build -directory.) +`out/Default/apks/ContentShell.apk`. If you use custom out dir instead of standard out/ dir, use CHROMIUM_OUT_DIR env.
diff --git a/extensions/browser/api/cast_channel/cast_message_util.cc b/extensions/browser/api/cast_channel/cast_message_util.cc index 95ba5d4..3b64661 100644 --- a/extensions/browser/api/cast_channel/cast_message_util.cc +++ b/extensions/browser/api/cast_channel/cast_message_util.cc
@@ -49,8 +49,8 @@ // JS ArrayBuffer case base::Value::Type::BINARY: message_proto->set_payload_type(CastMessage_PayloadType_BINARY); - message_proto->set_payload_binary(message.data->GetBuffer(), - message.data->GetSize()); + message_proto->set_payload_binary(message.data->GetBlob().data(), + message.data->GetBlob().size()); break; default: // Unknown value type. message_proto will remain uninitialized because
diff --git a/extensions/browser/api/declarative/declarative_api.cc b/extensions/browser/api/declarative/declarative_api.cc index b2393b2c..863f92ed 100644 --- a/extensions/browser/api/declarative/declarative_api.cc +++ b/extensions/browser/api/declarative/declarative_api.cc
@@ -42,7 +42,7 @@ // Encodes |binary| as base64 and returns a new StringValue populated with the // encoded string. std::unique_ptr<base::Value> ConvertBinaryToBase64(base::Value* binary) { - std::string binary_data = std::string(binary->GetBuffer(), binary->GetSize()); + std::string binary_data(binary->GetBlob().data(), binary->GetBlob().size()); std::string data64; base::Base64Encode(binary_data, &data64); return std::unique_ptr<base::Value>(new base::Value(data64));
diff --git a/extensions/browser/api/socket/socket_api.cc b/extensions/browser/api/socket/socket_api.cc index 8a84f46..bb3d438 100644 --- a/extensions/browser/api/socket/socket_api.cc +++ b/extensions/browser/api/socket/socket_api.cc
@@ -539,8 +539,8 @@ base::Value* data = NULL; EXTENSION_FUNCTION_VALIDATE(args_->GetBinary(1, &data)); - io_buffer_size_ = data->GetSize(); - io_buffer_ = new net::WrappedIOBuffer(data->GetBuffer()); + io_buffer_size_ = data->GetBlob().size(); + io_buffer_ = new net::WrappedIOBuffer(data->GetBlob().data()); return true; } @@ -627,8 +627,8 @@ } port_ = static_cast<uint16_t>(port); - io_buffer_size_ = data->GetSize(); - io_buffer_ = new net::WrappedIOBuffer(data->GetBuffer()); + io_buffer_size_ = data->GetBlob().size(); + io_buffer_ = new net::WrappedIOBuffer(data->GetBlob().data()); return true; }
diff --git a/extensions/browser/guest_view/extension_options/extension_options_guest.cc b/extensions/browser/guest_view/extension_options/extension_options_guest.cc index 3441ba9..38c4da35 100644 --- a/extensions/browser/guest_view/extension_options/extension_options_guest.cc +++ b/extensions/browser/guest_view/extension_options/extension_options_guest.cc
@@ -154,10 +154,6 @@ options.ToValue())); } -bool ExtensionOptionsGuest::ShouldHandleFindRequestsForEmbedder() const { - return true; -} - WebContents* ExtensionOptionsGuest::OpenURLFromTab( WebContents* source, const content::OpenURLParams& params) {
diff --git a/extensions/browser/guest_view/extension_options/extension_options_guest.h b/extensions/browser/guest_view/extension_options/extension_options_guest.h index 2bb2790..6b2933a 100644 --- a/extensions/browser/guest_view/extension_options/extension_options_guest.h +++ b/extensions/browser/guest_view/extension_options/extension_options_guest.h
@@ -35,7 +35,6 @@ int GetTaskPrefix() const final; bool IsPreferredSizeModeEnabled() const final; void OnPreferredSizeChanged(const gfx::Size& pref_size) final; - bool ShouldHandleFindRequestsForEmbedder() const final; // content::WebContentsDelegate implementation. content::WebContents* OpenURLFromTab(
diff --git a/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.cc b/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.cc index 44793e9..ccc6b74 100644 --- a/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.cc +++ b/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.cc
@@ -195,10 +195,6 @@ ExtensionsAPIClient::Get()->AttachWebContentsHelpers(web_contents()); } -bool MimeHandlerViewGuest::ShouldHandleFindRequestsForEmbedder() const { - return is_full_page_plugin(); -} - bool MimeHandlerViewGuest::ZoomPropagatesFromEmbedderToGuest() const { return false; }
diff --git a/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h b/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h index d237318..dd4e55e 100644 --- a/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h +++ b/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h
@@ -80,7 +80,6 @@ const WebContentsCreatedCallback& callback) override; void DidAttachToEmbedder() override; void DidInitialize(const base::DictionaryValue& create_params) final; - bool ShouldHandleFindRequestsForEmbedder() const final; bool ZoomPropagatesFromEmbedderToGuest() const final; // WebContentsDelegate implementation.
diff --git a/extensions/browser/guest_view/web_view/web_view_guest.cc b/extensions/browser/guest_view/web_view/web_view_guest.cc index 6489fc6..a72785d8 100644 --- a/extensions/browser/guest_view/web_view/web_view_guest.cc +++ b/extensions/browser/guest_view/web_view/web_view_guest.cc
@@ -1039,12 +1039,6 @@ manager->SignalOnScriptsLoaded(callback); } -bool WebViewGuest::ShouldHandleFindRequestsForEmbedder() const { - if (web_view_guest_delegate_) - return web_view_guest_delegate_->ShouldHandleFindRequestsForEmbedder(); - return false; -} - void WebViewGuest::WillAttachToEmbedder() { rules_registry_id_ = GetOrGenerateRulesRegistryID( owner_web_contents()->GetRenderProcessHost()->GetID(),
diff --git a/extensions/browser/guest_view/web_view/web_view_guest.h b/extensions/browser/guest_view/web_view/web_view_guest.h index 2a3befd5..270007a 100644 --- a/extensions/browser/guest_view/web_view/web_view_guest.h +++ b/extensions/browser/guest_view/web_view/web_view_guest.h
@@ -191,7 +191,6 @@ bool IsAutoSizeSupported() const final; void SetContextMenuPosition(const gfx::Point& position) final; void SignalWhenReady(const base::Closure& callback) final; - bool ShouldHandleFindRequestsForEmbedder() const final; void WillAttachToEmbedder() final; void WillDestroy() final;
diff --git a/extensions/browser/process_manager.cc b/extensions/browser/process_manager.cc index da355fc..7ebfcd9 100644 --- a/extensions/browser/process_manager.cc +++ b/extensions/browser/process_manager.cc
@@ -248,7 +248,9 @@ content::DevToolsAgentHost::AddObserver(this); } -ProcessManager::~ProcessManager() = default; +ProcessManager::~ProcessManager() { + content::DevToolsAgentHost::RemoveObserver(this); +} void ProcessManager::Shutdown() { extension_registry_->RemoveObserver(this);
diff --git a/extensions/renderer/api_binding.cc b/extensions/renderer/api_binding.cc index 9abc53e..9e1aee5 100644 --- a/extensions/renderer/api_binding.cc +++ b/extensions/renderer/api_binding.cc
@@ -474,12 +474,13 @@ if (!IsContextValid(context)) return; + v8::Context::Scope context_scope(context); CHECK(info.Data()->IsExternal()); auto* property_data = static_cast<CustomPropertyData*>(info.Data().As<v8::External>()->Value()); v8::Local<v8::Object> property = property_data->create_custom_type.Run( - context, property_data->type_name, property_data->property_name, + isolate, property_data->type_name, property_data->property_name, property_data->property_values); if (property.IsEmpty()) return;
diff --git a/extensions/renderer/api_binding.h b/extensions/renderer/api_binding.h index 972df11..8e20a97e 100644 --- a/extensions/renderer/api_binding.h +++ b/extensions/renderer/api_binding.h
@@ -42,7 +42,7 @@ class APIBinding { public: using CreateCustomType = base::Callback<v8::Local<v8::Object>( - v8::Local<v8::Context> context, + v8::Isolate* isolate, const std::string& type_name, const std::string& property_name, const base::ListValue* property_values)>;
diff --git a/extensions/renderer/api_binding_unittest.cc b/extensions/renderer/api_binding_unittest.cc index d17e720..389fe96 100644 --- a/extensions/renderer/api_binding_unittest.cc +++ b/extensions/renderer/api_binding_unittest.cc
@@ -631,11 +631,11 @@ " 'value': ['b']" " }" "}"); - auto create_custom_type = [](v8::Local<v8::Context> context, + auto create_custom_type = [](v8::Isolate* isolate, const std::string& type_name, const std::string& property_name, const base::ListValue* property_values) { - v8::Isolate* isolate = context->GetIsolate(); + v8::Local<v8::Context> context = isolate->GetCurrentContext(); v8::Local<v8::Object> result = v8::Object::New(isolate); if (type_name == "AlphaRef") { EXPECT_EQ("alpha", property_name);
diff --git a/extensions/renderer/api_bindings_system.cc b/extensions/renderer/api_bindings_system.cc index 29e38c8..358eb6605 100644 --- a/extensions/renderer/api_bindings_system.cc +++ b/extensions/renderer/api_bindings_system.cc
@@ -130,13 +130,13 @@ } v8::Local<v8::Object> APIBindingsSystem::CreateCustomType( - v8::Local<v8::Context> context, + v8::Isolate* isolate, const std::string& type_name, const std::string& property_name, const base::ListValue* property_values) { auto iter = custom_types_.find(type_name); DCHECK(iter != custom_types_.end()) << "Custom type not found: " << type_name; - return iter->second.Run(context, property_name, property_values, + return iter->second.Run(isolate, property_name, property_values, &request_handler_, &event_handler_, &type_reference_map_); }
diff --git a/extensions/renderer/api_bindings_system.h b/extensions/renderer/api_bindings_system.h index 138d42d9..1b32dfb 100644 --- a/extensions/renderer/api_bindings_system.h +++ b/extensions/renderer/api_bindings_system.h
@@ -34,7 +34,7 @@ using GetAPISchemaMethod = base::Callback<const base::DictionaryValue&(const std::string&)>; using CustomTypeHandler = base::Callback<v8::Local<v8::Object>( - v8::Local<v8::Context> context, + v8::Isolate* isolate, const std::string& property_name, const base::ListValue* property_values, APIRequestHandler* request_handler, @@ -102,7 +102,7 @@ // Handles creating the type for the specified property. v8::Local<v8::Object> CreateCustomType( - v8::Local<v8::Context> context, + v8::Isolate* isolate, const std::string& type_name, const std::string& property_name, const base::ListValue* property_values);
diff --git a/extensions/renderer/chrome_setting.cc b/extensions/renderer/chrome_setting.cc index 81f1ca2..cb3b27b 100644 --- a/extensions/renderer/chrome_setting.cc +++ b/extensions/renderer/chrome_setting.cc
@@ -18,7 +18,7 @@ namespace extensions { v8::Local<v8::Object> ChromeSetting::Create( - v8::Local<v8::Context> context, + v8::Isolate* isolate, const std::string& property_name, const base::ListValue* property_values, APIRequestHandler* request_handler, @@ -29,10 +29,9 @@ const base::DictionaryValue* value_spec = nullptr; CHECK(property_values->GetDictionary(1u, &value_spec)); - gin::Handle<ChromeSetting> handle = - gin::CreateHandle(context->GetIsolate(), - new ChromeSetting(request_handler, event_handler, - type_refs, pref_name, *value_spec)); + gin::Handle<ChromeSetting> handle = gin::CreateHandle( + isolate, new ChromeSetting(request_handler, event_handler, type_refs, + pref_name, *value_spec)); return handle.ToV8().As<v8::Object>(); }
diff --git a/extensions/renderer/chrome_setting.h b/extensions/renderer/chrome_setting.h index d5bbba27..11b7dc2 100644 --- a/extensions/renderer/chrome_setting.h +++ b/extensions/renderer/chrome_setting.h
@@ -31,7 +31,7 @@ ~ChromeSetting() override; // Creates a ChromeSetting object for the given property. - static v8::Local<v8::Object> Create(v8::Local<v8::Context> context, + static v8::Local<v8::Object> Create(v8::Isolate* isolate, const std::string& property_name, const base::ListValue* property_values, APIRequestHandler* request_handler,
diff --git a/extensions/renderer/content_setting.cc b/extensions/renderer/content_setting.cc index aafc6d7e..ffa0858 100644 --- a/extensions/renderer/content_setting.cc +++ b/extensions/renderer/content_setting.cc
@@ -35,7 +35,7 @@ v8::Local<v8::Object> ContentSetting::Create( const binding::RunJSFunction& run_js, - v8::Local<v8::Context> context, + v8::Isolate* isolate, const std::string& property_name, const base::ListValue* property_values, APIRequestHandler* request_handler, @@ -46,10 +46,9 @@ const base::DictionaryValue* value_spec = nullptr; CHECK(property_values->GetDictionary(1u, &value_spec)); - gin::Handle<ContentSetting> handle = - gin::CreateHandle(context->GetIsolate(), - new ContentSetting(run_js, request_handler, type_refs, - pref_name, *value_spec)); + gin::Handle<ContentSetting> handle = gin::CreateHandle( + isolate, new ContentSetting(run_js, request_handler, type_refs, pref_name, + *value_spec)); return handle.ToV8().As<v8::Object>(); }
diff --git a/extensions/renderer/content_setting.h b/extensions/renderer/content_setting.h index cfc3db1..8f1dfb9 100644 --- a/extensions/renderer/content_setting.h +++ b/extensions/renderer/content_setting.h
@@ -34,7 +34,7 @@ // Creates a ContentSetting object for the given property. static v8::Local<v8::Object> Create(const binding::RunJSFunction& run_js, - v8::Local<v8::Context> context, + v8::Isolate* isolate, const std::string& property_name, const base::ListValue* property_values, APIRequestHandler* request_handler,
diff --git a/extensions/renderer/storage_area.cc b/extensions/renderer/storage_area.cc index b952460..e8d0ce6 100644 --- a/extensions/renderer/storage_area.cc +++ b/extensions/renderer/storage_area.cc
@@ -150,28 +150,25 @@ // static v8::Local<v8::Object> StorageArea::CreateStorageArea( - v8::Local<v8::Context> context, + v8::Isolate* isolate, const std::string& property_name, const base::ListValue* property_values, APIRequestHandler* request_handler, APIEventHandler* event_handler, APITypeReferenceMap* type_refs) { - v8::Context::Scope context_scope(context); v8::Local<v8::Object> object; if (property_name == "local") { - gin::Handle<LocalStorageArea> handle = - gin::CreateHandle(context->GetIsolate(), - new LocalStorageArea(request_handler, type_refs)); + gin::Handle<LocalStorageArea> handle = gin::CreateHandle( + isolate, new LocalStorageArea(request_handler, type_refs)); object = handle.ToV8().As<v8::Object>(); } else if (property_name == "sync") { gin::Handle<SyncStorageArea> handle = gin::CreateHandle( - context->GetIsolate(), new SyncStorageArea(request_handler, type_refs)); + isolate, new SyncStorageArea(request_handler, type_refs)); object = handle.ToV8().As<v8::Object>(); } else { CHECK_EQ("managed", property_name); - gin::Handle<ManagedStorageArea> handle = - gin::CreateHandle(context->GetIsolate(), - new ManagedStorageArea(request_handler, type_refs)); + gin::Handle<ManagedStorageArea> handle = gin::CreateHandle( + isolate, new ManagedStorageArea(request_handler, type_refs)); object = handle.ToV8().As<v8::Object>(); } return object;
diff --git a/extensions/renderer/storage_area.h b/extensions/renderer/storage_area.h index 40aa1094..f5abaeb 100644 --- a/extensions/renderer/storage_area.h +++ b/extensions/renderer/storage_area.h
@@ -35,7 +35,7 @@ // Creates a StorageArea object for the given context and property name. static v8::Local<v8::Object> CreateStorageArea( - v8::Local<v8::Context> context, + v8::Isolate* isolate, const std::string& property_name, const base::ListValue* property_values, APIRequestHandler* request_handler,
diff --git a/ipc/ipc_message_utils.cc b/ipc/ipc_message_utils.cc index 23cfd133..9a8630dc 100644 --- a/ipc/ipc_message_utils.cc +++ b/ipc/ipc_message_utils.cc
@@ -110,7 +110,7 @@ break; } case base::Value::Type::BINARY: { - sizer->AddData(static_cast<int>(value->GetSize())); + sizer->AddData(static_cast<int>(value->GetBlob().size())); break; } case base::Value::Type::DICTIONARY: { @@ -178,7 +178,8 @@ break; } case base::Value::Type::BINARY: { - m->WriteData(value->GetBuffer(), static_cast<int>(value->GetSize())); + m->WriteData(value->GetBlob().data(), + static_cast<int>(value->GetBlob().size())); break; } case base::Value::Type::DICTIONARY: {
diff --git a/media/base/android/android_cdm_factory.cc b/media/base/android/android_cdm_factory.cc index 08a43b8..286cf0d9 100644 --- a/media/base/android/android_cdm_factory.cc +++ b/media/base/android/android_cdm_factory.cc
@@ -49,7 +49,7 @@ IsExternalClearKey(key_system)) { scoped_refptr<ContentDecryptionModule> cdm( new AesDecryptor(security_origin, session_message_cb, session_closed_cb, - session_keys_change_cb)); + session_keys_change_cb, session_expiration_update_cb)); bound_cdm_created_cb.Run(cdm, ""); return; }
diff --git a/media/base/video_frame_metadata.cc b/media/base/video_frame_metadata.cc index 292274e5..5b65cd2f 100644 --- a/media/base/video_frame_metadata.cc +++ b/media/base/video_frame_metadata.cc
@@ -111,7 +111,8 @@ DCHECK(value); const base::Value* const binary_value = GetBinaryValue(key); if (binary_value) - value->assign(binary_value->GetBuffer(), binary_value->GetSize()); + value->assign(binary_value->GetBlob().data(), + binary_value->GetBlob().size()); return !!binary_value; } @@ -120,9 +121,10 @@ bool ToTimeValue(const base::Value& binary_value, TimeType* value) { DCHECK(value); int64_t internal_value; - if (binary_value.GetSize() != sizeof(internal_value)) + if (binary_value.GetBlob().size() != sizeof(internal_value)) return false; - memcpy(&internal_value, binary_value.GetBuffer(), sizeof(internal_value)); + memcpy(&internal_value, binary_value.GetBlob().data(), + sizeof(internal_value)); *value = TimeType::FromInternalValue(internal_value); return true; }
diff --git a/media/blink/webcontentdecryptionmodulesession_impl.cc b/media/blink/webcontentdecryptionmodulesession_impl.cc index c751232..7460c728 100644 --- a/media/blink/webcontentdecryptionmodulesession_impl.cc +++ b/media/blink/webcontentdecryptionmodulesession_impl.cc
@@ -252,6 +252,7 @@ : adapter_(adapter), has_close_been_called_(false), is_closed_(false), + is_persistent_session_(false), weak_ptr_factory_(this) {} WebContentDecryptionModuleSessionImpl:: @@ -357,8 +358,11 @@ // 10.8 Let cdm be the CDM instance represented by this object's cdm // instance value. // 10.9 Use the cdm to execute the following steps: + CdmSessionType cdm_session_type = convertSessionType(session_type); + is_persistent_session_ = + cdm_session_type != CdmSessionType::TEMPORARY_SESSION; adapter_->InitializeNewSession( - eme_init_data_type, sanitized_init_data, convertSessionType(session_type), + eme_init_data_type, sanitized_init_data, cdm_session_type, std::unique_ptr<NewSessionCdmPromise>(new NewSessionCdmResultPromise( result, adapter_->GetKeySystemUMAPrefix(), kGenerateRequestUMAName, base::Bind( @@ -391,6 +395,7 @@ // TODO(jrummell): Now that there are 2 types of persistent sessions, the // session type should be passed from blink. Type should also be passed in the // constructor (and removed from initializeNewSession()). + is_persistent_session_ = true; adapter_->LoadSession( CdmSessionType::PERSISTENT_LICENSE_SESSION, sanitized_session_id, std::unique_ptr<NewSessionCdmPromise>(new NewSessionCdmResultPromise( @@ -459,6 +464,16 @@ blink::WebContentDecryptionModuleResult result) { DCHECK(!session_id_.empty()); DCHECK(thread_checker_.CalledOnValidThread()); + + // TODO(http://crbug.com/616166). Once all supported CDMs allow remove() on + // temporary sessions, remove this code. + if (!is_persistent_session_ && !IsClearKey(adapter_->GetKeySystem())) { + result.CompleteWithError( + blink::kWebContentDecryptionModuleExceptionTypeError, 0, + "remove() on temporary sessions is not supported by this key system."); + return; + } + adapter_->RemoveSession( session_id_, std::unique_ptr<SimpleCdmPromise>(new CdmResultPromise<>(
diff --git a/media/blink/webcontentdecryptionmodulesession_impl.h b/media/blink/webcontentdecryptionmodulesession_impl.h index 9b7cdf2a..d1ec07d 100644 --- a/media/blink/webcontentdecryptionmodulesession_impl.h +++ b/media/blink/webcontentdecryptionmodulesession_impl.h
@@ -84,6 +84,9 @@ bool has_close_been_called_; bool is_closed_; + // Keep track of whether this is a persistent session or not. + bool is_persistent_session_; + base::ThreadChecker thread_checker_; // Since promises will live until they are fired, use a weak reference when // creating a promise in case this class disappears before the promise
diff --git a/media/capture/video/android/java/src/org/chromium/media/VideoCaptureCamera2.java b/media/capture/video/android/java/src/org/chromium/media/VideoCaptureCamera2.java index ef97261..aa828a7 100644 --- a/media/capture/video/android/java/src/org/chromium/media/VideoCaptureCamera2.java +++ b/media/capture/video/android/java/src/org/chromium/media/VideoCaptureCamera2.java
@@ -805,8 +805,12 @@ break; } } - if (cameraCharacteristics.get(CameraCharacteristics.CONTROL_AE_LOCK_AVAILABLE)) { - exposureModes.add(Integer.valueOf(AndroidMeteringMode.FIXED)); + try { + if (cameraCharacteristics.get(CameraCharacteristics.CONTROL_AE_LOCK_AVAILABLE)) { + exposureModes.add(Integer.valueOf(AndroidMeteringMode.FIXED)); + } + } catch (NoSuchFieldError e) { + // Ignore this exception, it means CONTROL_AE_LOCK_AVAILABLE is not known. } builder.setExposureModes(integerArrayListToArray(exposureModes)); @@ -840,8 +844,12 @@ break; } } - if (cameraCharacteristics.get(CameraCharacteristics.CONTROL_AWB_LOCK_AVAILABLE)) { - whiteBalanceModes.add(Integer.valueOf(AndroidMeteringMode.FIXED)); + try { + if (cameraCharacteristics.get(CameraCharacteristics.CONTROL_AWB_LOCK_AVAILABLE)) { + whiteBalanceModes.add(Integer.valueOf(AndroidMeteringMode.FIXED)); + } + } catch (NoSuchFieldError e) { + // Ignore this exception, it means CONTROL_AWB_LOCK_AVAILABLE is not known. } builder.setWhiteBalanceModes(integerArrayListToArray(whiteBalanceModes));
diff --git a/media/cdm/aes_decryptor.cc b/media/cdm/aes_decryptor.cc index b30a5ed..5c5f296 100644 --- a/media/cdm/aes_decryptor.cc +++ b/media/cdm/aes_decryptor.cc
@@ -15,7 +15,6 @@ #include "crypto/encryptor.h" #include "crypto/symmetric_key.h" #include "media/base/audio_decoder_config.h" -#include "media/base/cdm_key_information.h" #include "media/base/cdm_promise.h" #include "media/base/decoder_buffer.h" #include "media/base/decrypt_config.h" @@ -231,13 +230,16 @@ return output; } -AesDecryptor::AesDecryptor(const GURL& /* security_origin */, - const SessionMessageCB& session_message_cb, - const SessionClosedCB& session_closed_cb, - const SessionKeysChangeCB& session_keys_change_cb) +AesDecryptor::AesDecryptor( + const GURL& /* security_origin */, + const SessionMessageCB& session_message_cb, + const SessionClosedCB& session_closed_cb, + const SessionKeysChangeCB& session_keys_change_cb, + const SessionExpirationUpdateCB& session_expiration_update_cb) : session_message_cb_(session_message_cb), session_closed_cb_(session_closed_cb), - session_keys_change_cb_(session_keys_change_cb) { + session_keys_change_cb_(session_keys_change_cb), + session_expiration_update_cb_(session_expiration_update_cb) { // AesDecryptor doesn't keep any persistent data, so no need to do anything // with |security_origin|. DCHECK(!session_message_cb_.is_null()); @@ -391,19 +393,9 @@ promise->resolve(); - // Create the list of all available keys for this session. - CdmKeysInfo keys_info; - { - base::AutoLock auto_lock(key_map_lock_); - for (const auto& item : key_map_) { - if (item.second->Contains(session_id)) { - keys_info.push_back( - new CdmKeyInformation(item.first, CdmKeyInformation::USABLE, 0)); - } - } - } - - session_keys_change_cb_.Run(session_id, key_added, std::move(keys_info)); + session_keys_change_cb_.Run( + session_id, key_added, + GenerateKeysInfoList(session_id, CdmKeyInformation::USABLE)); } // Runs the parallel steps from https://w3c.github.io/encrypted-media/#close. @@ -437,11 +429,57 @@ promise->resolve(); } +// Runs the parallel steps from https://w3c.github.io/encrypted-media/#remove. void AesDecryptor::RemoveSession(const std::string& session_id, std::unique_ptr<SimpleCdmPromise> promise) { - NOTIMPLEMENTED() << "Need to address https://crbug.com/616166."; - promise->reject(CdmPromise::INVALID_ACCESS_ERROR, 0, - "Session does not exist."); + std::set<std::string>::iterator it = open_sessions_.find(session_id); + if (it == open_sessions_.end()) { + // Session doesn't exist. Since this should only be called if the session + // existed at one time, this must mean the session has been closed. + promise->reject(CdmPromise::INVALID_STATE_ERROR, 0, + "The session is already closed."); + return; + } + + // Create the list of all existing keys for this session. They will be + // removed, so set the status to "released". + CdmKeysInfo keys_info = + GenerateKeysInfoList(session_id, CdmKeyInformation::RELEASED); + + // 4.1. Let cdm be the CDM instance represented by session's cdm instance + // value. + // 4.2 Let message be null. + // 4.3 Let message type be null. + // 4.4 Use the cdm to execute the following steps: + // 4.4.1.1 Destroy the license(s) and/or key(s) associated with the session. + DeleteKeysForSession(session_id); + + // 4.4.1.2 Follow the steps for the value of this object's session type + // from the following list: + // "temporary" + // Continue with the following steps. + // "persistent-license" + // (Not supported, so no need to do anything.) + + // 4.5. Queue a task to run the following steps: + // 4.5.1 Run the Update Key Statuses algorithm on the session, providing + // all key ID(s) in the session along with the "released" + // MediaKeyStatus value for each. + session_keys_change_cb_.Run(session_id, false, std::move(keys_info)); + + // 4.5.2 Run the Update Expiration algorithm on the session, providing NaN. + session_expiration_update_cb_.Run(session_id, base::Time()); + + // 4.5.3 If any of the preceding steps failed, reject promise with a new + // DOMException whose name is the appropriate error name. + // 4.5.4 Let message type be "license-release". + // 4.5.5 If message is not null, run the Queue a "message" Event algorithm + // on the session, providing message type and message. + // (Not needed as message is only set for persistent licenses, and they're + // not supported here.) + + // 4.5.6. Resolve promise. + promise->resolve(); } CdmContext* AesDecryptor::GetCdmContext() { @@ -608,6 +646,22 @@ } } +CdmKeysInfo AesDecryptor::GenerateKeysInfoList( + const std::string& session_id, + CdmKeyInformation::KeyStatus status) { + // Create the list of all available keys for this session. + CdmKeysInfo keys_info; + { + base::AutoLock auto_lock(key_map_lock_); + for (const auto& item : key_map_) { + if (item.second->Contains(session_id)) { + keys_info.push_back(new CdmKeyInformation(item.first, status, 0)); + } + } + } + return keys_info; +} + AesDecryptor::DecryptionKey::DecryptionKey(const std::string& secret) : secret_(secret) { }
diff --git a/media/cdm/aes_decryptor.h b/media/cdm/aes_decryptor.h index f82b943..ef13083a 100644 --- a/media/cdm/aes_decryptor.h +++ b/media/cdm/aes_decryptor.h
@@ -17,6 +17,7 @@ #include "base/memory/ref_counted.h" #include "base/synchronization/lock.h" #include "media/base/cdm_context.h" +#include "media/base/cdm_key_information.h" #include "media/base/content_decryption_module.h" #include "media/base/decryptor.h" #include "media/base/media_export.h" @@ -38,7 +39,8 @@ AesDecryptor(const GURL& security_origin, const SessionMessageCB& session_message_cb, const SessionClosedCB& session_closed_cb, - const SessionKeysChangeCB& session_keys_change_cb); + const SessionKeysChangeCB& session_keys_change_cb, + const SessionExpirationUpdateCB& session_expiration_update_cb); // ContentDecryptionModule implementation. void SetServerCertificate(const std::vector<uint8_t>& certificate, @@ -135,10 +137,14 @@ // Deletes all keys associated with |session_id|. void DeleteKeysForSession(const std::string& session_id); + CdmKeysInfo GenerateKeysInfoList(const std::string& session_id, + CdmKeyInformation::KeyStatus status); + // Callbacks for firing session events. SessionMessageCB session_message_cb_; SessionClosedCB session_closed_cb_; SessionKeysChangeCB session_keys_change_cb_; + SessionExpirationUpdateCB session_expiration_update_cb_; // Since only Decrypt() is called off the renderer thread, we only need to // protect |key_map_|, the only member variable that is shared between
diff --git a/media/cdm/aes_decryptor_unittest.cc b/media/cdm/aes_decryptor_unittest.cc index 5e80c79a..856a2e57 100644 --- a/media/cdm/aes_decryptor_unittest.cc +++ b/media/cdm/aes_decryptor_unittest.cc
@@ -252,6 +252,8 @@ base::Bind(&MockCdmClient::OnSessionClosed, base::Unretained(&cdm_client_)), base::Bind(&MockCdmClient::OnSessionKeysChange, + base::Unretained(&cdm_client_)), + base::Bind(&MockCdmClient::OnSessionExpirationUpdate, base::Unretained(&cdm_client_))), std::string()); } else if (GetParam() == "CdmAdapter") { @@ -348,10 +350,12 @@ cdm_->CloseSession(session_id, CreatePromise(RESOLVED)); } - // Only persistent sessions can be removed. + // Removes the session specified by |session_id|. void RemoveSession(const std::string& session_id) { - // TODO(ddorwin): This should be RESOLVED after https://crbug.com/616166. - cdm_->RemoveSession(session_id, CreatePromise(REJECTED)); + EXPECT_CALL(cdm_client_, OnSessionKeysChangeCalled(session_id, false)); + EXPECT_CALL(cdm_client_, + OnSessionExpirationUpdate(session_id, IsNullTime())); + cdm_->RemoveSession(session_id, CreatePromise(RESOLVED)); } // Updates the session specified by |session_id| with |key|. |result| @@ -380,10 +384,14 @@ CreatePromise(expected_result)); } - bool KeysInfoContains(const std::vector<uint8_t>& expected) { + bool KeysInfoContains(const std::vector<uint8_t>& expected_key_id, + CdmKeyInformation::KeyStatus expected_status = + CdmKeyInformation::USABLE) { for (auto* key_id : cdm_client_.keys_info()) { - if (key_id->key_id == expected) + if (key_id->key_id == expected_key_id && + key_id->status == expected_status) { return true; + } } return false; } @@ -781,6 +789,26 @@ DecryptAndExpect(encrypted_buffer, original_data_, SUCCESS)); RemoveSession(session_id); + ASSERT_NO_FATAL_FAILURE( + DecryptAndExpect(encrypted_buffer, original_data_, NO_KEY)); +} + +TEST_P(AesDecryptorTest, RemoveThenCloseSession) { + std::string session_id = CreateSession(key_id_); + scoped_refptr<DecoderBuffer> encrypted_buffer = CreateEncryptedBuffer( + encrypted_data_, key_id_, iv_, no_subsample_entries_); + + UpdateSessionAndExpect(session_id, kKeyAsJWK, RESOLVED, true); + EXPECT_TRUE(KeysInfoContains(key_id_, CdmKeyInformation::USABLE)); + ASSERT_NO_FATAL_FAILURE( + DecryptAndExpect(encrypted_buffer, original_data_, SUCCESS)); + + RemoveSession(session_id); + EXPECT_TRUE(KeysInfoContains(key_id_, CdmKeyInformation::RELEASED)); + ASSERT_NO_FATAL_FAILURE( + DecryptAndExpect(encrypted_buffer, original_data_, NO_KEY)); + + CloseSession(session_id); } TEST_P(AesDecryptorTest, NoKeyAfterCloseSession) {
diff --git a/media/cdm/default_cdm_factory.cc b/media/cdm/default_cdm_factory.cc index ca80838..7a150df4 100644 --- a/media/cdm/default_cdm_factory.cc +++ b/media/cdm/default_cdm_factory.cc
@@ -58,7 +58,7 @@ scoped_refptr<ContentDecryptionModule> cdm( new AesDecryptor(security_origin, session_message_cb, session_closed_cb, - session_keys_change_cb)); + session_keys_change_cb, session_expiration_update_cb)); base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::Bind(cdm_created_cb, cdm, "")); }
diff --git a/media/cdm/ppapi/external_clear_key/clear_key_cdm.cc b/media/cdm/ppapi/external_clear_key/clear_key_cdm.cc index 18e4f87..80097750 100644 --- a/media/cdm/ppapi/external_clear_key/clear_key_cdm.cc +++ b/media/cdm/ppapi/external_clear_key/clear_key_cdm.cc
@@ -330,7 +330,8 @@ origin, base::Bind(&ClearKeyCdm::OnSessionMessage, base::Unretained(this)), base::Bind(&ClearKeyCdm::OnSessionClosed, base::Unretained(this)), - base::Bind(&ClearKeyCdm::OnSessionKeysChange, + base::Bind(&ClearKeyCdm::OnSessionKeysChange, base::Unretained(this)), + base::Bind(&ClearKeyCdm::OnSessionExpirationUpdate, base::Unretained(this)))), host_(host), key_system_(key_system), @@ -489,19 +490,8 @@ std::string web_session_str(session_id, session_id_length); // RemoveSession only allowed for the loadable session. - if (web_session_str == std::string(kLoadableSessionId)) { + if (web_session_str == std::string(kLoadableSessionId)) web_session_str = session_id_for_emulated_loadsession_; - } else { - // TODO(jrummell): This should be a DCHECK once blink does the proper - // checks. - std::string message("Not supported for non-persistent sessions."); - host_->OnRejectPromise(promise_id, - cdm::kInvalidAccessError, - 0, - message.data(), - message.length()); - return; - } std::unique_ptr<media::SimpleCdmPromise> promise( new media::CdmCallbackPromise<>( @@ -892,6 +882,15 @@ host_->OnSessionClosed(new_session_id.data(), new_session_id.length()); } +void ClearKeyCdm::OnSessionExpirationUpdate(const std::string& session_id, + base::Time new_expiry_time) { + std::string new_session_id = session_id; + if (new_session_id == session_id_for_emulated_loadsession_) + new_session_id = std::string(kLoadableSessionId); + host_->OnExpirationChange(new_session_id.data(), new_session_id.length(), + new_expiry_time.ToDoubleT()); +} + void ClearKeyCdm::OnSessionCreated(uint32_t promise_id, const std::string& session_id) { // Save the latest session ID for renewal and file IO test messages.
diff --git a/media/cdm/ppapi/external_clear_key/clear_key_cdm.h b/media/cdm/ppapi/external_clear_key/clear_key_cdm.h index a410aee..66b77e9f 100644 --- a/media/cdm/ppapi/external_clear_key/clear_key_cdm.h +++ b/media/cdm/ppapi/external_clear_key/clear_key_cdm.h
@@ -100,6 +100,8 @@ bool has_additional_usable_key, CdmKeysInfo keys_info); void OnSessionClosed(const std::string& session_id); + void OnSessionExpirationUpdate(const std::string& session_id, + base::Time new_expiry_time); // Handle the success/failure of a promise. These methods are responsible for // calling |host_| to resolve or reject the promise.
diff --git a/media/gpu/dxva_video_decode_accelerator_win.cc b/media/gpu/dxva_video_decode_accelerator_win.cc index 42951071..e65f1e8 100644 --- a/media/gpu/dxva_video_decode_accelerator_win.cc +++ b/media/gpu/dxva_video_decode_accelerator_win.cc
@@ -1549,17 +1549,34 @@ EGL_ALPHA_SIZE, 0, EGL_NONE}; - EGLint num_configs; + EGLint num_configs = 0; - if (!eglChooseConfig(egl_display, config_attribs, &egl_config_, 1, - &num_configs) || - num_configs == 0) { - if (use_fp16_) { - // Try again, but without use_fp16_ - use_fp16_ = false; - continue; + if (eglChooseConfig(egl_display, config_attribs, NULL, 0, &num_configs) && + num_configs > 0) { + std::vector<EGLConfig> configs(num_configs); + if (eglChooseConfig(egl_display, config_attribs, configs.data(), + num_configs, &num_configs)) { + egl_config_ = configs[0]; + for (int i = 0; i < num_configs; i++) { + EGLint red_bits; + eglGetConfigAttrib(egl_display, configs[i], EGL_RED_SIZE, &red_bits); + // Try to pick a configuration with the right number of bits rather + // than one that just has enough bits. + if (red_bits == (use_fp16_ ? 16 : 8)) { + egl_config_ = configs[i]; + break; + } + } } - return false; + + if (!num_configs) { + if (use_fp16_) { + // Try again, but without use_fp16_ + use_fp16_ = false; + continue; + } + return false; + } } break;
diff --git a/media/mojo/clients/mojo_cdm_factory.cc b/media/mojo/clients/mojo_cdm_factory.cc index cc51384..bad7a15c 100644 --- a/media/mojo/clients/mojo_cdm_factory.cc +++ b/media/mojo/clients/mojo_cdm_factory.cc
@@ -51,7 +51,7 @@ if (CanUseAesDecryptor(key_system)) { scoped_refptr<ContentDecryptionModule> cdm( new AesDecryptor(security_origin, session_message_cb, session_closed_cb, - session_keys_change_cb)); + session_keys_change_cb, session_expiration_update_cb)); base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::Bind(cdm_created_cb, cdm, "")); return;
diff --git a/media/renderers/skcanvas_video_renderer.cc b/media/renderers/skcanvas_video_renderer.cc index 2531dc5..532a0d1 100644 --- a/media/renderers/skcanvas_video_renderer.cc +++ b/media/renderers/skcanvas_video_renderer.cc
@@ -127,6 +127,7 @@ source_textures[i].fTarget = GL_TEXTURE_2D; } } + context_3d.gr_context->resetContext(kTextureBinding_GrGLBackendState); GrBackendObject handles[3] = { skia::GrGLTextureInfoToGrBackendObject(source_textures[0]), skia::GrGLTextureInfoToGrBackendObject(source_textures[1]), @@ -203,6 +204,7 @@ gl, video_frame, SkCanvasVideoRenderer::SingleFrameForVideoElementOrCanvas, source_texture, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, true, false); + context_3d.gr_context->resetContext(kTextureBinding_GrGLBackendState); } else { gl->WaitSyncTokenCHROMIUM(mailbox_holder.sync_token.GetConstData()); source_texture = gl->CreateAndConsumeTextureCHROMIUM(
diff --git a/media/test/fake_encrypted_media.cc b/media/test/fake_encrypted_media.cc index 094ed382..465f972 100644 --- a/media/test/fake_encrypted_media.cc +++ b/media/test/fake_encrypted_media.cc
@@ -22,14 +22,16 @@ } FakeEncryptedMedia::FakeEncryptedMedia(AppBase* app) - : decryptor_( - new AesDecryptor(GURL::EmptyGURL(), - base::Bind(&FakeEncryptedMedia::OnSessionMessage, - base::Unretained(this)), - base::Bind(&FakeEncryptedMedia::OnSessionClosed, - base::Unretained(this)), - base::Bind(&FakeEncryptedMedia::OnSessionKeysChange, - base::Unretained(this)))), + : decryptor_(new AesDecryptor( + GURL::EmptyGURL(), + base::Bind(&FakeEncryptedMedia::OnSessionMessage, + base::Unretained(this)), + base::Bind(&FakeEncryptedMedia::OnSessionClosed, + base::Unretained(this)), + base::Bind(&FakeEncryptedMedia::OnSessionKeysChange, + base::Unretained(this)), + base::Bind(&FakeEncryptedMedia::OnSessionExpirationUpdate, + base::Unretained(this)))), cdm_context_(decryptor_.get()), app_(app) {} @@ -58,6 +60,12 @@ std::move(keys_info)); } +void FakeEncryptedMedia::OnSessionExpirationUpdate( + const std::string& session_id, + base::Time new_expiry_time) { + app_->OnSessionExpirationUpdate(session_id, new_expiry_time); +} + void FakeEncryptedMedia::OnEncryptedMediaInitData( EmeInitDataType init_data_type, const std::vector<uint8_t>& init_data) {
diff --git a/media/test/fake_encrypted_media.h b/media/test/fake_encrypted_media.h index eb6bc3b..59f50b3 100644 --- a/media/test/fake_encrypted_media.h +++ b/media/test/fake_encrypted_media.h
@@ -33,6 +33,9 @@ bool has_additional_usable_key, CdmKeysInfo keys_info) = 0; + virtual void OnSessionExpirationUpdate(const std::string& session_id, + base::Time new_expiry_time) = 0; + virtual void OnEncryptedMediaInitData(EmeInitDataType init_data_type, const std::vector<uint8_t>& init_data, AesDecryptor* decryptor) = 0; @@ -49,6 +52,8 @@ void OnSessionKeysChange(const std::string& session_id, bool has_additional_usable_key, CdmKeysInfo keys_info); + void OnSessionExpirationUpdate(const std::string& session_id, + base::Time new_expiry_time); void OnEncryptedMediaInitData(EmeInitDataType init_data_type, const std::vector<uint8_t>& init_data);
diff --git a/media/test/pipeline_integration_test.cc b/media/test/pipeline_integration_test.cc index e1d7f55..69b7da0 100644 --- a/media/test/pipeline_integration_test.cc +++ b/media/test/pipeline_integration_test.cc
@@ -269,6 +269,11 @@ EXPECT_EQ(has_additional_usable_key, true); } + void OnSessionExpirationUpdate(const std::string& session_id, + base::Time new_expiry_time) override { + EXPECT_EQ(current_session_id_, session_id); + } + void OnEncryptedMediaInitData(EmeInitDataType init_data_type, const std::vector<uint8_t>& init_data, AesDecryptor* decryptor) override { @@ -352,6 +357,9 @@ EXPECT_EQ(has_additional_usable_key, true); } + void OnSessionExpirationUpdate(const std::string& session_id, + base::Time new_expiry_time) override {} + void OnEncryptedMediaInitData(EmeInitDataType init_data_type, const std::vector<uint8_t>& init_data, AesDecryptor* decryptor) override {}
diff --git a/mojo/common/values_struct_traits.h b/mojo/common/values_struct_traits.h index 7d8c2ed..2613f6bfd5 100644 --- a/mojo/common/values_struct_traits.h +++ b/mojo/common/values_struct_traits.h
@@ -173,12 +173,11 @@ } static mojo::ConstCArray<uint8_t> binary_value(const base::Value& value) { - const base::Value* binary_value = nullptr; - if (!value.GetAsBinary(&binary_value)) + if (!value.is_blob()) NOTREACHED(); return mojo::ConstCArray<uint8_t>( - binary_value->GetSize(), - reinterpret_cast<const uint8_t*>(binary_value->GetBuffer())); + value.GetBlob().size(), + reinterpret_cast<const uint8_t*>(value.GetBlob().data())); } static const base::ListValue& list_value(const base::Value& value) {
diff --git a/net/dns/mock_host_resolver.cc b/net/dns/mock_host_resolver.cc index 10258b3..57ccf2b 100644 --- a/net/dns/mock_host_resolver.cc +++ b/net/dns/mock_host_resolver.cc
@@ -4,12 +4,12 @@ #include "net/dns/mock_host_resolver.h" -#include <string> #include <vector> #include "base/bind.h" #include "base/callback_helpers.h" #include "base/location.h" +#include "base/logging.h" #include "base/memory/ref_counted.h" #include "base/single_thread_task_runner.h" #include "base/stl_util.h" @@ -247,40 +247,26 @@ //----------------------------------------------------------------------------- -struct RuleBasedHostResolverProc::Rule { - enum ResolverType { - kResolverTypeFail, - kResolverTypeSystem, - kResolverTypeIPLiteral, - }; +RuleBasedHostResolverProc::Rule::Rule( + ResolverType resolver_type, + const std::string& host_pattern, + AddressFamily address_family, + HostResolverFlags host_resolver_flags, + const std::string& replacement, + const std::string& canonical_name, + int latency_ms) + : resolver_type(resolver_type), + host_pattern(host_pattern), + address_family(address_family), + host_resolver_flags(host_resolver_flags), + replacement(replacement), + canonical_name(canonical_name), + latency_ms(latency_ms) {} - ResolverType resolver_type; - std::string host_pattern; - AddressFamily address_family; - HostResolverFlags host_resolver_flags; - std::string replacement; - std::string canonical_name; - int latency_ms; // In milliseconds. - - Rule(ResolverType resolver_type, - const std::string& host_pattern, - AddressFamily address_family, - HostResolverFlags host_resolver_flags, - const std::string& replacement, - const std::string& canonical_name, - int latency_ms) - : resolver_type(resolver_type), - host_pattern(host_pattern), - address_family(address_family), - host_resolver_flags(host_resolver_flags), - replacement(replacement), - canonical_name(canonical_name), - latency_ms(latency_ms) {} -}; +RuleBasedHostResolverProc::Rule::Rule(const Rule& other) = default; RuleBasedHostResolverProc::RuleBasedHostResolverProc(HostResolverProc* previous) - : HostResolverProc(previous) { -} + : HostResolverProc(previous), modifications_allowed_(true) {} void RuleBasedHostResolverProc::AddRule(const std::string& host_pattern, const std::string& replacement) { @@ -369,10 +355,25 @@ } void RuleBasedHostResolverProc::ClearRules() { + CHECK(modifications_allowed_); base::AutoLock lock(rule_lock_); rules_.clear(); } +void RuleBasedHostResolverProc::DisableModifications() { + CHECK(modifications_allowed_); + modifications_allowed_ = false; +} + +RuleBasedHostResolverProc::RuleList RuleBasedHostResolverProc::GetRules() { + RuleList rv; + { + base::AutoLock lock(rule_lock_); + rv = rules_; + } + return rv; +} + int RuleBasedHostResolverProc::Resolve(const std::string& host, AddressFamily address_family, HostResolverFlags host_resolver_flags, @@ -433,6 +434,7 @@ } void RuleBasedHostResolverProc::AddRuleInternal(const Rule& rule) { + CHECK(modifications_allowed_); base::AutoLock lock(rule_lock_); rules_.push_back(rule); }
diff --git a/net/dns/mock_host_resolver.h b/net/dns/mock_host_resolver.h index cca300ac..d61002c5 100644 --- a/net/dns/mock_host_resolver.h +++ b/net/dns/mock_host_resolver.h
@@ -9,6 +9,7 @@ #include <list> #include <map> +#include <string> #include "base/macros.h" #include "base/memory/weak_ptr.h" @@ -212,6 +213,11 @@ // Deletes all the rules that have been added. void ClearRules(); + // Causes method calls that add or delete rules to assert. + // TODO(jam): once this class isn't used by tests that use an out of process + // network service, remove this method and make Rule private. + void DisableModifications(); + // HostResolverProc methods: int Resolve(const std::string& host, AddressFamily address_family, @@ -219,10 +225,36 @@ AddressList* addrlist, int* os_error) override; - private: - struct Rule; + struct Rule { + enum ResolverType { + kResolverTypeFail, + kResolverTypeSystem, + kResolverTypeIPLiteral, + }; + + Rule(ResolverType resolver_type, + const std::string& host_pattern, + AddressFamily address_family, + HostResolverFlags host_resolver_flags, + const std::string& replacement, + const std::string& canonical_name, + int latency_ms); + Rule(const Rule& other); + + ResolverType resolver_type; + std::string host_pattern; + AddressFamily address_family; + HostResolverFlags host_resolver_flags; + std::string replacement; + std::string canonical_name; + int latency_ms; // In milliseconds. + }; + typedef std::list<Rule> RuleList; + RuleList GetRules(); + + private: ~RuleBasedHostResolverProc() override; void AddRuleInternal(const Rule& rule); @@ -231,6 +263,9 @@ // Must be obtained before writing to or reading from |rules_|. base::Lock rule_lock_; + + // Whether changes are allowed. + bool modifications_allowed_; }; // Create rules that map all requests to localhost.
diff --git a/net/http/http_stream_factory_impl_unittest.cc b/net/http/http_stream_factory_impl_unittest.cc index 3d77064e..9565d7f 100644 --- a/net/http/http_stream_factory_impl_unittest.cc +++ b/net/http/http_stream_factory_impl_unittest.cc
@@ -2267,9 +2267,8 @@ ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY); size_t spdy_headers_frame_length; QuicStreamOffset header_stream_offset = 0; - mock_quic_data.AddWrite(client_packet_maker().MakeSettingsPacket( - 1, SETTINGS_MAX_HEADER_LIST_SIZE, kDefaultMaxUncompressedHeaderSize, true, - &header_stream_offset)); + mock_quic_data.AddWrite(client_packet_maker().MakeInitialSettingsPacket( + 1, &header_stream_offset)); mock_quic_data.AddWrite(client_packet_maker().MakeRequestHeadersPacket( 2, test::kClientDataStreamId1, /*should_include_version=*/true, /*fin=*/true, priority, @@ -2396,9 +2395,8 @@ ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY); size_t spdy_headers_frame_length; QuicStreamOffset header_stream_offset = 0; - mock_quic_data.AddWrite(client_packet_maker().MakeSettingsPacket( - 1, SETTINGS_MAX_HEADER_LIST_SIZE, kDefaultMaxUncompressedHeaderSize, true, - &header_stream_offset)); + mock_quic_data.AddWrite(client_packet_maker().MakeInitialSettingsPacket( + 1, &header_stream_offset)); mock_quic_data.AddWrite(client_packet_maker().MakeRequestHeadersPacket( 2, test::kClientDataStreamId1, /*should_include_version=*/true, /*fin=*/true, priority,
diff --git a/net/quic/chromium/bidirectional_stream_quic_impl_unittest.cc b/net/quic/chromium/bidirectional_stream_quic_impl_unittest.cc index 5670cc2..c92c380 100644 --- a/net/quic/chromium/bidirectional_stream_quic_impl_unittest.cc +++ b/net/quic/chromium/bidirectional_stream_quic_impl_unittest.cc
@@ -656,13 +656,10 @@ !kIncludeCongestionFeedback); } - std::unique_ptr<QuicReceivedPacket> ConstructSettingsPacket( + std::unique_ptr<QuicReceivedPacket> ConstructInitialSettingsPacket( QuicPacketNumber packet_number, - SpdySettingsIds id, - size_t value, QuicStreamOffset* offset) { - return client_maker_.MakeSettingsPacket(packet_number, id, value, - kIncludeVersion, offset); + return client_maker_.MakeInitialSettingsPacket(packet_number, offset); } void ExpectLoadTimingValid(const LoadTimingInfo& load_timing_info, @@ -722,9 +719,7 @@ AddWrite(ConstructRequestHeadersPacketInner( 1, kClientDataStreamId1, kFin, DEFAULT_PRIORITY, &spdy_request_headers_frame_length, &header_stream_offset)); - AddWrite(ConstructSettingsPacket(2, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, - &header_stream_offset)); + AddWrite(ConstructInitialSettingsPacket(2, &header_stream_offset)); AddWrite(ConstructClientAckPacket(3, 3, 1, 1)); Initialize(); @@ -824,8 +819,7 @@ SetRequest("GET", "/", DEFAULT_PRIORITY); AddWrite(ConstructRequestHeadersPacketInner( 2, kClientDataStreamId2, kFin, DEFAULT_PRIORITY, nullptr, &offset)); - AddWrite(ConstructSettingsPacket(3, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, &offset)); + AddWrite(ConstructInitialSettingsPacket(3, &offset)); AddWrite(ConstructClientAckPacket(4, 3, 1, 1)); Initialize(); @@ -887,9 +881,7 @@ SetRequest("POST", "/", DEFAULT_PRIORITY); size_t spdy_request_headers_frame_length; QuicStreamOffset header_stream_offset = 0; - AddWrite(ConstructSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, - &header_stream_offset)); + AddWrite(ConstructInitialSettingsPacket(1, &header_stream_offset)); const char kBody1[] = "here are some data"; const char kBody2[] = "data keep coming"; std::vector<std::string> two_writes = {kBody1, kBody2}; @@ -1001,9 +993,7 @@ SetRequest("POST", "/", DEFAULT_PRIORITY); size_t spdy_request_headers_frame_length; QuicStreamOffset header_stream_offset = 0; - AddWrite(ConstructSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, - &header_stream_offset)); + AddWrite(ConstructInitialSettingsPacket(1, &header_stream_offset)); const char kBody1[] = "here are some data"; AddWrite(ConstructRequestHeadersAndMultipleDataFramesPacket( 2, !kFin, DEFAULT_PRIORITY, &header_stream_offset, @@ -1098,9 +1088,7 @@ SetRequest("POST", "/", DEFAULT_PRIORITY); size_t spdy_request_headers_frame_length; QuicStreamOffset header_stream_offset = 0; - AddWrite(ConstructSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, - &header_stream_offset)); + AddWrite(ConstructInitialSettingsPacket(1, &header_stream_offset)); const char kBody1[] = "here are some data"; const char kBody2[] = "data keep coming"; std::vector<std::string> two_writes = {kBody1, kBody2}; @@ -1206,9 +1194,7 @@ AddWrite(ConstructRequestHeadersPacketInner( 1, kClientDataStreamId1, !kFin, DEFAULT_PRIORITY, &spdy_request_headers_frame_length, &header_stream_offset)); - AddWrite(ConstructSettingsPacket(2, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, - &header_stream_offset)); + AddWrite(ConstructInitialSettingsPacket(2, &header_stream_offset)); AddWrite(ConstructDataPacket(3, kIncludeVersion, kFin, 0, kUploadData, &client_maker_)); AddWrite(ConstructClientAckPacket(4, 3, 1, 1)); @@ -1367,9 +1353,7 @@ 1, kClientDataStreamId1, !kFin, DEFAULT_PRIORITY, &spdy_request_headers_frame_length, &header_stream_offset)); - AddWrite(ConstructSettingsPacket(2, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, - &header_stream_offset)); + AddWrite(ConstructInitialSettingsPacket(2, &header_stream_offset)); AddWrite(ConstructAckAndDataPacket(3, !kIncludeVersion, 2, 1, 1, !kFin, 0, kUploadData, &client_maker_)); AddWrite(ConstructAckAndDataPacket(4, !kIncludeVersion, 3, 3, 3, kFin, @@ -1457,9 +1441,7 @@ AddWrite(ConstructRequestHeadersPacketInner( 1, kClientDataStreamId1, kFin, DEFAULT_PRIORITY, &spdy_request_headers_frame_length, &header_stream_offset)); - AddWrite(ConstructSettingsPacket(2, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, - &header_stream_offset)); + AddWrite(ConstructInitialSettingsPacket(2, &header_stream_offset)); Initialize(); BidirectionalStreamRequestInfo request; @@ -1500,9 +1482,7 @@ AddWrite(ConstructRequestHeadersPacketInner( 1, kClientDataStreamId1, kFin, DEFAULT_PRIORITY, &spdy_request_headers_frame_length, &header_stream_offset)); - AddWrite(ConstructSettingsPacket(2, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, - &header_stream_offset)); + AddWrite(ConstructInitialSettingsPacket(2, &header_stream_offset)); // Why does QUIC ack Rst? Is this expected? AddWrite(ConstructClientAckPacket(3, 3, 1, 1)); @@ -1563,9 +1543,7 @@ AddWrite(ConstructRequestHeadersPacketInner( 1, kClientDataStreamId1, !kFin, DEFAULT_PRIORITY, &spdy_request_headers_frame_length, &header_stream_offset)); - AddWrite(ConstructSettingsPacket(2, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, - &header_stream_offset)); + AddWrite(ConstructInitialSettingsPacket(2, &header_stream_offset)); Initialize(); BidirectionalStreamRequestInfo request; @@ -1625,9 +1603,7 @@ AddWrite(ConstructRequestHeadersPacketInner( 1, kClientDataStreamId1, !kFin, DEFAULT_PRIORITY, &spdy_request_headers_frame_length, &header_stream_offset)); - AddWrite(ConstructSettingsPacket(2, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, - &header_stream_offset)); + AddWrite(ConstructInitialSettingsPacket(2, &header_stream_offset)); AddWrite(ConstructClientAckAndRstStreamPacket(3, 2, 1, 1)); Initialize(); @@ -1681,9 +1657,7 @@ AddWrite(ConstructRequestHeadersPacketInner( 1, kClientDataStreamId1, !kFin, DEFAULT_PRIORITY, &spdy_request_headers_frame_length, &header_stream_offset)); - AddWrite(ConstructSettingsPacket(2, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, - &header_stream_offset)); + AddWrite(ConstructInitialSettingsPacket(2, &header_stream_offset)); AddWrite(ConstructClientAckAndRstStreamPacket(3, 2, 1, 1)); Initialize(); @@ -1729,9 +1703,7 @@ AddWrite(ConstructRequestHeadersPacketInner( 1, kClientDataStreamId1, !kFin, DEFAULT_PRIORITY, &spdy_request_headers_frame_length, &header_stream_offset)); - AddWrite(ConstructSettingsPacket(2, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, - &header_stream_offset)); + AddWrite(ConstructInitialSettingsPacket(2, &header_stream_offset)); AddWrite(ConstructClientAckPacket(3, 3, 1, 1)); AddWrite(ConstructClientRstStreamPacket(4));
diff --git a/net/quic/chromium/quic_chromium_client_session_test.cc b/net/quic/chromium/quic_chromium_client_session_test.cc index a3cf2e3d..2c4c5828 100644 --- a/net/quic/chromium/quic_chromium_client_session_test.cc +++ b/net/quic/chromium/quic_chromium_client_session_test.cc
@@ -184,9 +184,7 @@ TEST_P(QuicChromiumClientSessionTest, CryptoConnect) { MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)}; std::unique_ptr<QuicEncryptedPacket> settings_packet( - client_maker_.MakeSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, true, - nullptr)); + client_maker_.MakeInitialSettingsPacket(1, nullptr)); MockWrite writes[] = { MockWrite(ASYNC, settings_packet->data(), settings_packet->length(), 1)}; socket_data_.reset(new SequencedSocketData(reads, arraysize(reads), writes, @@ -198,9 +196,7 @@ TEST_P(QuicChromiumClientSessionTest, MaxNumStreams) { MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)}; std::unique_ptr<QuicEncryptedPacket> settings_packet( - client_maker_.MakeSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, true, - nullptr)); + client_maker_.MakeInitialSettingsPacket(1, nullptr)); std::unique_ptr<QuicEncryptedPacket> client_rst(client_maker_.MakeRstPacket( 2, true, kClientDataStreamId1, QUIC_RST_ACKNOWLEDGEMENT)); MockWrite writes[] = { @@ -239,9 +235,7 @@ base::HistogramTester histogram_tester; MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)}; std::unique_ptr<QuicEncryptedPacket> settings_packet( - client_maker_.MakeSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, true, - nullptr)); + client_maker_.MakeInitialSettingsPacket(1, nullptr)); std::unique_ptr<QuicEncryptedPacket> client_rst(client_maker_.MakeRstPacket( 2, true, kServerDataStreamId1, QUIC_PUSH_STREAM_TIMED_OUT)); MockWrite writes[] = { @@ -290,9 +284,7 @@ base::HistogramTester histogram_tester; MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)}; std::unique_ptr<QuicEncryptedPacket> settings_packet( - client_maker_.MakeSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, true, - nullptr)); + client_maker_.MakeInitialSettingsPacket(1, nullptr)); std::unique_ptr<QuicEncryptedPacket> client_rst(client_maker_.MakeRstPacket( 2, true, kServerDataStreamId1, QUIC_PUSH_STREAM_TIMED_OUT)); MockWrite writes[] = { @@ -343,9 +335,7 @@ TEST_P(QuicChromiumClientSessionTest, CancelPushWhenPendingValidation) { MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)}; std::unique_ptr<QuicEncryptedPacket> settings_packet( - client_maker_.MakeSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, true, - nullptr)); + client_maker_.MakeInitialSettingsPacket(1, nullptr)); std::unique_ptr<QuicEncryptedPacket> client_rst(client_maker_.MakeRstPacket( 2, true, kClientDataStreamId1, QUIC_RST_ACKNOWLEDGEMENT)); @@ -400,9 +390,7 @@ base::HistogramTester histogram_tester; MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)}; std::unique_ptr<QuicEncryptedPacket> settings_packet( - client_maker_.MakeSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, true, - nullptr)); + client_maker_.MakeInitialSettingsPacket(1, nullptr)); std::unique_ptr<QuicEncryptedPacket> client_rst(client_maker_.MakeRstPacket( 2, true, kServerDataStreamId1, QUIC_STREAM_CANCELLED)); MockWrite writes[] = { @@ -452,9 +440,7 @@ base::HistogramTester histogram_tester; MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)}; std::unique_ptr<QuicEncryptedPacket> settings_packet( - client_maker_.MakeSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, true, - nullptr)); + client_maker_.MakeInitialSettingsPacket(1, nullptr)); std::unique_ptr<QuicEncryptedPacket> client_rst(client_maker_.MakeRstPacket( 2, true, kServerDataStreamId1, QUIC_STREAM_CANCELLED)); MockWrite writes[] = { @@ -508,9 +494,7 @@ TEST_P(QuicChromiumClientSessionTest, Priority) { MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)}; std::unique_ptr<QuicEncryptedPacket> settings_packet( - client_maker_.MakeSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, true, - nullptr)); + client_maker_.MakeInitialSettingsPacket(1, nullptr)); std::unique_ptr<QuicEncryptedPacket> client_rst(client_maker_.MakeRstPacket( 2, true, kClientDataStreamId1, QUIC_RST_ACKNOWLEDGEMENT)); MockWrite writes[] = { @@ -539,9 +523,7 @@ TEST_P(QuicChromiumClientSessionTest, MaxNumStreamsViaRequest) { MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)}; std::unique_ptr<QuicEncryptedPacket> settings_packet( - client_maker_.MakeSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, true, - nullptr)); + client_maker_.MakeInitialSettingsPacket(1, nullptr)); std::unique_ptr<QuicEncryptedPacket> client_rst(client_maker_.MakeRstPacket( 2, true, kClientDataStreamId1, QUIC_RST_ACKNOWLEDGEMENT)); MockWrite writes[] = { @@ -582,9 +564,7 @@ TEST_P(QuicChromiumClientSessionTest, GoAwayReceived) { MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)}; std::unique_ptr<QuicEncryptedPacket> settings_packet( - client_maker_.MakeSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, true, - nullptr)); + client_maker_.MakeInitialSettingsPacket(1, nullptr)); MockWrite writes[] = { MockWrite(ASYNC, settings_packet->data(), settings_packet->length(), 1)}; socket_data_.reset(new SequencedSocketData(reads, arraysize(reads), writes, @@ -602,9 +582,7 @@ TEST_P(QuicChromiumClientSessionTest, CanPool) { MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)}; std::unique_ptr<QuicEncryptedPacket> settings_packet( - client_maker_.MakeSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, true, - nullptr)); + client_maker_.MakeInitialSettingsPacket(1, nullptr)); MockWrite writes[] = { MockWrite(ASYNC, settings_packet->data(), settings_packet->length(), 1)}; socket_data_.reset(new SequencedSocketData(reads, arraysize(reads), writes, @@ -633,9 +611,7 @@ TEST_P(QuicChromiumClientSessionTest, ConnectionPooledWithTlsChannelId) { MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)}; std::unique_ptr<QuicEncryptedPacket> settings_packet( - client_maker_.MakeSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, true, - nullptr)); + client_maker_.MakeInitialSettingsPacket(1, nullptr)); MockWrite writes[] = { MockWrite(ASYNC, settings_packet->data(), settings_packet->length(), 1)}; socket_data_.reset(new SequencedSocketData(reads, arraysize(reads), writes, @@ -665,9 +641,7 @@ TEST_P(QuicChromiumClientSessionTest, ConnectionNotPooledWithDifferentPin) { MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)}; std::unique_ptr<QuicEncryptedPacket> settings_packet( - client_maker_.MakeSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, true, - nullptr)); + client_maker_.MakeInitialSettingsPacket(1, nullptr)); MockWrite writes[] = { MockWrite(ASYNC, settings_packet->data(), settings_packet->length(), 1)}; socket_data_.reset(new SequencedSocketData(reads, arraysize(reads), writes, @@ -700,9 +674,7 @@ TEST_P(QuicChromiumClientSessionTest, ConnectionPooledWithMatchingPin) { MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)}; std::unique_ptr<QuicEncryptedPacket> settings_packet( - client_maker_.MakeSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, true, - nullptr)); + client_maker_.MakeInitialSettingsPacket(1, nullptr)); MockWrite writes[] = { MockWrite(ASYNC, settings_packet->data(), settings_packet->length(), 1)}; socket_data_.reset(new SequencedSocketData(reads, arraysize(reads), writes, @@ -734,9 +706,7 @@ TEST_P(QuicChromiumClientSessionTest, MigrateToSocket) { MockRead old_reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)}; std::unique_ptr<QuicEncryptedPacket> settings_packet( - client_maker_.MakeSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, true, - nullptr)); + client_maker_.MakeInitialSettingsPacket(1, nullptr)); MockWrite old_writes[] = { MockWrite(ASYNC, settings_packet->data(), settings_packet->length(), 1)}; socket_data_.reset(new SequencedSocketData( @@ -802,9 +772,7 @@ TEST_P(QuicChromiumClientSessionTest, MigrateToSocketMaxReaders) { MockRead old_reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)}; std::unique_ptr<QuicEncryptedPacket> settings_packet( - client_maker_.MakeSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, true, - nullptr)); + client_maker_.MakeInitialSettingsPacket(1, nullptr)); MockWrite old_writes[] = { MockWrite(ASYNC, settings_packet->data(), settings_packet->length(), 1)}; socket_data_.reset(new SequencedSocketData( @@ -859,9 +827,7 @@ TEST_P(QuicChromiumClientSessionTest, MigrateToSocketReadError) { std::unique_ptr<QuicEncryptedPacket> settings_packet( - client_maker_.MakeSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, true, - nullptr)); + client_maker_.MakeInitialSettingsPacket(1, nullptr)); std::unique_ptr<QuicEncryptedPacket> client_ping( client_maker_.MakePingPacket(2, /*include_version=*/false)); std::unique_ptr<QuicEncryptedPacket> server_ping(
diff --git a/net/quic/chromium/quic_http_stream_test.cc b/net/quic/chromium/quic_http_stream_test.cc index 1c8e37a..6b7e951 100644 --- a/net/quic/chromium/quic_http_stream_test.cc +++ b/net/quic/chromium/quic_http_stream_test.cc
@@ -531,13 +531,9 @@ !kIncludeCongestionFeedback); } - std::unique_ptr<QuicReceivedPacket> ConstructSettingsPacket( - QuicPacketNumber packet_number, - SpdySettingsIds id, - size_t value, + std::unique_ptr<QuicReceivedPacket> ConstructInitialSettingsPacket( QuicStreamOffset* offset) { - return client_maker_.MakeSettingsPacket(packet_number, id, value, - kIncludeVersion, offset); + return client_maker_.MakeInitialSettingsPacket(1, offset); } void ReceivePromise(QuicStreamId id) { @@ -638,9 +634,7 @@ SetRequest("GET", "/", DEFAULT_PRIORITY); size_t spdy_request_header_frame_length; QuicStreamOffset header_stream_offset = 0; - AddWrite(ConstructSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, - &header_stream_offset)); + AddWrite(ConstructInitialSettingsPacket(&header_stream_offset)); AddWrite(InnerConstructRequestHeadersPacket( 2, kClientDataStreamId1, kIncludeVersion, kFin, DEFAULT_PRIORITY, &spdy_request_header_frame_length, &header_stream_offset)); @@ -702,8 +696,7 @@ size_t spdy_request_header_frame_length; QuicStreamOffset offset = 0; - AddWrite(ConstructSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, &offset)); + AddWrite(ConstructInitialSettingsPacket(&offset)); AddWrite(InnerConstructRequestHeadersPacket( 2, kClientDataStreamId1, kIncludeVersion, kFin, DEFAULT_PRIORITY, &spdy_request_header_frame_length, &offset)); @@ -786,9 +779,7 @@ SetRequest("GET", "/", DEFAULT_PRIORITY); size_t spdy_request_header_frame_length; QuicStreamOffset header_stream_offset = 0; - AddWrite(ConstructSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, - &header_stream_offset)); + AddWrite(ConstructInitialSettingsPacket(&header_stream_offset)); AddWrite(InnerConstructRequestHeadersPacket( 2, kClientDataStreamId1, kIncludeVersion, kFin, DEFAULT_PRIORITY, &spdy_request_header_frame_length, &header_stream_offset)); @@ -882,9 +873,7 @@ SetRequest("GET", "/", DEFAULT_PRIORITY); size_t spdy_request_headers_frame_length; QuicStreamOffset header_stream_offset = 0; - AddWrite(ConstructSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, - &header_stream_offset)); + AddWrite(ConstructInitialSettingsPacket(&header_stream_offset)); AddWrite(InnerConstructRequestHeadersPacket( 2, kClientDataStreamId1, kIncludeVersion, kFin, DEFAULT_PRIORITY, &spdy_request_headers_frame_length, &header_stream_offset)); @@ -1011,9 +1000,7 @@ SetRequest("GET", "/", DEFAULT_PRIORITY); size_t spdy_request_headers_frame_length; QuicStreamOffset header_stream_offset = 0; - AddWrite(ConstructSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, - &header_stream_offset)); + AddWrite(ConstructInitialSettingsPacket(&header_stream_offset)); AddWrite(InnerConstructRequestHeadersPacket( 2, kClientDataStreamId1, kIncludeVersion, kFin, DEFAULT_PRIORITY, &spdy_request_headers_frame_length, &header_stream_offset)); @@ -1051,9 +1038,7 @@ SetRequest("GET", "/", DEFAULT_PRIORITY); size_t spdy_request_headers_frame_length; QuicStreamOffset header_stream_offset = 0; - AddWrite(ConstructSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, - &header_stream_offset)); + AddWrite(ConstructInitialSettingsPacket(&header_stream_offset)); AddWrite(InnerConstructRequestHeadersPacket( 2, kClientDataStreamId1, kIncludeVersion, kFin, DEFAULT_PRIORITY, &spdy_request_headers_frame_length, &header_stream_offset)); @@ -1096,9 +1081,7 @@ SetRequest("GET", "/", DEFAULT_PRIORITY); size_t spdy_request_headers_frame_length; QuicStreamOffset header_stream_offset = 0; - AddWrite(ConstructSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, - &header_stream_offset)); + AddWrite(ConstructInitialSettingsPacket(&header_stream_offset)); AddWrite(InnerConstructRequestHeadersPacket( 2, kClientDataStreamId1, kIncludeVersion, kFin, DEFAULT_PRIORITY, &spdy_request_headers_frame_length, &header_stream_offset)); @@ -1130,9 +1113,7 @@ SetRequest("POST", "/", DEFAULT_PRIORITY); size_t spdy_request_headers_frame_length; QuicStreamOffset header_stream_offset = 0; - AddWrite(ConstructSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, - &header_stream_offset)); + AddWrite(ConstructInitialSettingsPacket(&header_stream_offset)); AddWrite(InnerConstructRequestHeadersPacket( 2, kClientDataStreamId1, kIncludeVersion, !kFin, DEFAULT_PRIORITY, &spdy_request_headers_frame_length, &header_stream_offset)); @@ -1201,9 +1182,7 @@ size_t chunk_size = strlen(kUploadData); size_t spdy_request_headers_frame_length; QuicStreamOffset header_stream_offset = 0; - AddWrite(ConstructSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, - &header_stream_offset)); + AddWrite(ConstructInitialSettingsPacket(&header_stream_offset)); AddWrite(InnerConstructRequestHeadersPacket( 2, kClientDataStreamId1, kIncludeVersion, !kFin, DEFAULT_PRIORITY, &spdy_request_headers_frame_length, &header_stream_offset)); @@ -1277,9 +1256,7 @@ size_t chunk_size = strlen(kUploadData); size_t spdy_request_headers_frame_length; QuicStreamOffset header_stream_offset = 0; - AddWrite(ConstructSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, - &header_stream_offset)); + AddWrite(ConstructInitialSettingsPacket(&header_stream_offset)); AddWrite(InnerConstructRequestHeadersPacket( 2, kClientDataStreamId1, kIncludeVersion, !kFin, DEFAULT_PRIORITY, &spdy_request_headers_frame_length, &header_stream_offset)); @@ -1349,9 +1326,7 @@ SetRequest("POST", "/", DEFAULT_PRIORITY); size_t spdy_request_headers_frame_length; QuicStreamOffset header_stream_offset = 0; - AddWrite(ConstructSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, - &header_stream_offset)); + AddWrite(ConstructInitialSettingsPacket(&header_stream_offset)); AddWrite(InnerConstructRequestHeadersPacket( 2, kClientDataStreamId1, kIncludeVersion, !kFin, DEFAULT_PRIORITY, &spdy_request_headers_frame_length, &header_stream_offset)); @@ -1418,9 +1393,7 @@ SetRequest("GET", "/", DEFAULT_PRIORITY); size_t spdy_request_headers_frame_length; QuicStreamOffset header_stream_offset = 0; - AddWrite(ConstructSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, - &header_stream_offset)); + AddWrite(ConstructInitialSettingsPacket(&header_stream_offset)); AddWrite(InnerConstructRequestHeadersPacket( 2, kClientDataStreamId1, kIncludeVersion, kFin, DEFAULT_PRIORITY, &spdy_request_headers_frame_length, &header_stream_offset)); @@ -1463,9 +1436,7 @@ SetRequest("GET", "/", MEDIUM); size_t spdy_request_headers_frame_length; QuicStreamOffset header_stream_offset = 0; - AddWrite(ConstructSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, - &header_stream_offset)); + AddWrite(ConstructInitialSettingsPacket(&header_stream_offset)); AddWrite(InnerConstructRequestHeadersPacket( 2, kClientDataStreamId1, kIncludeVersion, kFin, MEDIUM, &spdy_request_headers_frame_length, &header_stream_offset)); @@ -1519,9 +1490,7 @@ SetRequest("GET", "/", MEDIUM); use_closing_stream_ = true; QuicStreamOffset header_stream_offset = 0; - AddWrite(ConstructSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, - &header_stream_offset)); + AddWrite(ConstructInitialSettingsPacket(&header_stream_offset)); AddWrite(ConstructClientRstStreamPacket(2)); Initialize(); @@ -1554,9 +1523,7 @@ SetRequest("POST", "/", DEFAULT_PRIORITY); size_t spdy_request_headers_frame_length; QuicStreamOffset header_stream_offset = 0; - AddWrite(ConstructSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, - &header_stream_offset)); + AddWrite(ConstructInitialSettingsPacket(&header_stream_offset)); AddWrite(InnerConstructRequestHeadersPacket( 2, kClientDataStreamId1, kIncludeVersion, !kFin, DEFAULT_PRIORITY, &spdy_request_headers_frame_length, &header_stream_offset)); @@ -1593,9 +1560,7 @@ TEST_P(QuicHttpStreamTest, SessionClosedBeforeSendHeadersComplete) { SetRequest("POST", "/", DEFAULT_PRIORITY); QuicStreamOffset header_stream_offset = 0; - AddWrite(ConstructSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, - &header_stream_offset)); + AddWrite(ConstructInitialSettingsPacket(&header_stream_offset)); AddWrite(SYNCHRONOUS, ERR_FAILED); Initialize(); @@ -1618,9 +1583,7 @@ SetRequest("POST", "/", DEFAULT_PRIORITY); size_t spdy_request_headers_frame_length; QuicStreamOffset header_stream_offset = 0; - AddWrite(ConstructSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, - &header_stream_offset)); + AddWrite(ConstructInitialSettingsPacket(&header_stream_offset)); AddWrite(InnerConstructRequestHeadersPacket( 2, kClientDataStreamId1, kIncludeVersion, !kFin, DEFAULT_PRIORITY, &spdy_request_headers_frame_length, &header_stream_offset)); @@ -2011,9 +1974,7 @@ size_t spdy_request_header_frame_length; QuicStreamOffset header_stream_offset = 0; - AddWrite(ConstructSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, - &header_stream_offset)); + AddWrite(ConstructInitialSettingsPacket(&header_stream_offset)); AddWrite(ConstructClientRstStreamVaryMismatchPacket(2)); AddWrite(InnerConstructRequestHeadersPacket( 3, stream_id_ + 2, !kIncludeVersion, kFin, DEFAULT_PRIORITY, @@ -2126,9 +2087,7 @@ SetRequest("POST", "/", DEFAULT_PRIORITY); size_t spdy_request_headers_frame_length; QuicStreamOffset header_stream_offset = 0; - AddWrite(ConstructSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, - &header_stream_offset)); + AddWrite(ConstructInitialSettingsPacket(&header_stream_offset)); AddWrite(InnerConstructRequestHeadersPacket( 2, kClientDataStreamId1, kIncludeVersion, !kFin, DEFAULT_PRIORITY, &spdy_request_headers_frame_length, &header_stream_offset)); @@ -2163,9 +2122,7 @@ SetRequest("POST", "/", DEFAULT_PRIORITY); size_t spdy_request_headers_frame_length; QuicStreamOffset header_stream_offset = 0; - AddWrite(ConstructSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, - &header_stream_offset)); + AddWrite(ConstructInitialSettingsPacket(&header_stream_offset)); AddWrite(InnerConstructRequestHeadersPacket( 2, kClientDataStreamId1, kIncludeVersion, !kFin, DEFAULT_PRIORITY, &spdy_request_headers_frame_length, &header_stream_offset));
diff --git a/net/quic/chromium/quic_network_transaction_unittest.cc b/net/quic/chromium/quic_network_transaction_unittest.cc index f2b6030..23692e1 100644 --- a/net/quic/chromium/quic_network_transaction_unittest.cc +++ b/net/quic/chromium/quic_network_transaction_unittest.cc
@@ -350,13 +350,10 @@ error_code); } - std::unique_ptr<QuicReceivedPacket> ConstructSettingsPacket( + std::unique_ptr<QuicReceivedPacket> ConstructInitialSettingsPacket( QuicPacketNumber packet_number, - SpdySettingsIds id, - size_t value, QuicStreamOffset* offset) { - return client_maker_.MakeSettingsPacket(packet_number, id, value, - kIncludeVersion, offset); + return client_maker_.MakeInitialSettingsPacket(packet_number, offset); } std::unique_ptr<QuicReceivedPacket> ConstructServerAckPacket( @@ -776,9 +773,8 @@ MockQuicData mock_quic_data; QuicStreamOffset header_stream_offset = 0; - mock_quic_data.AddWrite(ConstructSettingsPacket( - 1, SETTINGS_MAX_HEADER_LIST_SIZE, kDefaultMaxUncompressedHeaderSize, - &header_stream_offset)); + mock_quic_data.AddWrite( + ConstructInitialSettingsPacket(1, &header_stream_offset)); mock_quic_data.AddWrite(ConstructClientRequestHeadersPacket( 2, kClientDataStreamId1, true, true, GetRequestHeaders("GET", "https", "/"), &header_stream_offset)); @@ -807,9 +803,8 @@ MockQuicData mock_quic_data; QuicStreamOffset header_stream_offset = 0; - mock_quic_data.AddWrite(ConstructSettingsPacket( - 1, SETTINGS_MAX_HEADER_LIST_SIZE, kDefaultMaxUncompressedHeaderSize, - &header_stream_offset)); + mock_quic_data.AddWrite( + ConstructInitialSettingsPacket(1, &header_stream_offset)); mock_quic_data.AddWrite(ConstructClientRequestHeadersPacket( 2, kClientDataStreamId1, true, true, GetRequestHeaders("GET", "https", "/"), &header_stream_offset)); @@ -838,9 +833,8 @@ MockQuicData mock_quic_data; QuicStreamOffset header_stream_offset = 0; - mock_quic_data.AddWrite(ConstructSettingsPacket( - 1, SETTINGS_MAX_HEADER_LIST_SIZE, kDefaultMaxUncompressedHeaderSize, - &header_stream_offset)); + mock_quic_data.AddWrite( + ConstructInitialSettingsPacket(1, &header_stream_offset)); mock_quic_data.AddWrite(ConstructClientRequestHeadersPacket( 2, kClientDataStreamId1, true, true, GetRequestHeaders("GET", "https", "/"), &header_stream_offset)); @@ -903,9 +897,8 @@ MockQuicData mock_quic_data; QuicStreamOffset header_stream_offset = 0; - mock_quic_data.AddWrite(ConstructSettingsPacket( - 1, SETTINGS_MAX_HEADER_LIST_SIZE, kDefaultMaxUncompressedHeaderSize, - &header_stream_offset)); + mock_quic_data.AddWrite( + ConstructInitialSettingsPacket(1, &header_stream_offset)); mock_quic_data.AddWrite(ConstructClientRequestHeadersPacket( 2, kClientDataStreamId1, true, true, GetRequestHeaders("GET", "https", "/"), &header_stream_offset)); @@ -932,9 +925,8 @@ MockQuicData mock_quic_data; QuicStreamOffset header_stream_offset = 0; - mock_quic_data.AddWrite(ConstructSettingsPacket( - 1, SETTINGS_MAX_HEADER_LIST_SIZE, kDefaultMaxUncompressedHeaderSize, - &header_stream_offset)); + mock_quic_data.AddWrite( + ConstructInitialSettingsPacket(1, &header_stream_offset)); mock_quic_data.AddWrite(ConstructClientRequestHeadersPacket( 2, kClientDataStreamId1, true, true, GetRequestHeaders("GET", "http", "/"), &header_stream_offset)); @@ -975,9 +967,8 @@ client_maker_.set_hostname(origin_host); MockQuicData mock_quic_data; QuicStreamOffset header_stream_offset = 0; - mock_quic_data.AddWrite(ConstructSettingsPacket( - 1, SETTINGS_MAX_HEADER_LIST_SIZE, kDefaultMaxUncompressedHeaderSize, - &header_stream_offset)); + mock_quic_data.AddWrite( + ConstructInitialSettingsPacket(1, &header_stream_offset)); mock_quic_data.AddWrite(ConstructClientRequestHeadersPacket( 2, kClientDataStreamId1, true, true, GetRequestHeaders("GET", "http", "/"), &header_stream_offset)); @@ -1029,9 +1020,8 @@ client_maker_.set_hostname(origin.host()); MockQuicData mock_quic_data; QuicStreamOffset header_stream_offset = 0; - mock_quic_data.AddWrite(ConstructSettingsPacket( - 1, SETTINGS_MAX_HEADER_LIST_SIZE, kDefaultMaxUncompressedHeaderSize, - &header_stream_offset)); + mock_quic_data.AddWrite( + ConstructInitialSettingsPacket(1, &header_stream_offset)); mock_quic_data.AddWrite(ConstructClientRequestHeadersPacket( 2, kClientDataStreamId1, true, true, GetRequestHeaders("GET", "https", "/"), &header_stream_offset)); @@ -1072,9 +1062,8 @@ // First try: alternative job uses QUIC, gets 421 Misdirected Request error. MockQuicData mock_quic_data; QuicStreamOffset request_header_offset = 0; - mock_quic_data.AddWrite(ConstructSettingsPacket( - 1, SETTINGS_MAX_HEADER_LIST_SIZE, kDefaultMaxUncompressedHeaderSize, - &request_header_offset)); + mock_quic_data.AddWrite( + ConstructInitialSettingsPacket(1, &request_header_offset)); mock_quic_data.AddWrite(ConstructClientRequestHeadersPacket( 2, kClientDataStreamId1, true, true, GetRequestHeaders("GET", "https", "/"), &request_header_offset)); @@ -1122,15 +1111,13 @@ MockQuicData mock_quic_data1; QuicStreamOffset header_stream_offset = 0; - mock_quic_data1.AddWrite(ConstructSettingsPacket( - 1, SETTINGS_MAX_HEADER_LIST_SIZE, kDefaultMaxUncompressedHeaderSize, - &header_stream_offset)); + mock_quic_data1.AddWrite( + ConstructInitialSettingsPacket(1, &header_stream_offset)); mock_quic_data1.AddRead(ASYNC, ERR_SOCKET_NOT_CONNECTED); MockQuicData mock_quic_data2; header_stream_offset = 0; - mock_quic_data2.AddWrite(ConstructSettingsPacket( - 1, SETTINGS_MAX_HEADER_LIST_SIZE, kDefaultMaxUncompressedHeaderSize, - &header_stream_offset)); + mock_quic_data2.AddWrite( + ConstructInitialSettingsPacket(1, &header_stream_offset)); crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_); mock_quic_data2.AddRead(ASYNC, ERR_SOCKET_NOT_CONNECTED); crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_); @@ -1186,9 +1173,8 @@ MockQuicData mock_quic_data; QuicStreamOffset header_stream_offset = 0; - mock_quic_data.AddWrite(ConstructSettingsPacket( - 1, SETTINGS_MAX_HEADER_LIST_SIZE, kDefaultMaxUncompressedHeaderSize, - &header_stream_offset)); + mock_quic_data.AddWrite( + ConstructInitialSettingsPacket(1, &header_stream_offset)); mock_quic_data.AddWrite(ConstructClientRequestHeadersPacket( 2, kClientDataStreamId1, true, true, GetRequestHeaders("GET", "https", "/"), &header_stream_offset)); @@ -1225,9 +1211,8 @@ MockQuicData mock_quic_data; QuicStreamOffset header_stream_offset = 0; - mock_quic_data.AddWrite(ConstructSettingsPacket( - 1, SETTINGS_MAX_HEADER_LIST_SIZE, kDefaultMaxUncompressedHeaderSize, - &header_stream_offset)); + mock_quic_data.AddWrite( + ConstructInitialSettingsPacket(1, &header_stream_offset)); mock_quic_data.AddWrite(ConstructClientRequestHeadersPacket( 2, kClientDataStreamId1, true, true, GetRequestHeaders("GET", "https", "/"), &header_stream_offset)); @@ -1330,9 +1315,8 @@ MockQuicData mock_quic_data; QuicStreamOffset header_stream_offset = 0; - mock_quic_data.AddWrite(ConstructSettingsPacket( - 1, SETTINGS_MAX_HEADER_LIST_SIZE, kDefaultMaxUncompressedHeaderSize, - &header_stream_offset)); + mock_quic_data.AddWrite( + ConstructInitialSettingsPacket(1, &header_stream_offset)); mock_quic_data.AddWrite(ConstructClientRequestHeadersPacket( 2, kClientDataStreamId1, true, true, GetRequestHeaders("GET", "https", "/"), &header_stream_offset)); @@ -1356,9 +1340,8 @@ TEST_P(QuicNetworkTransactionTest, GoAwayWithConnectionMigrationOnPortsOnly) { MockQuicData mock_quic_data; QuicStreamOffset header_stream_offset = 0; - mock_quic_data.AddWrite(ConstructSettingsPacket( - 1, SETTINGS_MAX_HEADER_LIST_SIZE, kDefaultMaxUncompressedHeaderSize, - &header_stream_offset)); + mock_quic_data.AddWrite( + ConstructInitialSettingsPacket(1, &header_stream_offset)); mock_quic_data.AddWrite(ConstructClientRequestHeadersPacket( 2, kClientDataStreamId1, true, true, GetRequestHeaders("GET", "https", "/"), &header_stream_offset)); @@ -1437,9 +1420,8 @@ std::string settings_data; QuicStreamOffset settings_offset = header_stream_offset; - quic_data.AddWrite(client_maker_.MakeSettingsPacketAndSaveData( - 2, SETTINGS_MAX_HEADER_LIST_SIZE, kDefaultMaxUncompressedHeaderSize, true, - &header_stream_offset, &settings_data)); + quic_data.AddWrite(client_maker_.MakeInitialSettingsPacketAndSaveData( + 2, &header_stream_offset, &settings_data)); // TLP 1 quic_data.AddWrite(client_maker_.MakeDataPacket(3, kHeadersStreamId, true, false, 0, request_data)); @@ -1528,9 +1510,8 @@ std::string settings_data; QuicStreamOffset settings_offset = header_stream_offset; - quic_data.AddWrite(client_maker_.MakeSettingsPacketAndSaveData( - 2, SETTINGS_MAX_HEADER_LIST_SIZE, kDefaultMaxUncompressedHeaderSize, true, - &header_stream_offset, &settings_data)); + quic_data.AddWrite(client_maker_.MakeInitialSettingsPacketAndSaveData( + 2, &header_stream_offset, &settings_data)); // TLP 1 quic_data.AddWrite(client_maker_.MakeDataPacket(3, kHeadersStreamId, true, false, 0, request_data)); @@ -1628,9 +1609,8 @@ std::string settings_data; QuicStreamOffset settings_offset = header_stream_offset; - quic_data.AddWrite(client_maker_.MakeSettingsPacketAndSaveData( - 2, SETTINGS_MAX_HEADER_LIST_SIZE, kDefaultMaxUncompressedHeaderSize, true, - &header_stream_offset, &settings_data)); + quic_data.AddWrite(client_maker_.MakeInitialSettingsPacketAndSaveData( + 2, &header_stream_offset, &settings_data)); quic_data.AddWrite(client_maker_.MakeRstPacket(3, true, kClientDataStreamId1, QUIC_STREAM_CANCELLED)); @@ -1724,9 +1704,7 @@ quic_data.AddWrite(ConstructClientRequestHeadersPacket( 1, kClientDataStreamId1, true, true, GetRequestHeaders("GET", "https", "/"), &header_stream_offset)); - quic_data.AddWrite(ConstructSettingsPacket(2, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, - &header_stream_offset)); + quic_data.AddWrite(ConstructInitialSettingsPacket(2, &header_stream_offset)); // Peer sending data from an non-existing stream causes this end to raise // error and close connection. quic_data.AddRead( @@ -1799,9 +1777,8 @@ std::string settings_data; QuicStreamOffset settings_offset = header_stream_offset; - quic_data.AddWrite(client_maker_.MakeSettingsPacketAndSaveData( - 2, SETTINGS_MAX_HEADER_LIST_SIZE, kDefaultMaxUncompressedHeaderSize, true, - &header_stream_offset, &settings_data)); + quic_data.AddWrite(client_maker_.MakeInitialSettingsPacketAndSaveData( + 2, &header_stream_offset, &settings_data)); // TLP 1 quic_data.AddWrite(client_maker_.MakeDataPacket(3, kHeadersStreamId, true, false, 0, request_data)); @@ -1917,9 +1894,8 @@ std::string settings_data; QuicStreamOffset settings_offset = header_stream_offset; - quic_data.AddWrite(client_maker_.MakeSettingsPacketAndSaveData( - 2, SETTINGS_MAX_HEADER_LIST_SIZE, kDefaultMaxUncompressedHeaderSize, true, - &header_stream_offset, &settings_data)); + quic_data.AddWrite(client_maker_.MakeInitialSettingsPacketAndSaveData( + 2, &header_stream_offset, &settings_data)); // TLP 1 quic_data.AddWrite(client_maker_.MakeDataPacket(3, kHeadersStreamId, true, false, 0, request_data)); @@ -2038,9 +2014,8 @@ std::string settings_data; QuicStreamOffset settings_offset = header_stream_offset; - quic_data.AddWrite(client_maker_.MakeSettingsPacketAndSaveData( - 2, SETTINGS_MAX_HEADER_LIST_SIZE, kDefaultMaxUncompressedHeaderSize, true, - &header_stream_offset, &settings_data)); + quic_data.AddWrite(client_maker_.MakeInitialSettingsPacketAndSaveData( + 2, &header_stream_offset, &settings_data)); quic_data.AddRead(ConstructServerResponseHeadersPacket( 1, kClientDataStreamId1, false, false, GetResponseHeaders("200 OK"))); @@ -2150,9 +2125,8 @@ std::string settings_data; QuicStreamOffset settings_offset = header_stream_offset; - quic_data.AddWrite(client_maker_.MakeSettingsPacketAndSaveData( - 2, SETTINGS_MAX_HEADER_LIST_SIZE, kDefaultMaxUncompressedHeaderSize, true, - &header_stream_offset, &settings_data)); + quic_data.AddWrite(client_maker_.MakeInitialSettingsPacketAndSaveData( + 2, &header_stream_offset, &settings_data)); // TLP 1 quic_data.AddWrite(client_maker_.MakeDataPacket(3, kHeadersStreamId, true, false, 0, request_data)); @@ -2276,9 +2250,8 @@ std::string settings_data; QuicStreamOffset settings_offset = header_stream_offset; - quic_data.AddWrite(client_maker_.MakeSettingsPacketAndSaveData( - 2, SETTINGS_MAX_HEADER_LIST_SIZE, kDefaultMaxUncompressedHeaderSize, true, - &header_stream_offset, &settings_data)); + quic_data.AddWrite(client_maker_.MakeInitialSettingsPacketAndSaveData( + 2, &header_stream_offset, &settings_data)); quic_data.AddWrite(client_maker_.MakeRstPacket(3, true, kClientDataStreamId1, QUIC_STREAM_CANCELLED)); @@ -2377,9 +2350,7 @@ quic_data.AddWrite(ConstructClientRequestHeadersPacket( 1, kClientDataStreamId1, true, true, GetRequestHeaders("GET", "https", "/"), &header_stream_offset)); - quic_data.AddWrite(ConstructSettingsPacket(2, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, - &header_stream_offset)); + quic_data.AddWrite(ConstructInitialSettingsPacket(2, &header_stream_offset)); // Peer sending data from an non-existing stream causes this end to raise // error and close connection. quic_data.AddRead( @@ -2500,9 +2471,8 @@ // Open a session to foo.example.org:443 using the first entry of the // alternative service list. MockQuicData mock_quic_data; - mock_quic_data.AddWrite(ConstructSettingsPacket( - 1, SETTINGS_MAX_HEADER_LIST_SIZE, kDefaultMaxUncompressedHeaderSize, - &request_header_offset)); + mock_quic_data.AddWrite( + ConstructInitialSettingsPacket(1, &request_header_offset)); mock_quic_data.AddWrite(ConstructClientRequestHeadersPacket( 2, kClientDataStreamId1, true, true, GetRequestHeaders("GET", "https", "/"), &request_header_offset)); @@ -2555,9 +2525,8 @@ // Open a session to foo.example.org:443 using the first entry of the // alternative service list. MockQuicData mock_quic_data; - mock_quic_data.AddWrite(ConstructSettingsPacket( - 1, SETTINGS_MAX_HEADER_LIST_SIZE, kDefaultMaxUncompressedHeaderSize, - &request_header_offset)); + mock_quic_data.AddWrite( + ConstructInitialSettingsPacket(1, &request_header_offset)); mock_quic_data.AddWrite(ConstructClientRequestHeadersPacket( 2, kClientDataStreamId1, true, true, GetRequestHeaders("GET", "http", "/"), &request_header_offset)); @@ -2622,9 +2591,8 @@ QuicStreamOffset request_header_offset(0); QuicStreamOffset response_header_offset(0); - mock_quic_data.AddWrite(ConstructSettingsPacket( - 1, SETTINGS_MAX_HEADER_LIST_SIZE, kDefaultMaxUncompressedHeaderSize, - &request_header_offset)); + mock_quic_data.AddWrite( + ConstructInitialSettingsPacket(1, &request_header_offset)); // First request. mock_quic_data.AddWrite(ConstructClientRequestHeadersPacket( 2, kClientDataStreamId1, true, true, @@ -2691,10 +2659,8 @@ QuicStreamOffset request_header_offset(0); QuicStreamOffset response_header_offset(0); - mock_quic_data.AddWrite(ConstructSettingsPacket( - 1, SETTINGS_MAX_HEADER_LIST_SIZE, kDefaultMaxUncompressedHeaderSize, - &request_header_offset)); - + mock_quic_data.AddWrite( + ConstructInitialSettingsPacket(1, &request_header_offset)); // First request. mock_quic_data.AddWrite(ConstructClientRequestHeadersPacket( 2, kClientDataStreamId1, true, true, @@ -2806,9 +2772,8 @@ server_maker_.set_hostname("www.example.org"); client_maker_.set_hostname("www.example.org"); MockQuicData mock_quic_data; - mock_quic_data.AddWrite(ConstructSettingsPacket( - 1, SETTINGS_MAX_HEADER_LIST_SIZE, kDefaultMaxUncompressedHeaderSize, - &request_header_offset)); + mock_quic_data.AddWrite( + ConstructInitialSettingsPacket(1, &request_header_offset)); // First QUIC request data. mock_quic_data.AddWrite(ConstructClientRequestHeadersPacket( 2, kClientDataStreamId1, true, true, @@ -2898,9 +2863,8 @@ MockQuicData mock_quic_data; QuicStreamOffset header_stream_offset = 0; - mock_quic_data.AddWrite(ConstructSettingsPacket( - 1, SETTINGS_MAX_HEADER_LIST_SIZE, kDefaultMaxUncompressedHeaderSize, - &header_stream_offset)); + mock_quic_data.AddWrite( + ConstructInitialSettingsPacket(1, &header_stream_offset)); mock_quic_data.AddWrite(ConstructClientRequestHeadersPacket( 2, kClientDataStreamId1, true, true, GetRequestHeaders("GET", "https", "/"), &header_stream_offset)); @@ -2950,9 +2914,8 @@ MockQuicData mock_quic_data; QuicStreamOffset header_stream_offset = 0; - mock_quic_data.AddWrite(ConstructSettingsPacket( - 1, SETTINGS_MAX_HEADER_LIST_SIZE, kDefaultMaxUncompressedHeaderSize, - &header_stream_offset)); + mock_quic_data.AddWrite( + ConstructInitialSettingsPacket(1, &header_stream_offset)); mock_quic_data.AddWrite(ConstructClientRequestHeadersPacket( 2, kClientDataStreamId1, true, true, GetRequestHeaders("GET", "https", "/"), &header_stream_offset)); @@ -2981,9 +2944,8 @@ MockQuicData mock_quic_data; QuicStreamOffset header_stream_offset = 0; - mock_quic_data.AddWrite(ConstructSettingsPacket( - 1, SETTINGS_MAX_HEADER_LIST_SIZE, kDefaultMaxUncompressedHeaderSize, - &header_stream_offset)); + mock_quic_data.AddWrite( + ConstructInitialSettingsPacket(1, &header_stream_offset)); mock_quic_data.AddWrite(ConstructClientRequestHeadersPacket( 2, kClientDataStreamId1, true, true, GetRequestHeaders("GET", "http", "/"), &header_stream_offset)); @@ -3177,9 +3139,8 @@ TEST_P(QuicNetworkTransactionTest, ZeroRTTWithConfirmationRequired) { MockQuicData mock_quic_data; QuicStreamOffset header_stream_offset = 0; - mock_quic_data.AddWrite(ConstructSettingsPacket( - 1, SETTINGS_MAX_HEADER_LIST_SIZE, kDefaultMaxUncompressedHeaderSize, - &header_stream_offset)); + mock_quic_data.AddWrite( + ConstructInitialSettingsPacket(1, &header_stream_offset)); mock_quic_data.AddWrite(ConstructClientRequestHeadersPacket( 2, kClientDataStreamId1, true, true, GetRequestHeaders("GET", "https", "/"), &header_stream_offset)); @@ -3230,9 +3191,8 @@ LogGranularQuicErrorCodeOnQuicProtocolErrorLocal) { MockQuicData mock_quic_data; QuicStreamOffset header_stream_offset = 0; - mock_quic_data.AddWrite(ConstructSettingsPacket( - 1, SETTINGS_MAX_HEADER_LIST_SIZE, kDefaultMaxUncompressedHeaderSize, - &header_stream_offset)); + mock_quic_data.AddWrite( + ConstructInitialSettingsPacket(1, &header_stream_offset)); mock_quic_data.AddWrite(ConstructClientRequestHeadersPacket( 2, kClientDataStreamId1, true, true, GetRequestHeaders("GET", "https", "/"), &header_stream_offset)); @@ -3284,9 +3244,8 @@ LogGranularQuicErrorCodeOnQuicProtocolErrorRemote) { MockQuicData mock_quic_data; QuicStreamOffset header_stream_offset = 0; - mock_quic_data.AddWrite(ConstructSettingsPacket( - 1, SETTINGS_MAX_HEADER_LIST_SIZE, kDefaultMaxUncompressedHeaderSize, - &header_stream_offset)); + mock_quic_data.AddWrite( + ConstructInitialSettingsPacket(1, &header_stream_offset)); mock_quic_data.AddWrite(ConstructClientRequestHeadersPacket( 2, kClientDataStreamId1, true, true, GetRequestHeaders("GET", "https", "/"), &header_stream_offset)); @@ -3340,9 +3299,8 @@ TEST_P(QuicNetworkTransactionTest, RstSteamErrorHandling) { MockQuicData mock_quic_data; QuicStreamOffset header_stream_offset = 0; - mock_quic_data.AddWrite(ConstructSettingsPacket( - 1, SETTINGS_MAX_HEADER_LIST_SIZE, kDefaultMaxUncompressedHeaderSize, - &header_stream_offset)); + mock_quic_data.AddWrite( + ConstructInitialSettingsPacket(1, &header_stream_offset)); mock_quic_data.AddWrite(ConstructClientRequestHeadersPacket( 2, kClientDataStreamId1, true, true, GetRequestHeaders("GET", "https", "/"), &header_stream_offset)); @@ -3403,9 +3361,8 @@ TEST_P(QuicNetworkTransactionTest, RstSteamBeforeHeaders) { MockQuicData mock_quic_data; QuicStreamOffset header_stream_offset = 0; - mock_quic_data.AddWrite(ConstructSettingsPacket( - 1, SETTINGS_MAX_HEADER_LIST_SIZE, kDefaultMaxUncompressedHeaderSize, - &header_stream_offset)); + mock_quic_data.AddWrite( + ConstructInitialSettingsPacket(1, &header_stream_offset)); mock_quic_data.AddWrite(ConstructClientRequestHeadersPacket( 2, kClientDataStreamId1, true, true, GetRequestHeaders("GET", "https", "/"), &header_stream_offset)); @@ -3746,9 +3703,8 @@ test_socket_performance_watcher_factory_.rtt_notification_received()); MockQuicData mock_quic_data; QuicStreamOffset header_stream_offset = 0; - mock_quic_data.AddWrite(ConstructSettingsPacket( - 1, SETTINGS_MAX_HEADER_LIST_SIZE, kDefaultMaxUncompressedHeaderSize, - &header_stream_offset)); + mock_quic_data.AddWrite( + ConstructInitialSettingsPacket(1, &header_stream_offset)); mock_quic_data.AddWrite(ConstructClientRequestHeadersPacket( 2, kClientDataStreamId1, true, true, GetRequestHeaders("GET", "https", "/"), &header_stream_offset)); @@ -3862,9 +3818,7 @@ MockQuicData socket_data; socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); QuicStreamOffset offset = 0; - socket_data.AddWrite( - ConstructSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, &offset)); + socket_data.AddWrite(ConstructInitialSettingsPacket(1, &offset)); socket_data.AddWrite(ConstructClientRequestHeadersPacket( 2, kClientDataStreamId1, true, false, GetRequestHeaders("POST", "https", "/"), &offset)); @@ -3907,9 +3861,8 @@ MockQuicData mock_quic_data; QuicStreamOffset header_stream_offset = 0; - mock_quic_data.AddWrite(ConstructSettingsPacket( - 1, SETTINGS_MAX_HEADER_LIST_SIZE, kDefaultMaxUncompressedHeaderSize, - &header_stream_offset)); + mock_quic_data.AddWrite( + ConstructInitialSettingsPacket(1, &header_stream_offset)); mock_quic_data.AddWrite(ConstructClientRequestHeadersPacket( 2, kClientDataStreamId1, true, true, GetRequestHeaders("GET", "https", "/"), &header_stream_offset)); @@ -3968,9 +3921,7 @@ MockQuicData mock_quic_data; QuicStreamOffset offset = 0; - mock_quic_data.AddWrite( - ConstructSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, &offset)); + mock_quic_data.AddWrite(ConstructInitialSettingsPacket(1, &offset)); mock_quic_data.AddWrite(ConstructClientRequestHeadersPacket( 2, kClientDataStreamId1, true, false, GetRequestHeaders("POST", "https", "/"), &offset)); @@ -4050,9 +4001,8 @@ MockQuicData mock_quic_data; QuicStreamOffset header_stream_offset = 0; - mock_quic_data.AddWrite(ConstructSettingsPacket( - 1, SETTINGS_MAX_HEADER_LIST_SIZE, kDefaultMaxUncompressedHeaderSize, - &header_stream_offset)); + mock_quic_data.AddWrite( + ConstructInitialSettingsPacket(1, &header_stream_offset)); SpdyHeaderBlock headers(GetRequestHeaders("GET", "https", "/")); headers["user-agent"] = ""; headers["accept-encoding"] = "gzip, deflate"; @@ -4108,9 +4058,8 @@ MockQuicData mock_quic_data; QuicStreamOffset header_stream_offset = 0; - mock_quic_data.AddWrite(ConstructSettingsPacket( - 1, SETTINGS_MAX_HEADER_LIST_SIZE, kDefaultMaxUncompressedHeaderSize, - &header_stream_offset)); + mock_quic_data.AddWrite( + ConstructInitialSettingsPacket(1, &header_stream_offset)); SpdyHeaderBlock headers(GetRequestHeaders("GET", "https", "/")); headers["user-agent"] = ""; headers["accept-encoding"] = "gzip, deflate"; @@ -4315,14 +4264,11 @@ smallest_received, least_unacked, true); } - std::unique_ptr<QuicReceivedPacket> ConstructSettingsPacket( + std::unique_ptr<QuicReceivedPacket> ConstructInitialSettingsPacket( QuicPacketNumber packet_number, - SpdySettingsIds id, - size_t value, QuicStreamOffset* offset, QuicTestPacketMaker* maker) { - return maker->MakeSettingsPacket(packet_number, id, value, kIncludeVersion, - offset); + return maker->MakeInitialSettingsPacket(packet_number, offset); } void AddRefusedSocketData() { @@ -4484,9 +4430,8 @@ QuicStreamOffset response_header_offset(0); MockQuicData mock_quic_data; - mock_quic_data.AddWrite(ConstructSettingsPacket( - 1, SETTINGS_MAX_HEADER_LIST_SIZE, kDefaultMaxUncompressedHeaderSize, - &request_header_offset, &client_maker1)); + mock_quic_data.AddWrite(ConstructInitialSettingsPacket( + 1, &request_header_offset, &client_maker1)); mock_quic_data.AddWrite(ConstructClientRequestHeadersPacket( 2, kClientDataStreamId1, true, &request_header_offset, &client_maker1)); mock_quic_data.AddRead(ConstructServerResponseHeadersPacket( @@ -4561,9 +4506,8 @@ MockQuicData mock_quic_data1; QuicStreamOffset header_stream_offset1 = 0; - mock_quic_data1.AddWrite(ConstructSettingsPacket( - 1, SETTINGS_MAX_HEADER_LIST_SIZE, kDefaultMaxUncompressedHeaderSize, - &header_stream_offset1, &client_maker1)); + mock_quic_data1.AddWrite(ConstructInitialSettingsPacket( + 1, &header_stream_offset1, &client_maker1)); mock_quic_data1.AddWrite(ConstructClientRequestHeadersPacket( 2, kClientDataStreamId1, true, &header_stream_offset1, &client_maker1)); mock_quic_data1.AddRead(ConstructServerResponseHeadersPacket( @@ -4586,9 +4530,8 @@ MockQuicData mock_quic_data2; QuicStreamOffset header_stream_offset2 = 0; - mock_quic_data2.AddWrite(ConstructSettingsPacket( - 1, SETTINGS_MAX_HEADER_LIST_SIZE, kDefaultMaxUncompressedHeaderSize, - &header_stream_offset2, &client_maker2)); + mock_quic_data2.AddWrite(ConstructInitialSettingsPacket( + 1, &header_stream_offset2, &client_maker2)); mock_quic_data2.AddWrite(ConstructClientRequestHeadersPacket( 2, kClientDataStreamId1, true, &header_stream_offset2, &client_maker2)); mock_quic_data2.AddRead(ConstructServerResponseHeadersPacket( @@ -4618,9 +4561,8 @@ MockQuicData mock_quic_data; QuicStreamOffset header_stream_offset = 0; - mock_quic_data.AddWrite(ConstructSettingsPacket( - 1, SETTINGS_MAX_HEADER_LIST_SIZE, kDefaultMaxUncompressedHeaderSize, - &header_stream_offset)); + mock_quic_data.AddWrite( + ConstructInitialSettingsPacket(1, &header_stream_offset)); mock_quic_data.AddWrite(ConstructClientRequestHeadersPacket( 2, kClientDataStreamId1, true, true, GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
diff --git a/net/quic/chromium/quic_stream_factory_test.cc b/net/quic/chromium/quic_stream_factory_test.cc index d6d0b9d..7246829 100644 --- a/net/quic/chromium/quic_stream_factory_test.cc +++ b/net/quic/chromium/quic_stream_factory_test.cc
@@ -278,9 +278,7 @@ MockQuicData socket_data; socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); - socket_data.AddWrite( - ConstructSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, nullptr)); + socket_data.AddWrite(ConstructInitialSettingsPacket()); socket_data.AddSocketDataToFactory(&socket_factory_); QuicStreamRequest request(factory_.get(), &http_server_properties_); @@ -392,13 +390,14 @@ std::move(headers), &spdy_headers_frame_len); } - std::unique_ptr<QuicReceivedPacket> ConstructSettingsPacket( + std::unique_ptr<QuicReceivedPacket> ConstructInitialSettingsPacket() { + return client_maker_.MakeInitialSettingsPacket(1, nullptr); + } + + std::unique_ptr<QuicReceivedPacket> ConstructInitialSettingsPacket( QuicPacketNumber packet_number, - SpdySettingsIds id, - size_t value, QuicStreamOffset* offset) { - return client_maker_.MakeSettingsPacket(packet_number, id, value, - kIncludeVersion, offset); + return client_maker_.MakeInitialSettingsPacket(packet_number, offset); } // Helper method for server migration tests. @@ -419,9 +418,7 @@ // migration. MockQuicData socket_data2; socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); - socket_data2.AddWrite( - ConstructSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, nullptr)); + socket_data2.AddWrite(ConstructInitialSettingsPacket()); socket_data2.AddWrite( client_maker_.MakePingPacket(2, /*include_version=*/true)); socket_data2.AddWrite(client_maker_.MakeRstPacket( @@ -759,9 +756,7 @@ MockQuicData socket_data; socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); - socket_data.AddWrite( - ConstructSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, nullptr)); + socket_data.AddWrite(ConstructInitialSettingsPacket()); socket_data.AddSocketDataToFactory(&socket_factory_); QuicStreamRequest request(factory_.get(), &http_server_properties_); @@ -855,9 +850,7 @@ MockQuicData socket_data; socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); - socket_data.AddWrite( - ConstructSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, nullptr)); + socket_data.AddWrite(ConstructInitialSettingsPacket()); socket_data.AddSocketDataToFactory(&socket_factory_); QuicStreamRequest request(factory_.get(), &http_server_properties_); @@ -888,9 +881,7 @@ MockQuicData socket_data; socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); - socket_data.AddWrite( - ConstructSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, nullptr)); + socket_data.AddWrite(ConstructInitialSettingsPacket()); socket_data.AddSocketDataToFactory(&socket_factory_); QuicStreamRequest request(factory_.get(), &http_server_properties_); @@ -921,9 +912,7 @@ MockQuicData socket_data; socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); - socket_data.AddWrite( - ConstructSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, nullptr)); + socket_data.AddWrite(ConstructInitialSettingsPacket()); socket_data.AddSocketDataToFactory(&socket_factory_); QuicStreamRequest request(factory_.get(), &http_server_properties_); @@ -954,9 +943,7 @@ MockQuicData socket_data; socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); - socket_data.AddWrite( - ConstructSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, nullptr)); + socket_data.AddWrite(ConstructInitialSettingsPacket()); socket_data.AddSocketDataToFactory(&socket_factory_); QuicStreamRequest request(factory_.get(), &http_server_properties_); @@ -982,9 +969,7 @@ MockQuicData socket_data; socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); - socket_data.AddWrite( - ConstructSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, nullptr)); + socket_data.AddWrite(ConstructInitialSettingsPacket()); socket_data.AddSocketDataToFactory(&socket_factory_); QuicStreamRequest request(factory_.get(), &http_server_properties_); @@ -1014,9 +999,7 @@ MockQuicData socket_data; socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); - socket_data.AddWrite( - ConstructSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, nullptr)); + socket_data.AddWrite(ConstructInitialSettingsPacket()); socket_data.AddSocketDataToFactory(&socket_factory_); QuicStreamRequest request(factory_.get(), &http_server_properties_); @@ -1055,9 +1038,7 @@ MockQuicData socket_data; socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); - socket_data.AddWrite( - ConstructSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, nullptr)); + socket_data.AddWrite(ConstructInitialSettingsPacket()); socket_data.AddSocketDataToFactory(&socket_factory_); HostPortPair server2(kServer2HostName, kDefaultServerPort); @@ -1108,9 +1089,7 @@ MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)}; std::unique_ptr<QuicEncryptedPacket> settings_packet( - client_maker_.MakeSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, true, - nullptr)); + client_maker_.MakeInitialSettingsPacket(1, nullptr)); MockWrite writes[] = {MockWrite(SYNCHRONOUS, settings_packet->data(), settings_packet->length(), 1)}; @@ -1147,15 +1126,11 @@ MockQuicData socket_data1; socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); - socket_data1.AddWrite( - ConstructSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, nullptr)); + socket_data1.AddWrite(ConstructInitialSettingsPacket()); socket_data1.AddSocketDataToFactory(&socket_factory_); MockQuicData socket_data2; socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); - socket_data2.AddWrite( - ConstructSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, nullptr)); + socket_data2.AddWrite(ConstructInitialSettingsPacket()); socket_data2.AddSocketDataToFactory(&socket_factory_); HostPortPair server2(kServer2HostName, kDefaultServerPort); @@ -1204,9 +1179,7 @@ MockQuicData socket_data; socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); - socket_data.AddWrite( - ConstructSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, nullptr)); + socket_data.AddWrite(ConstructInitialSettingsPacket()); socket_data.AddSocketDataToFactory(&socket_factory_); HostPortPair server1(kDefaultServerHostName, 443); @@ -1244,9 +1217,7 @@ Initialize(); MockQuicData socket_data; socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); - socket_data.AddWrite( - ConstructSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, nullptr)); + socket_data.AddWrite(ConstructInitialSettingsPacket()); socket_data.AddSocketDataToFactory(&socket_factory_); HostPortPair server1(kDefaultServerHostName, 443); @@ -1291,15 +1262,11 @@ MockQuicData socket_data1; socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); - socket_data1.AddWrite( - ConstructSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, nullptr)); + socket_data1.AddWrite(ConstructInitialSettingsPacket()); socket_data1.AddSocketDataToFactory(&socket_factory_); MockQuicData socket_data2; socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); - socket_data2.AddWrite( - ConstructSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, nullptr)); + socket_data2.AddWrite(ConstructInitialSettingsPacket()); socket_data2.AddSocketDataToFactory(&socket_factory_); HostPortPair server1(kDefaultServerHostName, 443); @@ -1355,15 +1322,11 @@ MockQuicData socket_data; socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); - socket_data.AddWrite( - ConstructSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, nullptr)); + socket_data.AddWrite(ConstructInitialSettingsPacket()); socket_data.AddSocketDataToFactory(&socket_factory_); MockQuicData socket_data2; socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); - socket_data2.AddWrite( - ConstructSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, nullptr)); + socket_data2.AddWrite(ConstructInitialSettingsPacket()); socket_data2.AddSocketDataToFactory(&socket_factory_); QuicStreamRequest request(factory_.get(), &http_server_properties_); @@ -1416,9 +1379,7 @@ QuicStreamId stream_id = kClientDataStreamId1; MockQuicData socket_data; - socket_data.AddWrite( - ConstructSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, nullptr)); + socket_data.AddWrite(ConstructInitialSettingsPacket()); socket_data.AddWrite( client_maker_.MakeRstPacket(2, true, stream_id, QUIC_STREAM_CANCELLED)); socket_data.AddRead( @@ -1517,9 +1478,7 @@ Initialize(); MockQuicData socket_data; socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); - socket_data.AddWrite( - ConstructSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, nullptr)); + socket_data.AddWrite(ConstructInitialSettingsPacket()); socket_data.AddSocketDataToFactory(&socket_factory_); { QuicStreamRequest request(factory_.get(), &http_server_properties_); @@ -1552,17 +1511,13 @@ MockQuicData socket_data; socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); - socket_data.AddWrite( - ConstructSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, nullptr)); + socket_data.AddWrite(ConstructInitialSettingsPacket()); socket_data.AddWrite(ConstructClientRstPacket(2)); socket_data.AddSocketDataToFactory(&socket_factory_); MockQuicData socket_data2; socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); - socket_data2.AddWrite( - ConstructSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, nullptr)); + socket_data2.AddWrite(ConstructInitialSettingsPacket()); socket_data2.AddSocketDataToFactory(&socket_factory_); QuicStreamRequest request(factory_.get(), &http_server_properties_); @@ -1635,9 +1590,7 @@ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details); MockQuicData socket_data2; socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); - socket_data2.AddWrite( - ConstructSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, nullptr)); + socket_data2.AddWrite(ConstructInitialSettingsPacket()); socket_data2.AddSocketDataToFactory(&socket_factory_); QuicStreamRequest request2(factory_.get(), &http_server_properties_); @@ -1699,9 +1652,7 @@ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details); MockQuicData socket_data2; socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); - socket_data2.AddWrite( - ConstructSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, nullptr)); + socket_data2.AddWrite(ConstructInitialSettingsPacket()); socket_data2.AddSocketDataToFactory(&socket_factory_); QuicStreamRequest request2(factory_.get(), &http_server_properties_); @@ -1738,17 +1689,13 @@ MockQuicData socket_data; socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); - socket_data.AddWrite( - ConstructSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, nullptr)); + socket_data.AddWrite(ConstructInitialSettingsPacket()); socket_data.AddWrite(ConstructClientRstPacket(2)); socket_data.AddSocketDataToFactory(&socket_factory_); MockQuicData socket_data2; socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); - socket_data2.AddWrite( - ConstructSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, nullptr)); + socket_data2.AddWrite(ConstructInitialSettingsPacket()); socket_data2.AddSocketDataToFactory(&socket_factory_); QuicStreamRequest request(factory_.get(), &http_server_properties_); @@ -1807,9 +1754,8 @@ MockQuicData socket_data; QuicStreamOffset header_stream_offset = 0; socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); - socket_data.AddWrite(ConstructSettingsPacket( - packet_number++, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, &header_stream_offset)); + socket_data.AddWrite( + ConstructInitialSettingsPacket(packet_number++, &header_stream_offset)); socket_data.AddWrite(ConstructGetRequestPacket(packet_number++, kClientDataStreamId1, true, true, &header_stream_offset)); @@ -1884,9 +1830,7 @@ // new session is created. MockQuicData socket_data2; socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); - socket_data2.AddWrite( - ConstructSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, nullptr)); + socket_data2.AddWrite(ConstructInitialSettingsPacket()); socket_data2.AddSocketDataToFactory(&socket_factory_); QuicStreamRequest request2(factory_.get(), &http_server_properties_); @@ -1940,9 +1884,8 @@ MockQuicData socket_data; QuicStreamOffset header_stream_offset = 0; socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); - socket_data.AddWrite(ConstructSettingsPacket( - packet_number++, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, &header_stream_offset)); + socket_data.AddWrite( + ConstructInitialSettingsPacket(packet_number++, &header_stream_offset)); socket_data.AddWrite(ConstructGetRequestPacket(packet_number++, kClientDataStreamId1, true, true, &header_stream_offset)); @@ -2012,9 +1955,7 @@ // new session is created. MockQuicData socket_data2; socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); - socket_data2.AddWrite( - ConstructSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, nullptr)); + socket_data2.AddWrite(ConstructInitialSettingsPacket()); socket_data2.AddSocketDataToFactory(&socket_factory_); QuicStreamRequest request2(factory_.get(), &http_server_properties_); @@ -2061,9 +2002,7 @@ MockQuicData socket_data; socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); - socket_data.AddWrite( - ConstructSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, nullptr)); + socket_data.AddWrite(ConstructInitialSettingsPacket()); socket_data.AddSocketDataToFactory(&socket_factory_); // Create request and QuicHttpStream. @@ -2119,9 +2058,7 @@ MockQuicData socket_data; socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); - socket_data.AddWrite( - ConstructSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, nullptr)); + socket_data.AddWrite(ConstructInitialSettingsPacket()); socket_data.AddWrite(client_maker_.MakeRstPacket( 2, true, kClientDataStreamId1, QUIC_STREAM_CANCELLED)); socket_data.AddSocketDataToFactory(&socket_factory_); @@ -2170,9 +2107,7 @@ MockQuicData socket_data; socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); - socket_data.AddWrite( - ConstructSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, nullptr)); + socket_data.AddWrite(ConstructInitialSettingsPacket()); socket_data.AddWrite(client_maker_.MakeRstPacket( 2, true, kClientDataStreamId1, QUIC_STREAM_CANCELLED)); socket_data.AddSocketDataToFactory(&socket_factory_); @@ -2224,9 +2159,7 @@ MockQuicData socket_data; socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); - socket_data.AddWrite( - ConstructSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, nullptr)); + socket_data.AddWrite(ConstructInitialSettingsPacket()); socket_data.AddWrite(client_maker_.MakeRstPacket( 2, true, kClientDataStreamId1, QUIC_RST_ACKNOWLEDGEMENT)); socket_data.AddSocketDataToFactory(&socket_factory_); @@ -2274,9 +2207,7 @@ MockQuicData socket_data; socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); - socket_data.AddWrite( - ConstructSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, nullptr)); + socket_data.AddWrite(ConstructInitialSettingsPacket()); socket_data.AddWrite(client_maker_.MakeRstPacket( 2, true, kClientDataStreamId1, QUIC_RST_ACKNOWLEDGEMENT)); socket_data.AddSocketDataToFactory(&socket_factory_); @@ -2326,9 +2257,7 @@ MockQuicData socket_data; socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); - socket_data.AddWrite( - ConstructSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, nullptr)); + socket_data.AddWrite(ConstructInitialSettingsPacket()); socket_data.AddSocketDataToFactory(&socket_factory_); // Create request and QuicHttpStream. @@ -2366,9 +2295,7 @@ MockQuicData socket_data; socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); - socket_data.AddWrite( - ConstructSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, nullptr)); + socket_data.AddWrite(ConstructInitialSettingsPacket()); socket_data.AddSocketDataToFactory(&socket_factory_); // Create request and QuicHttpStream. @@ -2407,9 +2334,8 @@ MockQuicData socket_data; QuicStreamOffset header_stream_offset = 0; socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); - socket_data.AddWrite(ConstructSettingsPacket( - 1, SETTINGS_MAX_HEADER_LIST_SIZE, kDefaultMaxUncompressedHeaderSize, - &header_stream_offset)); + socket_data.AddWrite( + ConstructInitialSettingsPacket(1, &header_stream_offset)); socket_data.AddWrite(ConstructGetRequestPacket(2, kClientDataStreamId1, true, true, &header_stream_offset)); socket_data.AddSocketDataToFactory(&socket_factory_); @@ -2488,9 +2414,7 @@ // Create a new request and verify that a new session is created. MockQuicData socket_data2; socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); - socket_data2.AddWrite( - ConstructSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, nullptr)); + socket_data2.AddWrite(ConstructInitialSettingsPacket()); socket_data2.AddSocketDataToFactory(&socket_factory_); QuicStreamRequest request2(factory_.get(), &http_server_properties_); EXPECT_EQ(ERR_IO_PENDING, @@ -2520,16 +2444,12 @@ MockQuicData socket_data1; socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); - socket_data1.AddWrite( - ConstructSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, nullptr)); + socket_data1.AddWrite(ConstructInitialSettingsPacket()); socket_data1.AddWrite(ASYNC, OK); socket_data1.AddSocketDataToFactory(&socket_factory_); MockQuicData socket_data2; socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); - socket_data2.AddWrite( - ConstructSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, nullptr)); + socket_data2.AddWrite(ConstructInitialSettingsPacket()); socket_data2.AddWrite(ASYNC, OK); socket_data2.AddSocketDataToFactory(&socket_factory_); @@ -2630,9 +2550,8 @@ MockQuicData socket_data; QuicStreamOffset header_stream_offset = 0; socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); - socket_data.AddWrite(ConstructSettingsPacket( - 1, SETTINGS_MAX_HEADER_LIST_SIZE, kDefaultMaxUncompressedHeaderSize, - &header_stream_offset)); + socket_data.AddWrite( + ConstructInitialSettingsPacket(1, &header_stream_offset)); socket_data.AddWrite(ConstructGetRequestPacket(2, kClientDataStreamId1, true, true, &header_stream_offset)); socket_data.AddSocketDataToFactory(&socket_factory_); @@ -2698,9 +2617,7 @@ // new session is created. MockQuicData socket_data2; socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); - socket_data2.AddWrite( - ConstructSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, nullptr)); + socket_data2.AddWrite(ConstructInitialSettingsPacket()); socket_data2.AddSocketDataToFactory(&socket_factory_); QuicStreamRequest request2(factory_.get(), &http_server_properties_); @@ -2757,9 +2674,8 @@ MockQuicData socket_data; QuicStreamOffset header_stream_offset = 0; socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); - socket_data.AddWrite(ConstructSettingsPacket( - 1, SETTINGS_MAX_HEADER_LIST_SIZE, kDefaultMaxUncompressedHeaderSize, - &header_stream_offset)); + socket_data.AddWrite( + ConstructInitialSettingsPacket(1, &header_stream_offset)); socket_data.AddWrite(ConstructGetRequestPacket(2, kClientDataStreamId1, true, true, &header_stream_offset)); socket_data.AddSocketDataToFactory(&socket_factory_); @@ -2827,9 +2743,7 @@ // new session is created. MockQuicData socket_data2; socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); - socket_data2.AddWrite( - ConstructSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, nullptr)); + socket_data2.AddWrite(ConstructInitialSettingsPacket()); socket_data2.AddSocketDataToFactory(&socket_factory_); QuicStreamRequest request2(factory_.get(), &http_server_properties_); @@ -2879,9 +2793,7 @@ MockQuicData socket_data; socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); - socket_data.AddWrite( - ConstructSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, nullptr)); + socket_data.AddWrite(ConstructInitialSettingsPacket()); socket_data.AddWrite(client_maker_.MakeRstPacket( 2, true, kClientDataStreamId1, QUIC_STREAM_CANCELLED)); socket_data.AddSocketDataToFactory(&socket_factory_); @@ -2933,9 +2845,7 @@ MockQuicData socket_data; socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); - socket_data.AddWrite( - ConstructSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, nullptr)); + socket_data.AddWrite(ConstructInitialSettingsPacket()); socket_data.AddWrite(client_maker_.MakeRstPacket( 2, true, kClientDataStreamId1, QUIC_STREAM_CANCELLED)); socket_data.AddSocketDataToFactory(&socket_factory_); @@ -2987,9 +2897,7 @@ MockQuicData socket_data; socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); - socket_data.AddWrite( - ConstructSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, nullptr)); + socket_data.AddWrite(ConstructInitialSettingsPacket()); socket_data.AddWrite(client_maker_.MakeRstPacket( 2, true, kClientDataStreamId1, QUIC_STREAM_CANCELLED)); socket_data.AddSocketDataToFactory(&socket_factory_); @@ -3047,9 +2955,8 @@ MockQuicData socket_data; QuicStreamOffset header_stream_offset = 0; socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); - socket_data.AddWrite(ConstructSettingsPacket( - 1, SETTINGS_MAX_HEADER_LIST_SIZE, kDefaultMaxUncompressedHeaderSize, - &header_stream_offset)); + socket_data.AddWrite( + ConstructInitialSettingsPacket(1, &header_stream_offset)); socket_data.AddWrite(write_error_mode, ERR_ADDRESS_UNREACHABLE); socket_data.AddSocketDataToFactory(&socket_factory_); @@ -3137,9 +3044,7 @@ MockQuicData socket_data; socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); - socket_data.AddWrite( - ConstructSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, nullptr)); + socket_data.AddWrite(ConstructInitialSettingsPacket()); socket_data.AddWrite(write_error_mode, ERR_ADDRESS_UNREACHABLE); socket_data.AddSocketDataToFactory(&socket_factory_); @@ -3228,9 +3133,7 @@ MockQuicData socket_data; socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); - socket_data.AddWrite( - ConstructSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, nullptr)); + socket_data.AddWrite(ConstructInitialSettingsPacket()); socket_data.AddWrite(write_error_mode, ERR_ADDRESS_UNREACHABLE); socket_data.AddSocketDataToFactory(&socket_factory_); @@ -3294,9 +3197,7 @@ MockQuicData socket_data; socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); - socket_data.AddWrite( - ConstructSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, nullptr)); + socket_data.AddWrite(ConstructInitialSettingsPacket()); socket_data.AddWrite(write_error_mode, ERR_ADDRESS_UNREACHABLE); socket_data.AddSocketDataToFactory(&socket_factory_); @@ -3370,9 +3271,7 @@ if (i < kMaxReadersPerQuicSession) { socket_data[i].AddRead(SYNCHRONOUS, ERR_IO_PENDING); if (i == 0) { - socket_data[i].AddWrite(ConstructSettingsPacket( - 1, SETTINGS_MAX_HEADER_LIST_SIZE, kDefaultMaxUncompressedHeaderSize, - nullptr)); + socket_data[i].AddWrite(ConstructInitialSettingsPacket(1, nullptr)); } socket_data[i].AddWrite( (i % 2 == 0) ? first_write_error_mode : second_write_error_mode, @@ -3456,9 +3355,8 @@ MockQuicData socket_data; QuicStreamOffset header_stream_offset = 0; socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); - socket_data.AddWrite(ConstructSettingsPacket( - 1, SETTINGS_MAX_HEADER_LIST_SIZE, kDefaultMaxUncompressedHeaderSize, - &header_stream_offset)); + socket_data.AddWrite( + ConstructInitialSettingsPacket(1, &header_stream_offset)); socket_data.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE); socket_data.AddSocketDataToFactory(&socket_factory_); @@ -3554,9 +3452,8 @@ MockQuicData socket_data; QuicStreamOffset header_stream_offset = 0; socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); - socket_data.AddWrite(ConstructSettingsPacket( - 1, SETTINGS_MAX_HEADER_LIST_SIZE, kDefaultMaxUncompressedHeaderSize, - &header_stream_offset)); + socket_data.AddWrite( + ConstructInitialSettingsPacket(1, &header_stream_offset)); socket_data.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE); socket_data.AddSocketDataToFactory(&socket_factory_); @@ -3653,9 +3550,8 @@ MockQuicData socket_data; QuicStreamOffset header_stream_offset = 0; socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); - socket_data.AddWrite(ConstructSettingsPacket( - 1, SETTINGS_MAX_HEADER_LIST_SIZE, kDefaultMaxUncompressedHeaderSize, - &header_stream_offset)); + socket_data.AddWrite( + ConstructInitialSettingsPacket(1, &header_stream_offset)); socket_data.AddWrite(SYNCHRONOUS, ERR_FAILED); socket_data.AddSocketDataToFactory(&socket_factory_); @@ -3737,9 +3633,7 @@ // new session is created. MockQuicData socket_data2; socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); - socket_data2.AddWrite( - ConstructSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, nullptr)); + socket_data2.AddWrite(ConstructInitialSettingsPacket()); socket_data2.AddSocketDataToFactory(&socket_factory_); QuicStreamRequest request2(factory_.get(), &http_server_properties_); @@ -3788,9 +3682,8 @@ MockQuicData socket_data; QuicStreamOffset header_stream_offset = 0; socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); - socket_data.AddWrite(ConstructSettingsPacket( - 1, SETTINGS_MAX_HEADER_LIST_SIZE, kDefaultMaxUncompressedHeaderSize, - &header_stream_offset)); + socket_data.AddWrite( + ConstructInitialSettingsPacket(1, &header_stream_offset)); socket_data.AddWrite(SYNCHRONOUS, ERR_FAILED); socket_data.AddSocketDataToFactory(&socket_factory_); @@ -3880,9 +3773,7 @@ // new session is created. MockQuicData socket_data2; socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); - socket_data2.AddWrite( - ConstructSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, nullptr)); + socket_data2.AddWrite(ConstructInitialSettingsPacket()); socket_data2.AddSocketDataToFactory(&socket_factory_); QuicStreamRequest request2(factory_.get(), &http_server_properties_); @@ -3943,9 +3834,8 @@ MockQuicData socket_data; QuicStreamOffset header_stream_offset = 0; socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); - socket_data.AddWrite(ConstructSettingsPacket( - 1, SETTINGS_MAX_HEADER_LIST_SIZE, kDefaultMaxUncompressedHeaderSize, - &header_stream_offset)); + socket_data.AddWrite( + ConstructInitialSettingsPacket(1, &header_stream_offset)); socket_data.AddWrite(ConstructGetRequestPacket(2, kClientDataStreamId1, true, true, &header_stream_offset)); socket_data.AddSocketDataToFactory(&socket_factory_); @@ -4007,9 +3897,8 @@ MockQuicData socket_data1; QuicStreamOffset header_stream_offset = 0; socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); - socket_data1.AddWrite(ConstructSettingsPacket( - 1, SETTINGS_MAX_HEADER_LIST_SIZE, kDefaultMaxUncompressedHeaderSize, - &header_stream_offset)); + socket_data1.AddWrite( + ConstructInitialSettingsPacket(1, &header_stream_offset)); socket_data1.AddWrite(ConstructGetRequestPacket(2, kClientDataStreamId1, true, true, &header_stream_offset)); socket_data1.AddSocketDataToFactory(&socket_factory_); @@ -4150,9 +4039,7 @@ // Set up only socket data provider. MockQuicData socket_data1; socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); - socket_data1.AddWrite( - ConstructSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, nullptr)); + socket_data1.AddWrite(ConstructInitialSettingsPacket()); socket_data1.AddWrite(client_maker_.MakeRstPacket( 2, true, kClientDataStreamId1, QUIC_STREAM_CANCELLED)); socket_data1.AddSocketDataToFactory(&socket_factory_); @@ -4203,17 +4090,13 @@ MockQuicData socket_data; socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); - socket_data.AddWrite( - ConstructSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, nullptr)); + socket_data.AddWrite(ConstructInitialSettingsPacket()); socket_data.AddWrite(ConstructClientRstPacket(2)); socket_data.AddSocketDataToFactory(&socket_factory_); MockQuicData socket_data2; socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); - socket_data2.AddWrite( - ConstructSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, nullptr)); + socket_data2.AddWrite(ConstructInitialSettingsPacket(1, nullptr)); socket_data2.AddSocketDataToFactory(&socket_factory_); QuicStreamRequest request(factory_.get(), &http_server_properties_); @@ -4260,17 +4143,13 @@ MockQuicData socket_data; socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); - socket_data.AddWrite( - ConstructSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, nullptr)); + socket_data.AddWrite(ConstructInitialSettingsPacket()); socket_data.AddWrite(ConstructClientRstPacket(2)); socket_data.AddSocketDataToFactory(&socket_factory_); MockQuicData socket_data2; socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); - socket_data2.AddWrite( - ConstructSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, nullptr)); + socket_data2.AddWrite(ConstructInitialSettingsPacket(1, nullptr)); socket_data2.AddSocketDataToFactory(&socket_factory_); QuicStreamRequest request(factory_.get(), &http_server_properties_); @@ -4425,16 +4304,12 @@ MockQuicData socket_data; socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); - socket_data.AddWrite( - ConstructSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, nullptr)); + socket_data.AddWrite(ConstructInitialSettingsPacket()); socket_data.AddSocketDataToFactory(&socket_factory_); MockQuicData socket_data2; socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); - socket_data2.AddWrite( - ConstructSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, nullptr)); + socket_data2.AddWrite(ConstructInitialSettingsPacket(1, nullptr)); socket_data2.AddSocketDataToFactory(&socket_factory_); HostPortPair server2(kServer2HostName, kDefaultServerPort); @@ -4524,9 +4399,7 @@ MockQuicData socket_data; socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); - socket_data.AddWrite( - ConstructSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, nullptr)); + socket_data.AddWrite(ConstructInitialSettingsPacket()); socket_data.AddSocketDataToFactory(&socket_factory_); // Save current state of |race_cert_verification|. @@ -4675,9 +4548,7 @@ MockQuicData socket_data; socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); - socket_data.AddWrite( - ConstructSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, nullptr)); + socket_data.AddWrite(ConstructInitialSettingsPacket()); socket_data.AddSocketDataToFactory(&socket_factory_); QuicStreamRequest request(factory_.get(), &http_server_properties_); @@ -4716,18 +4587,14 @@ MockQuicData socket_data1; socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); - socket_data1.AddWrite( - ConstructSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, nullptr)); + socket_data1.AddWrite(ConstructInitialSettingsPacket()); socket_data1.AddWrite(client_maker_.MakeRstPacket( 2, true, kServerDataStreamId1, QUIC_STREAM_CANCELLED)); socket_data1.AddSocketDataToFactory(&socket_factory_); MockQuicData socket_data2; socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); - socket_data2.AddWrite( - ConstructSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, nullptr)); + socket_data2.AddWrite(ConstructInitialSettingsPacket()); socket_data2.AddSocketDataToFactory(&socket_factory_); QuicStreamRequest request(factory_.get(), &http_server_properties_); @@ -4787,9 +4654,7 @@ MockQuicData socket_data; socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); - socket_data.AddWrite( - ConstructSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, nullptr)); + socket_data.AddWrite(ConstructInitialSettingsPacket()); socket_data.AddSocketDataToFactory(&socket_factory_); QuicStreamRequest request1(factory_.get(), &http_server_properties_); @@ -4832,9 +4697,7 @@ MockQuicData socket_data; socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); - socket_data.AddWrite( - ConstructSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, nullptr)); + socket_data.AddWrite(ConstructInitialSettingsPacket()); socket_data.AddSocketDataToFactory(&socket_factory_); QuicStreamRequest request(factory_.get(), &http_server_properties_); @@ -4968,9 +4831,7 @@ MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)}; std::unique_ptr<QuicEncryptedPacket> settings_packet( - client_maker_.MakeSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, true, - nullptr)); + client_maker_.MakeInitialSettingsPacket(1, nullptr)); MockWrite writes[] = {MockWrite(SYNCHRONOUS, settings_packet->data(), settings_packet->length(), 1)}; std::unique_ptr<SequencedSocketData> sequenced_socket_data( @@ -5038,9 +4899,7 @@ MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)}; std::unique_ptr<QuicEncryptedPacket> settings_packet( - client_maker_.MakeSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, true, - nullptr)); + client_maker_.MakeInitialSettingsPacket(1, nullptr)); MockWrite writes[] = {MockWrite(SYNCHRONOUS, settings_packet->data(), settings_packet->length(), 1)}; std::unique_ptr<SequencedSocketData> sequenced_socket_data( @@ -5123,9 +4982,7 @@ MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)}; std::unique_ptr<QuicEncryptedPacket> settings_packet( - client_maker_.MakeSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE, - kDefaultMaxUncompressedHeaderSize, true, - nullptr)); + client_maker_.MakeInitialSettingsPacket(1, nullptr)); MockWrite writes[] = {MockWrite(SYNCHRONOUS, settings_packet->data(), settings_packet->length(), 1)}; std::unique_ptr<SequencedSocketData> sequenced_socket_data(
diff --git a/net/quic/chromium/quic_test_packet_maker.cc b/net/quic/chromium/quic_test_packet_maker.cc index 1ef4ac83..6a692ec 100644 --- a/net/quic/chromium/quic_test_packet_maker.cc +++ b/net/quic/chromium/quic_test_packet_maker.cc
@@ -651,30 +651,25 @@ header_.packet_number = packet_number; } -std::unique_ptr<QuicReceivedPacket> QuicTestPacketMaker::MakeSettingsPacket( - QuicPacketNumber packet_number, - SpdySettingsIds id, - size_t value, - bool should_include_version, - QuicStreamOffset* offset) { +std::unique_ptr<QuicReceivedPacket> +QuicTestPacketMaker::MakeInitialSettingsPacket(QuicPacketNumber packet_number, + QuicStreamOffset* offset) { std::string unused_data; - return MakeSettingsPacketAndSaveData( - packet_number, id, value, should_include_version, offset, &unused_data); + return MakeInitialSettingsPacketAndSaveData(packet_number, offset, + &unused_data); } std::unique_ptr<QuicReceivedPacket> -QuicTestPacketMaker::MakeSettingsPacketAndSaveData( +QuicTestPacketMaker::MakeInitialSettingsPacketAndSaveData( QuicPacketNumber packet_number, - SpdySettingsIds id, - size_t value, - bool should_include_version, QuicStreamOffset* offset, std::string* stream_data) { SpdySettingsIR settings_frame; - settings_frame.AddSetting(id, value); + settings_frame.AddSetting(SETTINGS_MAX_HEADER_LIST_SIZE, + kDefaultMaxUncompressedHeaderSize); SpdySerializedFrame spdy_frame( spdy_request_framer_.SerializeFrame(settings_frame)); - InitializeHeader(packet_number, should_include_version); + InitializeHeader(packet_number, /*should_include_version*/ true); *stream_data = std::string(spdy_frame.data(), spdy_frame.size()); if (offset != nullptr) { QuicStreamFrame quic_frame(
diff --git a/net/quic/chromium/quic_test_packet_maker.h b/net/quic/chromium/quic_test_packet_maker.h index 6bfb4cc..eb3f53c 100644 --- a/net/quic/chromium/quic_test_packet_maker.h +++ b/net/quic/chromium/quic_test_packet_maker.h
@@ -216,20 +216,16 @@ SpdyHeaderBlock headers, QuicStreamOffset* offset); - std::unique_ptr<QuicReceivedPacket> MakeSettingsPacket( + // Creates a packet containing the initial SETTINGS frame, and saves the + // headers stream offset into |offset|. + std::unique_ptr<QuicReceivedPacket> MakeInitialSettingsPacket( QuicPacketNumber packet_number, - SpdySettingsIds id, - size_t value, - bool should_include_version, QuicStreamOffset* offset); // Same as above, but also saves the serialized QUIC stream data in // |stream_data|. - std::unique_ptr<QuicReceivedPacket> MakeSettingsPacketAndSaveData( + std::unique_ptr<QuicReceivedPacket> MakeInitialSettingsPacketAndSaveData( QuicPacketNumber packet_number, - SpdySettingsIds id, - size_t value, - bool should_include_version, QuicStreamOffset* offset, std::string* stream_data);
diff --git a/net/spdy/core/array_output_buffer.h b/net/spdy/core/array_output_buffer.h index cfcd0b8a..c9b147a 100644 --- a/net/spdy/core/array_output_buffer.h +++ b/net/spdy/core/array_output_buffer.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef NET_SPDY_ARRAY_OUTPUT_BUFFER_H_ -#define NET_SPDY_ARRAY_OUTPUT_BUFFER_H_ +#ifndef NET_SPDY_CORE_ARRAY_OUTPUT_BUFFER_H_ +#define NET_SPDY_CORE_ARRAY_OUTPUT_BUFFER_H_ #include <cstddef> #include "net/spdy/core/zero_copy_output_buffer.h" @@ -42,4 +42,4 @@ } // namespace net -#endif // NET_SPDY_ARRAY_OUTPUT_BUFFER_H_ +#endif // NET_SPDY_CORE_ARRAY_OUTPUT_BUFFER_H_
diff --git a/net/spdy/core/fuzzing/hpack_fuzz_util.h b/net/spdy/core/fuzzing/hpack_fuzz_util.h index 0072e298..0a37e34 100644 --- a/net/spdy/core/fuzzing/hpack_fuzz_util.h +++ b/net/spdy/core/fuzzing/hpack_fuzz_util.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef NET_SPDY_FUZZING_HPACK_FUZZ_UTIL_H_ -#define NET_SPDY_FUZZING_HPACK_FUZZ_UTIL_H_ +#ifndef NET_SPDY_CORE_FUZZING_HPACK_FUZZ_UTIL_H_ +#define NET_SPDY_CORE_FUZZING_HPACK_FUZZ_UTIL_H_ #include <stddef.h> #include <stdint.h> @@ -92,4 +92,4 @@ } // namespace net -#endif // NET_SPDY_FUZZING_HPACK_FUZZ_UTIL_H_ +#endif // NET_SPDY_CORE_FUZZING_HPACK_FUZZ_UTIL_H_
diff --git a/net/spdy/core/hpack/hpack_constants.h b/net/spdy/core/hpack/hpack_constants.h index fdfb0d12..f1ae5f9 100644 --- a/net/spdy/core/hpack/hpack_constants.h +++ b/net/spdy/core/hpack/hpack_constants.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef NET_SPDY_HPACK_HPACK_CONSTANTS_H_ -#define NET_SPDY_HPACK_HPACK_CONSTANTS_H_ +#ifndef NET_SPDY_CORE_HPACK_HPACK_CONSTANTS_H_ +#define NET_SPDY_CORE_HPACK_HPACK_CONSTANTS_H_ #include <stddef.h> #include <stdint.h> @@ -90,4 +90,4 @@ } // namespace net -#endif // NET_SPDY_HPACK_HPACK_CONSTANTS_H_ +#endif // NET_SPDY_CORE_HPACK_HPACK_CONSTANTS_H_
diff --git a/net/spdy/core/hpack/hpack_decoder.h b/net/spdy/core/hpack/hpack_decoder.h index 05e501d..a13c61e 100644 --- a/net/spdy/core/hpack/hpack_decoder.h +++ b/net/spdy/core/hpack/hpack_decoder.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef NET_SPDY_HPACK_HPACK_DECODER_H_ -#define NET_SPDY_HPACK_HPACK_DECODER_H_ +#ifndef NET_SPDY_CORE_HPACK_HPACK_DECODER_H_ +#define NET_SPDY_CORE_HPACK_HPACK_DECODER_H_ #include <stddef.h> #include <stdint.h> @@ -152,4 +152,4 @@ } // namespace net -#endif // NET_SPDY_HPACK_HPACK_DECODER_H_ +#endif // NET_SPDY_CORE_HPACK_HPACK_DECODER_H_
diff --git a/net/spdy/core/hpack/hpack_decoder3.h b/net/spdy/core/hpack/hpack_decoder3.h index da9e5fb4..b388155 100644 --- a/net/spdy/core/hpack/hpack_decoder3.h +++ b/net/spdy/core/hpack/hpack_decoder3.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef NET_SPDY_HPACK_HPACK_DECODER3_H_ -#define NET_SPDY_HPACK_HPACK_DECODER3_H_ +#ifndef NET_SPDY_CORE_HPACK_HPACK_DECODER3_H_ +#define NET_SPDY_CORE_HPACK_HPACK_DECODER3_H_ // HpackDecoder3 implements HpackDecoderInterface, using Http2HpackDecoder to // decode HPACK blocks into HTTP/2 header lists as outlined in @@ -128,4 +128,4 @@ } // namespace net -#endif // NET_SPDY_HPACK_HPACK_DECODER3_H_ +#endif // NET_SPDY_CORE_HPACK_HPACK_DECODER3_H_
diff --git a/net/spdy/core/hpack/hpack_decoder_interface.h b/net/spdy/core/hpack/hpack_decoder_interface.h index 7cc84a9..828e799 100644 --- a/net/spdy/core/hpack/hpack_decoder_interface.h +++ b/net/spdy/core/hpack/hpack_decoder_interface.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef NET_SPDY_HPACK_HPACK_DECODER_INTERFACE_H_ -#define NET_SPDY_HPACK_HPACK_DECODER_INTERFACE_H_ +#ifndef NET_SPDY_CORE_HPACK_HPACK_DECODER_INTERFACE_H_ +#define NET_SPDY_CORE_HPACK_HPACK_DECODER_INTERFACE_H_ // HpackDecoderInterface is the base class for HPACK block decoders. // HPACK is defined in http://tools.ietf.org/html/rfc7541 @@ -73,4 +73,4 @@ } // namespace net -#endif // NET_SPDY_HPACK_HPACK_DECODER_INTERFACE_H_ +#endif // NET_SPDY_CORE_HPACK_HPACK_DECODER_INTERFACE_H_
diff --git a/net/spdy/core/hpack/hpack_encoder.h b/net/spdy/core/hpack/hpack_encoder.h index 72144c5b..b691ba7 100644 --- a/net/spdy/core/hpack/hpack_encoder.h +++ b/net/spdy/core/hpack/hpack_encoder.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef NET_SPDY_HPACK_HPACK_ENCODER_H_ -#define NET_SPDY_HPACK_HPACK_ENCODER_H_ +#ifndef NET_SPDY_CORE_HPACK_HPACK_ENCODER_H_ +#define NET_SPDY_CORE_HPACK_HPACK_ENCODER_H_ #include <stddef.h> @@ -153,4 +153,4 @@ } // namespace net -#endif // NET_SPDY_HPACK_HPACK_ENCODER_H_ +#endif // NET_SPDY_CORE_HPACK_HPACK_ENCODER_H_
diff --git a/net/spdy/core/hpack/hpack_entry.h b/net/spdy/core/hpack/hpack_entry.h index 0d4287f..e59b3297 100644 --- a/net/spdy/core/hpack/hpack_entry.h +++ b/net/spdy/core/hpack/hpack_entry.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef NET_SPDY_HPACK_HPACK_ENTRY_H_ -#define NET_SPDY_HPACK_HPACK_ENTRY_H_ +#ifndef NET_SPDY_CORE_HPACK_HPACK_ENTRY_H_ +#define NET_SPDY_CORE_HPACK_HPACK_ENTRY_H_ #include <stddef.h> @@ -106,4 +106,4 @@ } // namespace net -#endif // NET_SPDY_HPACK_HPACK_ENTRY_H_ +#endif // NET_SPDY_CORE_HPACK_HPACK_ENTRY_H_
diff --git a/net/spdy/core/hpack/hpack_header_table.h b/net/spdy/core/hpack/hpack_header_table.h index d6f2b91..aedb3d4 100644 --- a/net/spdy/core/hpack/hpack_header_table.h +++ b/net/spdy/core/hpack/hpack_header_table.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef NET_SPDY_HPACK_HPACK_HEADER_TABLE_H_ -#define NET_SPDY_HPACK_HPACK_HEADER_TABLE_H_ +#ifndef NET_SPDY_CORE_HPACK_HPACK_HEADER_TABLE_H_ +#define NET_SPDY_CORE_HPACK_HPACK_HEADER_TABLE_H_ #include <cstddef> #include <deque> @@ -174,4 +174,4 @@ } // namespace net -#endif // NET_SPDY_HPACK_HPACK_HEADER_TABLE_H_ +#endif // NET_SPDY_CORE_HPACK_HPACK_HEADER_TABLE_H_
diff --git a/net/spdy/core/hpack/hpack_huffman_decoder.h b/net/spdy/core/hpack/hpack_huffman_decoder.h index 1e5d3ce..9820565 100644 --- a/net/spdy/core/hpack/hpack_huffman_decoder.h +++ b/net/spdy/core/hpack/hpack_huffman_decoder.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef NET_SPDY_HPACK_HPACK_HUFFMAN_DECODER_H_ -#define NET_SPDY_HPACK_HPACK_HUFFMAN_DECODER_H_ +#ifndef NET_SPDY_CORE_HPACK_HPACK_HUFFMAN_DECODER_H_ +#define NET_SPDY_CORE_HPACK_HPACK_HUFFMAN_DECODER_H_ #include <stddef.h> #include <stdint.h> @@ -64,4 +64,4 @@ } // namespace net -#endif // NET_SPDY_HPACK_HPACK_HUFFMAN_DECODER_H_ +#endif // NET_SPDY_CORE_HPACK_HPACK_HUFFMAN_DECODER_H_
diff --git a/net/spdy/core/hpack/hpack_huffman_table.h b/net/spdy/core/hpack/hpack_huffman_table.h index 22142bf..fe2d0fd 100644 --- a/net/spdy/core/hpack/hpack_huffman_table.h +++ b/net/spdy/core/hpack/hpack_huffman_table.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef NET_SPDY_HPACK_HPACK_HUFFMAN_TABLE_H_ -#define NET_SPDY_HPACK_HPACK_HUFFMAN_TABLE_H_ +#ifndef NET_SPDY_CORE_HPACK_HPACK_HUFFMAN_TABLE_H_ +#define NET_SPDY_CORE_HPACK_HPACK_HUFFMAN_TABLE_H_ #include <stdint.h> @@ -131,4 +131,4 @@ } // namespace net -#endif // NET_SPDY_HPACK_HPACK_HUFFMAN_TABLE_H_ +#endif // NET_SPDY_CORE_HPACK_HPACK_HUFFMAN_TABLE_H_
diff --git a/net/spdy/core/hpack/hpack_input_stream.h b/net/spdy/core/hpack/hpack_input_stream.h index a1e14d1..555ea30 100644 --- a/net/spdy/core/hpack/hpack_input_stream.h +++ b/net/spdy/core/hpack/hpack_input_stream.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef NET_SPDY_HPACK_HPACK_INPUT_STREAM_H_ -#define NET_SPDY_HPACK_HPACK_INPUT_STREAM_H_ +#ifndef NET_SPDY_CORE_HPACK_HPACK_INPUT_STREAM_H_ +#define NET_SPDY_CORE_HPACK_HPACK_INPUT_STREAM_H_ #include <stddef.h> #include <stdint.h> @@ -110,4 +110,4 @@ } // namespace net -#endif // NET_SPDY_HPACK_HPACK_INPUT_STREAM_H_ +#endif // NET_SPDY_CORE_HPACK_HPACK_INPUT_STREAM_H_
diff --git a/net/spdy/core/hpack/hpack_output_stream.h b/net/spdy/core/hpack/hpack_output_stream.h index c4befc4..eeee31e 100644 --- a/net/spdy/core/hpack/hpack_output_stream.h +++ b/net/spdy/core/hpack/hpack_output_stream.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef NET_SPDY_HPACK_HPACK_OUTPUT_STREAM_H_ -#define NET_SPDY_HPACK_HPACK_OUTPUT_STREAM_H_ +#ifndef NET_SPDY_CORE_HPACK_HPACK_OUTPUT_STREAM_H_ +#define NET_SPDY_CORE_HPACK_HPACK_OUTPUT_STREAM_H_ #include <stddef.h> #include <stdint.h> @@ -75,4 +75,4 @@ } // namespace net -#endif // NET_SPDY_HPACK_HPACK_OUTPUT_STREAM_H_ +#endif // NET_SPDY_CORE_HPACK_HPACK_OUTPUT_STREAM_H_
diff --git a/net/spdy/core/hpack/hpack_static_table.h b/net/spdy/core/hpack/hpack_static_table.h index d839e1c1..564dab5 100644 --- a/net/spdy/core/hpack/hpack_static_table.h +++ b/net/spdy/core/hpack/hpack_static_table.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef NET_SPDY_HPACK_HPACK_STATIC_TABLE_H_ -#define NET_SPDY_HPACK_HPACK_STATIC_TABLE_H_ +#ifndef NET_SPDY_CORE_HPACK_HPACK_STATIC_TABLE_H_ +#define NET_SPDY_CORE_HPACK_HPACK_STATIC_TABLE_H_ #include <stddef.h> @@ -53,4 +53,4 @@ } // namespace net -#endif // NET_SPDY_HPACK_HPACK_STATIC_TABLE_H_ +#endif // NET_SPDY_CORE_HPACK_HPACK_STATIC_TABLE_H_
diff --git a/net/spdy/core/http2_frame_decoder_adapter.h b/net/spdy/core/http2_frame_decoder_adapter.h index 42dcbf7..9914d811 100644 --- a/net/spdy/core/http2_frame_decoder_adapter.h +++ b/net/spdy/core/http2_frame_decoder_adapter.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef NET_SPDY_HTTP2_FRAME_DECODER_ADAPTER_H_ -#define NET_SPDY_HTTP2_FRAME_DECODER_ADAPTER_H_ +#ifndef NET_SPDY_CORE_HTTP2_FRAME_DECODER_ADAPTER_H_ +#define NET_SPDY_CORE_HTTP2_FRAME_DECODER_ADAPTER_H_ // Provides a SpdyFramerDecoderAdapter that uses Http2FrameDecoder for decoding // HTTP/2 frames. The adapter does not directly decode HPACK, but instead calls @@ -21,4 +21,4 @@ } // namespace net -#endif // NET_SPDY_HTTP2_FRAME_DECODER_ADAPTER_H_ +#endif // NET_SPDY_CORE_HTTP2_FRAME_DECODER_ADAPTER_H_
diff --git a/net/spdy/core/lifo_write_scheduler.h b/net/spdy/core/lifo_write_scheduler.h index 7c78f56..f66b818 100644 --- a/net/spdy/core/lifo_write_scheduler.h +++ b/net/spdy/core/lifo_write_scheduler.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef NET_SPDY_LIFO_WRITE_SCHEDULER_H_ -#define NET_SPDY_LIFO_WRITE_SCHEDULER_H_ +#ifndef NET_SPDY_CORE_LIFO_WRITE_SCHEDULER_H_ +#define NET_SPDY_CORE_LIFO_WRITE_SCHEDULER_H_ #include <map> #include <set> @@ -180,4 +180,4 @@ } // namespace net -#endif // NET_SPDY_LIFO_WRITE_SCHEDULER_H_ +#endif // NET_SPDY_CORE_LIFO_WRITE_SCHEDULER_H_
diff --git a/net/spdy/core/mock_spdy_framer_visitor.h b/net/spdy/core/mock_spdy_framer_visitor.h index ab74c6be..b74f8a9 100644 --- a/net/spdy/core/mock_spdy_framer_visitor.h +++ b/net/spdy/core/mock_spdy_framer_visitor.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef NET_SPDY_MOCK_SPDY_FRAMER_VISITOR_H_ -#define NET_SPDY_MOCK_SPDY_FRAMER_VISITOR_H_ +#ifndef NET_SPDY_CORE_MOCK_SPDY_FRAMER_VISITOR_H_ +#define NET_SPDY_CORE_MOCK_SPDY_FRAMER_VISITOR_H_ #include <stddef.h> #include <stdint.h> @@ -101,4 +101,4 @@ } // namespace net -#endif // NET_SPDY_MOCK_SPDY_FRAMER_VISITOR_H_ +#endif // NET_SPDY_CORE_MOCK_SPDY_FRAMER_VISITOR_H_
diff --git a/net/spdy/core/priority_write_scheduler.h b/net/spdy/core/priority_write_scheduler.h index 3874309..9cc331f 100644 --- a/net/spdy/core/priority_write_scheduler.h +++ b/net/spdy/core/priority_write_scheduler.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef NET_SPDY_PRIORITY_WRITE_SCHEDULER_H_ -#define NET_SPDY_PRIORITY_WRITE_SCHEDULER_H_ +#ifndef NET_SPDY_CORE_PRIORITY_WRITE_SCHEDULER_H_ +#define NET_SPDY_CORE_PRIORITY_WRITE_SCHEDULER_H_ #include <stddef.h> #include <stdint.h> @@ -295,4 +295,4 @@ } // namespace net -#endif // NET_SPDY_PRIORITY_WRITE_SCHEDULER_H_ +#endif // NET_SPDY_CORE_PRIORITY_WRITE_SCHEDULER_H_
diff --git a/net/spdy/core/spdy_alt_svc_wire_format.h b/net/spdy/core/spdy_alt_svc_wire_format.h index b6b8ee1..8a834f6 100644 --- a/net/spdy/core/spdy_alt_svc_wire_format.h +++ b/net/spdy/core/spdy_alt_svc_wire_format.h
@@ -7,8 +7,8 @@ // fields and HTTP/2 and QUIC ALTSVC frames. See specification at // https://httpwg.github.io/http-extensions/alt-svc.html. -#ifndef NET_SPDY_SPDY_ALT_SVC_WIRE_FORMAT_H_ -#define NET_SPDY_SPDY_ALT_SVC_WIRE_FORMAT_H_ +#ifndef NET_SPDY_CORE_SPDY_ALT_SVC_WIRE_FORMAT_H_ +#define NET_SPDY_CORE_SPDY_ALT_SVC_WIRE_FORMAT_H_ #include <cstdint> #include <vector> @@ -84,4 +84,4 @@ } // namespace net -#endif // NET_SPDY_SPDY_ALT_SVC_WIRE_FORMAT_H_ +#endif // NET_SPDY_CORE_SPDY_ALT_SVC_WIRE_FORMAT_H_
diff --git a/net/spdy/core/spdy_bitmasks.h b/net/spdy/core/spdy_bitmasks.h index 71ad1e6..1e9ddd1 100644 --- a/net/spdy/core/spdy_bitmasks.h +++ b/net/spdy/core/spdy_bitmasks.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef NET_SPDY_SPDY_BITMASKS_H_ -#define NET_SPDY_SPDY_BITMASKS_H_ +#ifndef NET_SPDY_CORE_SPDY_BITMASKS_H_ +#define NET_SPDY_CORE_SPDY_BITMASKS_H_ namespace net { @@ -24,4 +24,4 @@ } // namespace net -#endif // NET_SPDY_SPDY_BITMASKS_H_ +#endif // NET_SPDY_CORE_SPDY_BITMASKS_H_
diff --git a/net/spdy/core/spdy_bug_tracker.h b/net/spdy/core/spdy_bug_tracker.h index fc05f68..9e422e66 100644 --- a/net/spdy/core/spdy_bug_tracker.h +++ b/net/spdy/core/spdy_bug_tracker.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef NET_SPDY_SPDY_BUG_TRACKER_H_ -#define NET_SPDY_SPDY_BUG_TRACKER_H_ +#ifndef NET_SPDY_CORE_SPDY_BUG_TRACKER_H_ +#define NET_SPDY_CORE_SPDY_BUG_TRACKER_H_ #include "base/logging.h" @@ -11,4 +11,4 @@ #define SPDY_BUG_IF(condition) LOG_IF(DFATAL, (condition)) #define FLAGS_spdy_always_log_bugs_for_tests (true) -#endif // NET_SPDY_SPDY_BUG_TRACKER_H_ +#endif // NET_SPDY_CORE_SPDY_BUG_TRACKER_H_
diff --git a/net/spdy/core/spdy_deframer_visitor.h b/net/spdy/core/spdy_deframer_visitor.h index af56253..2a4af3e0 100644 --- a/net/spdy/core/spdy_deframer_visitor.h +++ b/net/spdy/core/spdy_deframer_visitor.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef NET_SPDY_SPDY_DEFRAMER_VISITOR_H_ -#define NET_SPDY_SPDY_DEFRAMER_VISITOR_H_ +#ifndef NET_SPDY_CORE_SPDY_DEFRAMER_VISITOR_H_ +#define NET_SPDY_CORE_SPDY_DEFRAMER_VISITOR_H_ // Supports testing by converting callbacks to SpdyFramerVisitorInterface into // callbacks to SpdyDeframerVisitorInterface, whose arguments are generally @@ -247,4 +247,4 @@ } // namespace test } // namespace net -#endif // NET_SPDY_SPDY_DEFRAMER_VISITOR_H_ +#endif // NET_SPDY_CORE_SPDY_DEFRAMER_VISITOR_H_
diff --git a/net/spdy/core/spdy_frame_builder.h b/net/spdy/core/spdy_frame_builder.h index 14e2f1f..ba15863 100644 --- a/net/spdy/core/spdy_frame_builder.h +++ b/net/spdy/core/spdy_frame_builder.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef NET_SPDY_SPDY_FRAME_BUILDER_H_ -#define NET_SPDY_SPDY_FRAME_BUILDER_H_ +#ifndef NET_SPDY_CORE_SPDY_FRAME_BUILDER_H_ +#define NET_SPDY_CORE_SPDY_FRAME_BUILDER_H_ #include <stddef.h> #include <stdint.h> @@ -165,4 +165,4 @@ } // namespace net -#endif // NET_SPDY_SPDY_FRAME_BUILDER_H_ +#endif // NET_SPDY_CORE_SPDY_FRAME_BUILDER_H_
diff --git a/net/spdy/core/spdy_frame_reader.h b/net/spdy/core/spdy_frame_reader.h index 0037c46..99b6d07 100644 --- a/net/spdy/core/spdy_frame_reader.h +++ b/net/spdy/core/spdy_frame_reader.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef NET_SPDY_SPDY_FRAME_READER_H_ -#define NET_SPDY_SPDY_FRAME_READER_H_ +#ifndef NET_SPDY_CORE_SPDY_FRAME_READER_H_ +#define NET_SPDY_CORE_SPDY_FRAME_READER_H_ #include <stddef.h> #include <stdint.h> @@ -127,4 +127,4 @@ } // namespace net -#endif // NET_SPDY_SPDY_FRAME_READER_H_ +#endif // NET_SPDY_CORE_SPDY_FRAME_READER_H_
diff --git a/net/spdy/core/spdy_framer.h b/net/spdy/core/spdy_framer.h index 6714e723..caa0cc4 100644 --- a/net/spdy/core/spdy_framer.h +++ b/net/spdy/core/spdy_framer.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef NET_SPDY_SPDY_FRAMER_H_ -#define NET_SPDY_SPDY_FRAMER_H_ +#ifndef NET_SPDY_CORE_SPDY_FRAMER_H_ +#define NET_SPDY_CORE_SPDY_FRAMER_H_ #include <stddef.h> #include <stdint.h> @@ -954,4 +954,4 @@ } // namespace net -#endif // NET_SPDY_SPDY_FRAMER_H_ +#endif // NET_SPDY_CORE_SPDY_FRAMER_H_
diff --git a/net/spdy/core/spdy_framer_decoder_adapter.h b/net/spdy/core/spdy_framer_decoder_adapter.h index 84ff6fd..a7a3da4 100644 --- a/net/spdy/core/spdy_framer_decoder_adapter.h +++ b/net/spdy/core/spdy_framer_decoder_adapter.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef NET_SPDY_SPDY_FRAMER_DECODER_ADAPTER_H_ -#define NET_SPDY_SPDY_FRAMER_DECODER_ADAPTER_H_ +#ifndef NET_SPDY_CORE_SPDY_FRAMER_DECODER_ADAPTER_H_ +#define NET_SPDY_CORE_SPDY_FRAMER_DECODER_ADAPTER_H_ #include <stddef.h> @@ -165,4 +165,4 @@ } // namespace net -#endif // NET_SPDY_SPDY_FRAMER_DECODER_ADAPTER_H_ +#endif // NET_SPDY_CORE_SPDY_FRAMER_DECODER_ADAPTER_H_
diff --git a/net/spdy/core/spdy_header_block.h b/net/spdy/core/spdy_header_block.h index 13288a89..4b97465 100644 --- a/net/spdy/core/spdy_header_block.h +++ b/net/spdy/core/spdy_header_block.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef NET_SPDY_SPDY_HEADER_BLOCK_H_ -#define NET_SPDY_SPDY_HEADER_BLOCK_H_ +#ifndef NET_SPDY_CORE_SPDY_HEADER_BLOCK_H_ +#define NET_SPDY_CORE_SPDY_HEADER_BLOCK_H_ #include <stddef.h> @@ -257,4 +257,4 @@ } // namespace net -#endif // NET_SPDY_SPDY_HEADER_BLOCK_H_ +#endif // NET_SPDY_CORE_SPDY_HEADER_BLOCK_H_
diff --git a/net/spdy/core/spdy_header_indexing.h b/net/spdy/core/spdy_header_indexing.h index 69cc08d..006ed85 100644 --- a/net/spdy/core/spdy_header_indexing.h +++ b/net/spdy/core/spdy_header_indexing.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef NET_SPDY_SPDY_HEADER_INDEXING_H_ -#define NET_SPDY_SPDY_HEADER_INDEXING_H_ +#ifndef NET_SPDY_CORE_SPDY_HEADER_INDEXING_H_ +#define NET_SPDY_CORE_SPDY_HEADER_INDEXING_H_ #include <stdint.h> #include <memory> @@ -68,4 +68,4 @@ } // namespace net -#endif // NET_SPDY_SPDY_HEADER_INDEXING_H_ +#endif // NET_SPDY_CORE_SPDY_HEADER_INDEXING_H_
diff --git a/net/spdy/core/spdy_headers_handler_interface.h b/net/spdy/core/spdy_headers_handler_interface.h index 26896ab..caa7e6a 100644 --- a/net/spdy/core/spdy_headers_handler_interface.h +++ b/net/spdy/core/spdy_headers_handler_interface.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef NET_SPDY_SPDY_HEADERS_HANDLER_INTERFACE_H_ -#define NET_SPDY_SPDY_HEADERS_HANDLER_INTERFACE_H_ +#ifndef NET_SPDY_CORE_SPDY_HEADERS_HANDLER_INTERFACE_H_ +#define NET_SPDY_CORE_SPDY_HEADERS_HANDLER_INTERFACE_H_ #include <stddef.h> @@ -43,4 +43,4 @@ } // namespace net -#endif // NET_SPDY_SPDY_HEADERS_HANDLER_INTERFACE_H_ +#endif // NET_SPDY_CORE_SPDY_HEADERS_HANDLER_INTERFACE_H_
diff --git a/net/spdy/core/spdy_no_op_visitor.h b/net/spdy/core/spdy_no_op_visitor.h index fe7af64a..3bc93ca 100644 --- a/net/spdy/core/spdy_no_op_visitor.h +++ b/net/spdy/core/spdy_no_op_visitor.h
@@ -6,8 +6,8 @@ // to make it easier to write tests that need to provide instances. Other // interfaces can be added as needed. -#ifndef NET_SPDY_SPDY_NO_OP_VISITOR_H_ -#define NET_SPDY_SPDY_NO_OP_VISITOR_H_ +#ifndef NET_SPDY_CORE_SPDY_NO_OP_VISITOR_H_ +#define NET_SPDY_CORE_SPDY_NO_OP_VISITOR_H_ #include <cstdint> @@ -87,4 +87,4 @@ } // namespace test } // namespace net -#endif // NET_SPDY_SPDY_NO_OP_VISITOR_H_ +#endif // NET_SPDY_CORE_SPDY_NO_OP_VISITOR_H_
diff --git a/net/spdy/core/spdy_pinnable_buffer_piece.h b/net/spdy/core/spdy_pinnable_buffer_piece.h index c0dc3f2e..2ade03e 100644 --- a/net/spdy/core/spdy_pinnable_buffer_piece.h +++ b/net/spdy/core/spdy_pinnable_buffer_piece.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef NET_SPDY_SPDY_PINNABLE_BUFFER_PIECE_H_ -#define NET_SPDY_SPDY_PINNABLE_BUFFER_PIECE_H_ +#ifndef NET_SPDY_CORE_SPDY_PINNABLE_BUFFER_PIECE_H_ +#define NET_SPDY_CORE_SPDY_PINNABLE_BUFFER_PIECE_H_ #include <stddef.h> @@ -56,4 +56,4 @@ } // namespace net -#endif // NET_SPDY_SPDY_PINNABLE_BUFFER_PIECE_H_ +#endif // NET_SPDY_CORE_SPDY_PINNABLE_BUFFER_PIECE_H_
diff --git a/net/spdy/core/spdy_prefixed_buffer_reader.h b/net/spdy/core/spdy_prefixed_buffer_reader.h index eed174ca..301c742e 100644 --- a/net/spdy/core/spdy_prefixed_buffer_reader.h +++ b/net/spdy/core/spdy_prefixed_buffer_reader.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef NET_SPDY_SPDY_PREFIXED_BUFFER_READER_H_ -#define NET_SPDY_SPDY_PREFIXED_BUFFER_READER_H_ +#ifndef NET_SPDY_CORE_SPDY_PREFIXED_BUFFER_READER_H_ +#define NET_SPDY_CORE_SPDY_PREFIXED_BUFFER_READER_H_ #include <stddef.h> @@ -40,4 +40,4 @@ } // namespace net -#endif // NET_SPDY_SPDY_PREFIXED_BUFFER_READER_H_ +#endif // NET_SPDY_CORE_SPDY_PREFIXED_BUFFER_READER_H_
diff --git a/net/spdy/core/spdy_protocol.h b/net/spdy/core/spdy_protocol.h index ac831d9..5a8031e 100644 --- a/net/spdy/core/spdy_protocol.h +++ b/net/spdy/core/spdy_protocol.h
@@ -6,8 +6,8 @@ // The SPDY 3 spec can be found at: // http://dev.chromium.org/spdy/spdy-protocol/spdy-protocol-draft3 -#ifndef NET_SPDY_SPDY_PROTOCOL_H_ -#define NET_SPDY_SPDY_PROTOCOL_H_ +#ifndef NET_SPDY_CORE_SPDY_PROTOCOL_H_ +#define NET_SPDY_CORE_SPDY_PROTOCOL_H_ #include <stddef.h> #include <stdint.h> @@ -915,4 +915,4 @@ } // namespace net -#endif // NET_SPDY_SPDY_PROTOCOL_H_ +#endif // NET_SPDY_CORE_SPDY_PROTOCOL_H_
diff --git a/net/spdy/core/spdy_protocol_test_utils.h b/net/spdy/core/spdy_protocol_test_utils.h index 3e90230..9159be6 100644 --- a/net/spdy/core/spdy_protocol_test_utils.h +++ b/net/spdy/core/spdy_protocol_test_utils.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef NET_SPDY_SPDY_PROTOCOL_TEST_UTILS_H_ -#define NET_SPDY_SPDY_PROTOCOL_TEST_UTILS_H_ +#ifndef NET_SPDY_CORE_SPDY_PROTOCOL_TEST_UTILS_H_ +#define NET_SPDY_CORE_SPDY_PROTOCOL_TEST_UTILS_H_ // These functions support tests that need to compare two concrete SpdyFrameIR // instances for equality. They return AssertionResult, so they may be used as @@ -156,4 +156,4 @@ } // namespace test } // namespace net -#endif // NET_SPDY_SPDY_PROTOCOL_TEST_UTILS_H_ +#endif // NET_SPDY_CORE_SPDY_PROTOCOL_TEST_UTILS_H_
diff --git a/net/spdy/core/spdy_test_utils.h b/net/spdy/core/spdy_test_utils.h index 69c3b2ea..55751ac8 100644 --- a/net/spdy/core/spdy_test_utils.h +++ b/net/spdy/core/spdy_test_utils.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef NET_SPDY_SPDY_TEST_UTILS_H_ -#define NET_SPDY_SPDY_TEST_UTILS_H_ +#ifndef NET_SPDY_CORE_SPDY_TEST_UTILS_H_ +#define NET_SPDY_CORE_SPDY_TEST_UTILS_H_ #include <stddef.h> #include <stdint.h> @@ -112,4 +112,4 @@ } // namespace test } // namespace net -#endif // NET_SPDY_SPDY_TEST_UTILS_H_ +#endif // NET_SPDY_CORE_SPDY_TEST_UTILS_H_
diff --git a/net/spdy/core/write_scheduler.h b/net/spdy/core/write_scheduler.h index ab284fa..715df88 100644 --- a/net/spdy/core/write_scheduler.h +++ b/net/spdy/core/write_scheduler.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef NET_SPDY_WRITE_SCHEDULER_H_ -#define NET_SPDY_WRITE_SCHEDULER_H_ +#ifndef NET_SPDY_CORE_WRITE_SCHEDULER_H_ +#define NET_SPDY_CORE_WRITE_SCHEDULER_H_ #include <tuple> #include <vector> @@ -148,4 +148,4 @@ } // namespace net -#endif // NET_SPDY_WRITE_SCHEDULER_H_ +#endif // NET_SPDY_CORE_WRITE_SCHEDULER_H_
diff --git a/net/spdy/core/zero_copy_output_buffer.h b/net/spdy/core/zero_copy_output_buffer.h index 2051962..d9330879 100644 --- a/net/spdy/core/zero_copy_output_buffer.h +++ b/net/spdy/core/zero_copy_output_buffer.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef NET_SPDY_ZERO_COPY_OUTPUT_BUFFER_H_ -#define NET_SPDY_ZERO_COPY_OUTPUT_BUFFER_H_ +#ifndef NET_SPDY_CORE_ZERO_COPY_OUTPUT_BUFFER_H_ +#define NET_SPDY_CORE_ZERO_COPY_OUTPUT_BUFFER_H_ #include <cstdint> @@ -27,4 +27,4 @@ } // namespace net -#endif // NET_SPDY_ZERO_COPY_OUTPUT_BUFFER_H_ +#endif // NET_SPDY_CORE_ZERO_COPY_OUTPUT_BUFFER_H_
diff --git a/pdf/out_of_process_instance.cc b/pdf/out_of_process_instance.cc index 2f80e2e..b3f71b3 100644 --- a/pdf/out_of_process_instance.cc +++ b/pdf/out_of_process_instance.cc
@@ -343,9 +343,8 @@ } } - // Only allow the plugin to handle find requests if it is full frame. - if (full_) - SetPluginToHandleFindRequests(); + // Allow the plugin to handle find requests. + SetPluginToHandleFindRequests(); text_input_ = base::MakeUnique<pp::TextInput_Dev>(this);
diff --git a/pdf/pdfium/pdfium_engine.cc b/pdf/pdfium/pdfium_engine.cc index 72a1c646..5bd7fed 100644 --- a/pdf/pdfium/pdfium_engine.cc +++ b/pdf/pdfium/pdfium_engine.cc
@@ -2077,19 +2077,6 @@ if (end_of_search) { // Send the final notification. client_->NotifyNumberOfFindResultsChanged(find_results_.size(), true); - - // When searching is complete, resume finding at a particular index. - // Assuming the user has not clicked the find button in the meanwhile. - if (resume_find_index_.valid() && !current_find_index_.valid()) { - size_t resume_index = resume_find_index_.GetIndex(); - if (resume_index >= find_results_.size()) { - // This might happen if the PDF has some dynamically generated text? - resume_index = 0; - } - current_find_index_.SetIndex(resume_index); - client_->NotifySelectedFindResultChanged(resume_index); - } - resume_find_index_.Invalidate(); } else { pp::CompletionCallback callback = find_factory_.NewCallback(&PDFiumEngine::ContinueFind); @@ -2198,18 +2185,6 @@ } find_results_.insert(find_results_.begin() + result_index, result); UpdateTickMarks(); - - if (current_find_index_.valid()) { - if (result_index <= current_find_index_.GetIndex()) { - // Update the current match index - size_t find_index = current_find_index_.IncrementIndex(); - DCHECK_LT(find_index, find_results_.size()); - client_->NotifySelectedFindResultChanged(current_find_index_.GetIndex()); - } - } else if (!resume_find_index_.valid()) { - // Both indices are invalid. Select the first match. - SelectFindResult(true); - } client_->NotifyNumberOfFindResultsChanged(find_results_.size(), false); } @@ -2224,13 +2199,28 @@ // Move back/forward through the search locations we previously found. size_t new_index; const size_t last_index = find_results_.size() - 1; - if (current_find_index_.valid()) { + + if (resume_find_index_.valid()) { + new_index = resume_find_index_.GetIndex(); + resume_find_index_.Invalidate(); + } else if (current_find_index_.valid()) { size_t current_index = current_find_index_.GetIndex(); if (forward) { - new_index = (current_index >= last_index) ? 0 : current_index + 1; + if (current_index >= last_index) { + current_find_index_.Invalidate(); + client_->NotifySelectedFindResultChanged(-1); + client_->NotifyNumberOfFindResultsChanged(find_results_.size(), true); + return true; + } + new_index = current_index + 1; } else { - new_index = (current_find_index_.GetIndex() == 0) ? last_index - : current_index - 1; + if (current_find_index_.GetIndex() == 0) { + current_find_index_.Invalidate(); + client_->NotifySelectedFindResultChanged(-1); + client_->NotifyNumberOfFindResultsChanged(find_results_.size(), true); + return true; + } + new_index = current_index - 1; } } else { new_index = forward ? 0 : last_index;
diff --git a/ppapi/shared_impl/private/ppb_x509_certificate_private_shared.cc b/ppapi/shared_impl/private/ppb_x509_certificate_private_shared.cc index e69aecc..a2b10dd3 100644 --- a/ppapi/shared_impl/private/ppb_x509_certificate_private_shared.cc +++ b/ppapi/shared_impl/private/ppb_x509_certificate_private_shared.cc
@@ -64,8 +64,8 @@ return StringVar::StringToPPVar(val); } case base::Value::Type::BINARY: { - uint32_t size = static_cast<uint32_t>(value->GetSize()); - const char* buffer = value->GetBuffer(); + uint32_t size = static_cast<uint32_t>(value->GetBlob().size()); + const char* buffer = value->GetBlob().data(); PP_Var array_buffer = PpapiGlobals::Get()->GetVarTracker()->MakeArrayBufferPPVar(size, buffer);
diff --git a/remoting/host/input_injector_x11.cc b/remoting/host/input_injector_x11.cc index 2e4bdc6..df871ca 100644 --- a/remoting/host/input_injector_x11.cc +++ b/remoting/host/input_injector_x11.cc
@@ -10,6 +10,7 @@ #include <X11/extensions/XTest.h> #include <X11/Xlib.h> #include <X11/XKBlib.h> +#include <X11/keysym.h> #undef Status // Xlib.h #defines this, which breaks protobuf headers. #include <set> @@ -121,6 +122,9 @@ // Enables or disables keyboard auto-repeat globally. void SetAutoRepeatEnabled(bool enabled); + // Sets the keyboard lock states to those provided. + void SetLockStates(uint32_t states); + void InjectScrollWheelClicks(int button, int count); // Compensates for global button mappings and resets the XTest device // mapping. @@ -276,6 +280,10 @@ XTestFakeKeyEvent(display_, keycode, False, CurrentTime); } + if (event.has_lock_states()) { + SetLockStates(event.lock_states()); + } + if (pressed_keys_.empty()) { // Disable auto-repeat, if necessary, to avoid triggering auto-repeat // if network congestion delays the key-up event from the client. @@ -347,6 +355,20 @@ XChangeKeyboardControl(display_, KBAutoRepeatMode, &control); } +void InputInjectorX11::Core::SetLockStates(uint32_t states) { + unsigned int caps_lock_mask = XkbKeysymToModifiers(display_, XK_Caps_Lock); + unsigned int num_lock_mask = XkbKeysymToModifiers(display_, XK_Num_Lock); + unsigned int lock_values = 0; + if (states & protocol::KeyEvent::LOCK_STATES_CAPSLOCK) { + lock_values |= caps_lock_mask; + } + if (states & protocol::KeyEvent::LOCK_STATES_NUMLOCK) { + lock_values |= num_lock_mask; + } + XkbLockModifiers(display_, XkbUseCoreKbd, caps_lock_mask | num_lock_mask, + lock_values); +} + void InputInjectorX11::Core::InjectScrollWheelClicks(int button, int count) { if (button < 0) { LOG(WARNING) << "Ignoring unmapped scroll wheel button";
diff --git a/testing/buildbot/chromium.linux.json b/testing/buildbot/chromium.linux.json index da701f6..8cf4ba6e 100644 --- a/testing/buildbot/chromium.linux.json +++ b/testing/buildbot/chromium.linux.json
@@ -245,6 +245,15 @@ "test": "cc_unittests" }, { + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "chrome_public_test_apk" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, "override_compile_targets": [ "chrome_public_test_apk" ],
diff --git a/testing/buildbot/filters/ash_mus_unittests.filter b/testing/buildbot/filters/ash_mus_unittests.filter index ed9440f4c..02224f2 100644 --- a/testing/buildbot/filters/ash_mus_unittests.filter +++ b/testing/buildbot/filters/ash_mus_unittests.filter
@@ -1,6 +1,17 @@ -AcceleratorControllerTest.DisallowedAtModalWindow -AcceleratorControllerTest.GlobalAccelerators -AcceleratorControllerTest.RotateScreen +-AppListPresenterDelegateTest.TinyDisplay +-AppListPresenterDelegateTest.HideOnFocusOut/0 +-AppListPresenterDelegateTest.HideOnFocusOut/1 +-AppListPresenterDelegateTest.RemainVisibleWhenFocusingToApplistContainer/0 +-AppListPresenterDelegateTest.RemainVisibleWhenFocusingToApplistContainer/1 +-AppListPresenterDelegateTest.ClickOutsideBubbleClosesBubble/0 +-AppListPresenterDelegateTest.ClickOutsideBubbleClosesBubble/1 +-AppListPresenterDelegateTest.TapOutsideBubbleClosesBubble/0 +-AppListPresenterDelegateTest.TapOutsideBubbleClosesBubble/1 +-AppListPresenterDelegateTest.NonPrimaryDisplay/0 +-AppListPresenterDelegateTest.NonPrimaryDisplay/1 -AshNativeCursorManagerTest.FractionalScale -AshNativeCursorManagerTest.LockCursor -AshNativeCursorManagerTest.SetCursor
diff --git a/third_party/WebKit/LayoutTests/LeakExpectations b/third_party/WebKit/LayoutTests/LeakExpectations index 2dcf955..bb2608f 100644 --- a/third_party/WebKit/LayoutTests/LeakExpectations +++ b/third_party/WebKit/LayoutTests/LeakExpectations
@@ -84,6 +84,7 @@ # the tests for IndexedDB are skipped. crbug.com/506752 external/wpt/IndexedDB/ [ Skip ] crbug.com/506752 storage/indexeddb/ [ Skip ] +crbug.com/506752 virtual/sharedarraybuffer/storage/indexeddb/ [ Skip ] # ----------------------------------------------------------------- # Untriaged but known leaks of ActiveDOMObject (http).
diff --git a/third_party/WebKit/LayoutTests/SlowTests b/third_party/WebKit/LayoutTests/SlowTests index 5ff05d4..ddf3f1a2 100644 --- a/third_party/WebKit/LayoutTests/SlowTests +++ b/third_party/WebKit/LayoutTests/SlowTests
@@ -9,7 +9,9 @@ # than 2 seconds in Release mode or 6 seconds in Debug mode should be listed here. crbug.com/24182 storage/indexeddb/objectstore-cursor.html [ Slow ] +crbug.com/24182 virtual/sharedarraybuffer/storage/indexeddb/objectstore-cursor.html [ Slow ] crbug.com/24182 storage/indexeddb/mozilla/test_objectStore_openKeyCursor.html [ Slow ] +crbug.com/24182 virtual/sharedarraybuffer/storage/indexeddb/mozilla/test_objectStore_openKeyCursor.html [ Slow ] crbug.com/24182 editing/selection/modify_move/move-by-word-visually-mac.html [ Slow ] crbug.com/24182 editing/selection/modify_move/move-by-word-visually-multi-line.html [ Slow ] crbug.com/24182 compositing/culling/filter-occlusion-blur-large.html [ Slow ] @@ -266,7 +268,9 @@ crbug.com/364250 [ Debug ] virtual/threaded/animations/interpolation/transform-interpolation.html [ Slow ] crbug.com/364250 [ Debug ] virtual/threaded/animations/interpolation/webkit-transform-interpolation.html [ Slow ] crbug.com/402379 [ Win7 Debug ] storage/indexeddb/cursor-continue-validity.html [ Slow ] +crbug.com/402379 [ Win7 Debug ] virtual/sharedarraybuffer/storage/indexeddb/cursor-continue-validity.html [ Slow ] crbug.com/402379 [ Win7 Debug ] storage/indexeddb/mozilla/indexes.html [ Slow ] +crbug.com/402379 [ Win7 Debug ] virtual/sharedarraybuffer/storage/indexeddb/mozilla/indexes.html [ Slow ] crbug.com/504706 [ Linux ] inspector/profiler/heap-snapshot-containment-expansion-preserved-when-sorting.html [ Slow ] crbug.com/504706 [ Linux ] inspector/profiler/heap-snapshot-containment-sorting.html [ Slow ] crbug.com/440452 virtual/display_list_2d_canvas/fast/canvas/canvas-partial-invalidation-zoomed.html [ Slow ] @@ -385,9 +389,12 @@ # IDB Observer tests require multiple browsing contexts/workers interacting with # IndexedDB, which can be slow. crbug.com/660468 [ Linux ] storage/indexeddb/observer-frame.html [ Slow ] +crbug.com/660468 [ Linux ] virtual/sharedarraybuffer/storage/indexeddb/observer-frame.html [ Slow ] crbug.com/660468 [ Linux ] storage/indexeddb/observer-workers.html [ Slow ] +crbug.com/660468 [ Linux ] virtual/sharedarraybuffer/storage/indexeddb/observer-workers.html [ Slow ] crbug.com/660492 [ Linux ] storage/indexeddb/structured-clone.html [ Slow ] +crbug.com/660492 [ Linux ] virtual/sharedarraybuffer/storage/indexeddb/structured-clone.html [ Slow ] # Foreign fetch tests make many requests, and create multiple browsing contexts, # which can be very slow.
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations index 7b50fe93..37bd5389 100644 --- a/third_party/WebKit/LayoutTests/TestExpectations +++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -3352,8 +3352,11 @@ crbug.com/678346 [ Win7 Debug ] fast/dom/shadow/selections-in-shadow.html [ Pass Timeout ] crbug.com/678346 [ Win7 Debug ] virtual/sharedarraybuffer/fast/dom/shadow/selections-in-shadow.html [ Pass Timeout ] crbug.com/678346 [ Win7 Debug ] storage/indexeddb/index-cursor.html [ Pass Timeout ] +crbug.com/678346 [ Win7 Debug ] virtual/sharedarraybuffer/storage/indexeddb/index-cursor.html [ Pass Timeout ] crbug.com/678346 [ Win7 Debug ] storage/indexeddb/mozilla/test_objectStore_openKeyCursor.html [ Pass Timeout ] +crbug.com/678346 [ Win7 Debug ] virtual/sharedarraybuffer/storage/indexeddb/mozilla/test_objectStore_openKeyCursor.html [ Pass Timeout ] crbug.com/678346 [ Win7 Debug ] storage/indexeddb/structured-clone.html [ Pass Timeout ] +crbug.com/678346 [ Win7 Debug ] virtual/sharedarraybuffer/storage/indexeddb/structured-clone.html [ Pass Timeout ] crbug.com/678487 http/tests/inspector/resource-tree/resource-tree-reload.html [ Failure Timeout Pass ] crbug.com/678487 virtual/mojo-loading/http/tests/inspector/resource-tree/resource-tree-reload.html [ Failure Timeout Pass ]
diff --git a/third_party/WebKit/LayoutTests/VirtualTestSuites b/third_party/WebKit/LayoutTests/VirtualTestSuites index 00bf19d..52c8cc84 100644 --- a/third_party/WebKit/LayoutTests/VirtualTestSuites +++ b/third_party/WebKit/LayoutTests/VirtualTestSuites
@@ -300,6 +300,12 @@ }, { "prefix": "sharedarraybuffer", + "base": "storage/indexeddb", + "args": ["--js-flags=--harmony-sharedarraybuffer", + "--enable-blink-features=SharedArrayBuffer"] + }, + { + "prefix": "sharedarraybuffer", "base": "webaudio", "args": ["--js-flags=--harmony-sharedarraybuffer", "--enable-blink-features=SharedArrayBuffer"]
diff --git a/third_party/WebKit/LayoutTests/inspector/sources/debugger-breakpoints/dom-breakpoints-editing-dom-from-inspector.html b/third_party/WebKit/LayoutTests/inspector/sources/debugger-breakpoints/dom-breakpoints-editing-dom-from-inspector.html index b07fde0b..04f0e4a 100644 --- a/third_party/WebKit/LayoutTests/inspector/sources/debugger-breakpoints/dom-breakpoints-editing-dom-from-inspector.html +++ b/third_party/WebKit/LayoutTests/inspector/sources/debugger-breakpoints/dom-breakpoints-editing-dom-from-inspector.html
@@ -7,8 +7,6 @@ function test() { - - var pane = Components.domBreakpointsSidebarPane; InspectorTest.runDebuggerTestSuite([ function testRemoveNode(next) { @@ -17,7 +15,7 @@ function step2(node) { - pane._setBreakpoint(node, Components.DOMBreakpointsSidebarPane.BreakpointTypes.NodeRemoved, true); + InspectorTest.domDebuggerModel.setDOMBreakpoint(node, SDK.DOMDebuggerModel.DOMBreakpoint.Type.NodeRemoved); InspectorTest.addResult("Set NodeRemoved DOM breakpoint."); node.removeNode(next); } @@ -30,7 +28,7 @@ function step2(node) { - pane._setBreakpoint(node, Components.DOMBreakpointsSidebarPane.BreakpointTypes.AttributeModified, true); + InspectorTest.domDebuggerModel.setDOMBreakpoint(node, SDK.DOMDebuggerModel.DOMBreakpoint.Type.AttributeModified); InspectorTest.addResult("Set AttributeModified DOM breakpoint."); node.setAttribute("title", "a title", next); }
diff --git a/third_party/WebKit/LayoutTests/inspector/sources/debugger-breakpoints/dom-breakpoints.html b/third_party/WebKit/LayoutTests/inspector/sources/debugger-breakpoints/dom-breakpoints.html index d814606..f305054 100644 --- a/third_party/WebKit/LayoutTests/inspector/sources/debugger-breakpoints/dom-breakpoints.html +++ b/third_party/WebKit/LayoutTests/inspector/sources/debugger-breakpoints/dom-breakpoints.html
@@ -82,7 +82,7 @@ function test() { - var pane = Components.domBreakpointsSidebarPane; + var pane = self.runtime.sharedInstance(Components.DOMBreakpointsSidebarPane); var rootElement; var outerElement; var authorShadowRoot; @@ -95,7 +95,7 @@ function step2(node) { rootElement = node; - pane._setBreakpoint(node, Components.DOMBreakpointsSidebarPane.BreakpointTypes.SubtreeModified, true); + InspectorTest.domDebuggerModel.setDOMBreakpoint(node, SDK.DOMDebuggerModel.DOMBreakpoint.Type.SubtreeModified); InspectorTest.addResult("Set 'Subtree Modified' DOM breakpoint on rootElement."); InspectorTest.evaluateInPageWithTimeout("appendElement('rootElement', 'childElement')"); InspectorTest.addResult("Append childElement to rootElement."); @@ -106,11 +106,9 @@ function testBreakpointToggle(next) { InspectorTest.addResult("Test that DOM breakpoint toggles properly using checkbox."); - Components.domBreakpointsSidebarPane._setBreakpoint(rootElement, Components.DOMBreakpointsSidebarPane.BreakpointTypes.AttributeModified, true); + var breakpoint = InspectorTest.domDebuggerModel.setDOMBreakpoint(rootElement, SDK.DOMDebuggerModel.DOMBreakpoint.Type.AttributeModified); InspectorTest.addResult("Set DOM breakpoint."); - var elementId = pane._createBreakpointId(rootElement.id, Components.DOMBreakpointsSidebarPane.BreakpointTypes.AttributeModified); - var element = pane._breakpointElements.get(elementId); - element._checkboxElement.click(); + pane._items.get(breakpoint).checkbox.click(); InspectorTest.addResult("Uncheck DOM breakpoint."); InspectorTest.evaluateInPagePromise("modifyAttribute('rootElement', 'data-test-breakpoint-toggle', 'foo')").then(step2); InspectorTest.addResult("DOM breakpoint should not be hit when disabled."); @@ -118,7 +116,7 @@ function step2() { InspectorTest.addResult("Check DOM breakpoint."); - element._checkboxElement.click(); + pane._items.get(breakpoint).checkbox.click(); InspectorTest.evaluateInPageWithTimeout("modifyAttribute('rootElement', 'data-test-breakpoint-toggle', 'bar')"); InspectorTest.addResult("Test that DOM breakpoint is hit when re-enabled."); InspectorTest.waitUntilPausedAndDumpStackAndResume(next); @@ -158,7 +156,7 @@ function step3(frames) { InspectorTest.captureStackTrace(frames); - pane._removeBreakpoint(rootElement, Components.DOMBreakpointsSidebarPane.BreakpointTypes.SubtreeModified); + InspectorTest.domDebuggerModel.removeDOMBreakpoint(rootElement, SDK.DOMDebuggerModel.DOMBreakpoint.Type.SubtreeModified); InspectorTest.resumeExecution(next); } }, @@ -166,7 +164,7 @@ function testModifyAttribute(next) { InspectorTest.addResult("Test that 'Attribute Modified' breakpoint is hit when modifying attribute."); - pane._setBreakpoint(rootElement, Components.DOMBreakpointsSidebarPane.BreakpointTypes.AttributeModified, true); + InspectorTest.domDebuggerModel.setDOMBreakpoint(rootElement, SDK.DOMDebuggerModel.DOMBreakpoint.Type.AttributeModified); InspectorTest.addResult("Set 'Attribute Modified' DOM breakpoint on rootElement."); InspectorTest.evaluateInPageWithTimeout("modifyAttribute('rootElement', 'data-test', 'foo')"); InspectorTest.addResult("Modify rootElement data-test attribute."); @@ -174,7 +172,7 @@ function step2(callFrames) { - pane._removeBreakpoint(rootElement, Components.DOMBreakpointsSidebarPane.BreakpointTypes.AttributeModified); + InspectorTest.domDebuggerModel.removeDOMBreakpoint(rootElement, SDK.DOMDebuggerModel.DOMBreakpoint.Type.AttributeModified); next(); } }, @@ -182,7 +180,7 @@ function testModifyAttrNode(next) { InspectorTest.addResult("Test that 'Attribute Modified' breakpoint is hit when modifying Attr node."); - pane._setBreakpoint(rootElement, Components.DOMBreakpointsSidebarPane.BreakpointTypes.AttributeModified, true); + InspectorTest.domDebuggerModel.setDOMBreakpoint(rootElement, SDK.DOMDebuggerModel.DOMBreakpoint.Type.AttributeModified); InspectorTest.addResult("Set 'Attribute Modified' DOM breakpoint on rootElement."); InspectorTest.evaluateInPageWithTimeout("modifyAttrNode('rootElement', 'data-test', 'bar')"); InspectorTest.addResult("Modify rootElement data-test attribute."); @@ -190,7 +188,7 @@ function step2(callFrames) { - pane._removeBreakpoint(rootElement, Components.DOMBreakpointsSidebarPane.BreakpointTypes.AttributeModified); + InspectorTest.domDebuggerModel.removeDOMBreakpoint(rootElement, SDK.DOMDebuggerModel.DOMBreakpoint.Type.AttributeModified); next(); } }, @@ -198,7 +196,7 @@ function testSetAttrNode(next) { InspectorTest.addResult("Test that 'Attribute Modified' breakpoint is hit when adding a new Attr node."); - pane._setBreakpoint(rootElement, Components.DOMBreakpointsSidebarPane.BreakpointTypes.AttributeModified, true); + InspectorTest.domDebuggerModel.setDOMBreakpoint(rootElement, SDK.DOMDebuggerModel.DOMBreakpoint.Type.AttributeModified); InspectorTest.addResult("Set 'Attribute Modified' DOM breakpoint on rootElement."); InspectorTest.evaluateInPageWithTimeout("setAttrNode('rootElement', 'data-foo', 'bar')"); InspectorTest.addResult("Modify rootElement data-foo attribute."); @@ -206,7 +204,7 @@ function step2(callFrames) { - pane._removeBreakpoint(rootElement, Components.DOMBreakpointsSidebarPane.BreakpointTypes.AttributeModified); + InspectorTest.domDebuggerModel.removeDOMBreakpoint(rootElement, SDK.DOMDebuggerModel.DOMBreakpoint.Type.AttributeModified); next(); } }, @@ -214,7 +212,7 @@ function testModifyStyleAttribute(next) { InspectorTest.addResult("Test that 'Attribute Modified' breakpoint is hit when modifying style attribute."); - pane._setBreakpoint(rootElement, Components.DOMBreakpointsSidebarPane.BreakpointTypes.AttributeModified, true); + InspectorTest.domDebuggerModel.setDOMBreakpoint(rootElement, SDK.DOMDebuggerModel.DOMBreakpoint.Type.AttributeModified); InspectorTest.addResult("Set 'Attribute Modified' DOM breakpoint on rootElement."); InspectorTest.evaluateInPageWithTimeout("modifyStyleAttribute('rootElement', 'color', 'green')"); InspectorTest.addResult("Modify rootElement style.color attribute."); @@ -222,7 +220,7 @@ function step2(callFrames) { - pane._removeBreakpoint(rootElement, Components.DOMBreakpointsSidebarPane.BreakpointTypes.AttributeModified); + InspectorTest.domDebuggerModel.removeDOMBreakpoint(rootElement, SDK.DOMDebuggerModel.DOMBreakpoint.Type.AttributeModified); next(); } }, @@ -234,7 +232,7 @@ function step2(node) { - pane._setBreakpoint(node, Components.DOMBreakpointsSidebarPane.BreakpointTypes.NodeRemoved, true); + InspectorTest.domDebuggerModel.setDOMBreakpoint(node, SDK.DOMDebuggerModel.DOMBreakpoint.Type.NodeRemoved); InspectorTest.addResult("Set 'Node Removed' DOM breakpoint on elementToRemove."); InspectorTest.evaluateInPageWithTimeout("removeElement('elementToRemove')"); InspectorTest.addResult("Remove elementToRemove."); @@ -249,8 +247,7 @@ function step2(node) { - pane._setBreakpoint(node, Components.DOMBreakpointsSidebarPane.BreakpointTypes.SubtreeModified, true); - pane._saveBreakpoints(); + InspectorTest.domDebuggerModel.setDOMBreakpoint(node, SDK.DOMDebuggerModel.DOMBreakpoint.Type.SubtreeModified); InspectorTest.addResult("Set 'Subtree Modified' DOM breakpoint on rootElement."); InspectorTest.reloadPage(step3); } @@ -276,7 +273,7 @@ { authorShadowRoot = node; InspectorTest.addResult("Test that 'Subtree Modified' breakpoint on author shadow root is hit when appending a child."); - pane._setBreakpoint(authorShadowRoot, Components.DOMBreakpointsSidebarPane.BreakpointTypes.SubtreeModified, true); + InspectorTest.domDebuggerModel.setDOMBreakpoint(authorShadowRoot, SDK.DOMDebuggerModel.DOMBreakpoint.Type.SubtreeModified); InspectorTest.addResult("Set 'Subtree Modified' DOM breakpoint on author shadow root."); InspectorTest.evaluateInPageWithTimeout("appendElementToOpenShadowRoot('childElement')"); InspectorTest.addResult("Append childElement to author shadow root."); @@ -293,8 +290,7 @@ outerElement = node; InspectorTest.addResult("Test that shadow DOM breakpoints are persisted between page reloads."); - pane._setBreakpoint(outerElement, Components.DOMBreakpointsSidebarPane.BreakpointTypes.SubtreeModified, true); - pane._saveBreakpoints(); + InspectorTest.domDebuggerModel.setDOMBreakpoint(outerElement, SDK.DOMDebuggerModel.DOMBreakpoint.Type.SubtreeModified); InspectorTest.addResult("Set 'Subtree Modified' DOM breakpoint on outerElement."); InspectorTest.reloadPage(step2); }
diff --git a/third_party/WebKit/LayoutTests/inspector/sources/debugger-pause/skip-pauses-until-reload.html b/third_party/WebKit/LayoutTests/inspector/sources/debugger-pause/skip-pauses-until-reload.html index 280db8d1..b9fda69 100644 --- a/third_party/WebKit/LayoutTests/inspector/sources/debugger-pause/skip-pauses-until-reload.html +++ b/third_party/WebKit/LayoutTests/inspector/sources/debugger-pause/skip-pauses-until-reload.html
@@ -71,11 +71,10 @@ function didResolveNode(node) { testRunner.logToStderr("didResolveNode"); - var pane = Components.domBreakpointsSidebarPane; InspectorTest.addResult("Set up DOM breakpoints."); - pane._setBreakpoint(node, Components.DOMBreakpointsSidebarPane.BreakpointTypes.SubtreeModified, true); - pane._setBreakpoint(node, Components.DOMBreakpointsSidebarPane.BreakpointTypes.AttributeModified, true); - pane._setBreakpoint(node, Components.DOMBreakpointsSidebarPane.BreakpointTypes.NodeRemoved, true); + InspectorTest.domDebuggerModel.setDOMBreakpoint(node, SDK.DOMDebuggerModel.DOMBreakpoint.Type.SubtreeModified); + InspectorTest.domDebuggerModel.setDOMBreakpoint(node, SDK.DOMDebuggerModel.DOMBreakpoint.Type.AttributeModified); + InspectorTest.domDebuggerModel.setDOMBreakpoint(node, SDK.DOMDebuggerModel.DOMBreakpoint.Type.NodeRemoved); setUpEventBreakpoints(); }
diff --git a/third_party/WebKit/LayoutTests/media/encrypted-media/encrypted-media-session-remove-temporary.html b/third_party/WebKit/LayoutTests/media/encrypted-media/encrypted-media-session-remove-temporary.html new file mode 100644 index 0000000..3ea6e78 --- /dev/null +++ b/third_party/WebKit/LayoutTests/media/encrypted-media/encrypted-media-session-remove-temporary.html
@@ -0,0 +1,57 @@ +<!DOCTYPE html> +<html> + <head> + <title>Test MediaKeySession remove() function on temporary sessions</title> + <script src="encrypted-media-utils.js"></script> + <script src="../../resources/testharness.js"></script> + <script src="../../resources/testharnessreport.js"></script> + </head> + <body> + <script> + promise_test(function(test) + { + var keyId = stringToUint8Array('0123456789012345'); + var rawKey = new Uint8Array([0xeb, 0xdd, 0x62, 0xf1, 0x68, 0x14, 0xd2, 0x7b, + 0x68, 0xef, 0x12, 0x2a, 0xfc, 0xe4, 0xae, 0x3c]); + + var mediaKeySession; + var waitForMessagePromise; + + return navigator.requestMediaKeySystemAccess('org.w3.clearkey', getSimpleConfigurationForInitDataType('keyids')).then(function(access) { + return access.createMediaKeys(); + }).then(function(mediaKeys) { + mediaKeySession = mediaKeys.createSession(); + waitForMessagePromise = waitForSingleEvent(mediaKeySession, 'message', function(e, resolve, reject) { + resolve(); + }); + const request = stringToUint8Array(createKeyIDs(keyId)); + return mediaKeySession.generateRequest('keyids', request); + }).then(function() { + return waitForMessagePromise; + }).then(function() { + const jwkSet = stringToUint8Array(createJWKSet(createJWK(keyId, rawKey))); + return mediaKeySession.update(jwkSet); + }).then(function() { + // After update() the session should have 1 usable key. + verifyKeyStatuses(mediaKeySession.keyStatuses, + { expected: [keyId], unexpected: [] }, 'usable'); + return mediaKeySession.remove(); + }).then(function() { + // After remove() all keys should be 'released'. + verifyKeyStatuses(mediaKeySession.keyStatuses, + { expected: [keyId], unexpected: [] }, 'released'); + // After remove() the session expiry should be NaN. + // ClearKey doesn't change set expiry times, but check + // anyway. + assert_true(isNaN(mediaKeySession.expiration)); + return mediaKeySession.close(); + }).then(function() { + // After close() there should be no keys. + verifyKeyStatuses(mediaKeySession.keyStatuses, + { expected: [], unexpected: [keyId] }); + }); + + }, 'Test MediaKeySession remove() function on temporary sessions'); + </script> + </body> +</html>
diff --git a/third_party/WebKit/LayoutTests/media/encrypted-media/encrypted-media-syntax.html b/third_party/WebKit/LayoutTests/media/encrypted-media/encrypted-media-syntax.html index dbf6fe4..d8b06418 100644 --- a/third_party/WebKit/LayoutTests/media/encrypted-media/encrypted-media-syntax.html +++ b/third_party/WebKit/LayoutTests/media/encrypted-media/encrypted-media-syntax.html
@@ -814,15 +814,6 @@ assert_unreached('remove() should not succeed if session uninitialized'); }, function(error) { assert_equals(error.name, 'InvalidStateError'); - - // remove() on a temporary session should fail. - return mediaKeySession.generateRequest(type, initData); - }).then(function(result) { - return mediaKeySession.remove(); - }).then(function(result) { - assert_unreached('remove() should not succeed for temporary sessions'); - }, function(error) { - assert_equals(error.name, 'TypeError'); }); } @@ -861,17 +852,26 @@ function create_remove_test(mediaKeys, type, initData) { - // Clear Key may not support persistent-license sessions. - var mediaKeySession; - try { - mediaKeySession = mediaKeys.createSession('persistent-license'); - } catch (error) { - // Not supported, so return a resolved promise. - assert_equals(error.name, 'NotSupportedError'); - return Promise.resolve(); - } - return mediaKeySession.generateRequest(type, initData).then(function(result) { + var mediaKeySession = mediaKeys.createSession(); + var promise = mediaKeySession.generateRequest(type, initData).then(function(result) { return mediaKeySession.remove(); + }).then(function() { + // remove() doesn't close the session, so must call close(). + return mediaKeySession.close(); + }).then(function() { + try { + // Clear Key may not support persistent-license sessions. + mediaKeySession = mediaKeys.createSession('persistent-license'); + return mediaKeySession.generateRequest(type, initData).then(function(result) { + return mediaKeySession.remove(); + }).then(function() { + return mediaKeySession.close(); + }); + } catch (error) { + // Not supported, so return a resolved promise. + assert_equals(error.name, 'NotSupportedError'); + return Promise.resolve(); + } }); }
diff --git a/third_party/WebKit/LayoutTests/media/encrypted-media/encrypted-media-utils.js b/third_party/WebKit/LayoutTests/media/encrypted-media/encrypted-media-utils.js index 7da4129..38d1c99 100644 --- a/third_party/WebKit/LayoutTests/media/encrypted-media/encrypted-media-utils.js +++ b/third_party/WebKit/LayoutTests/media/encrypted-media/encrypted-media-utils.js
@@ -182,28 +182,28 @@ } // Verify that |keyStatuses| contains just the keys in |keys.expected| -// and none of the keys in |keys.unexpected|. All keys should have status -// 'usable'. Example call: verifyKeyStatuses(mediaKeySession.keyStatuses, -// { expected: [key1], unexpected: [key2] }); -function verifyKeyStatuses(keyStatuses, keys) -{ - var expected = keys.expected || []; - var unexpected = keys.unexpected || []; +// and none of the keys in |keys.unexpected|. All expected keys should have +// status |status|. Example call: verifyKeyStatuses(mediaKeySession.keyStatuses, +// { expected: [key1], unexpected: [key2] }, 'usable'); +function verifyKeyStatuses(keyStatuses, keys, status) { + var expected = keys.expected || []; + var unexpected = keys.unexpected || []; + status = status || 'usable'; - // |keyStatuses| should have same size as number of |keys.expected|. - assert_equals(keyStatuses.size, expected.length); + // |keyStatuses| should have same size as number of |keys.expected|. + assert_equals(keyStatuses.size, expected.length); - // All |keys.expected| should be found. - expected.map(function(key) { - assert_true(keyStatuses.has(key)); - assert_equals(keyStatuses.get(key), 'usable'); - }); + // All |keys.expected| should be found. + expected.map(function(key) { + assert_true(keyStatuses.has(key)); + assert_equals(keyStatuses.get(key), status); + }); - // All |keys.unexpected| should not be found. - unexpected.map(function(key) { - assert_false(keyStatuses.has(key)); - assert_equals(keyStatuses.get(key), undefined); - }); + // All |keys.unexpected| should not be found. + unexpected.map(function(key) { + assert_false(keyStatuses.has(key)); + assert_equals(keyStatuses.get(key), undefined); + }); } // Encodes |data| into base64url string. There is no '=' padding, and the @@ -314,6 +314,18 @@ }); } +// Convert an event into a promise. When |event| is fired on |object|, +// call |func| to handle the event and either resolve or reject the promise. +// The event is only fired once. +function waitForSingleEvent(object, event, func) { + return new Promise(function(resolve, reject) { + object.addEventListener(event, function listener(e) { + object.removeEventListener(event, listener); + func(e, resolve, reject); + }); + }); +}; + // Play the specified |content| on |video|. Returns a promise that is resolved // after the video plays for |duration| seconds. function playVideoAndWaitForTimeupdate(video, content, duration)
diff --git a/third_party/WebKit/LayoutTests/storage/indexeddb/shared-array-buffer-throws.html b/third_party/WebKit/LayoutTests/storage/indexeddb/shared-array-buffer-throws.html new file mode 100644 index 0000000..07a60c8 --- /dev/null +++ b/third_party/WebKit/LayoutTests/storage/indexeddb/shared-array-buffer-throws.html
@@ -0,0 +1,28 @@ +<!DOCTYPE html> +<title>IndexedDB: Attempting to serialize a SharedArrayBuffer should throw</title> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> +<script src="resources/testharness-helpers.js"></script> +<script> + +if (window.SharedArrayBuffer) { + indexeddb_test( + (t, db) => { + db.createObjectStore('store'); + }, + (t, db) => { + const sab = new SharedArrayBuffer(256); + const tx = db.transaction('store', 'readwrite'); + const store = tx.objectStore('store'); + + assert_throws("DataCloneError", () => { + store.put({sab: sab}, 'key'); + }); + t.done(); + }, + 'Serializing SharedArrayBuffer throws DataClone error.'); +} else { + done(); +} + +</script>
diff --git a/third_party/WebKit/LayoutTests/virtual/sharedarraybuffer/storage/indexeddb/README.txt b/third_party/WebKit/LayoutTests/virtual/sharedarraybuffer/storage/indexeddb/README.txt new file mode 100644 index 0000000..51001f0f --- /dev/null +++ b/third_party/WebKit/LayoutTests/virtual/sharedarraybuffer/storage/indexeddb/README.txt
@@ -0,0 +1,3 @@ +# This suite runs the tests in with --js-flags=--harmony-sharedarraybuffer +# This enables the SharedArrayBuffer language feature in V8. +# See https://github.com/tc39/ecmascript_sharedmem for more information.
diff --git a/third_party/WebKit/Source/bindings/core/v8/ScriptModuleTest.cpp b/third_party/WebKit/Source/bindings/core/v8/ScriptModuleTest.cpp index 183efbb9..c85ee63 100644 --- a/third_party/WebKit/Source/bindings/core/v8/ScriptModuleTest.cpp +++ b/third_party/WebKit/Source/bindings/core/v8/ScriptModuleTest.cpp
@@ -4,9 +4,13 @@ #include "bindings/core/v8/ScriptModule.h" +#include "bindings/core/v8/ScriptController.h" +#include "bindings/core/v8/ScriptSourceCode.h" +#include "bindings/core/v8/V8Binding.h" #include "bindings/core/v8/V8BindingForTesting.h" #include "bindings/core/v8/V8PerContextData.h" #include "core/dom/ScriptModuleResolver.h" +#include "core/frame/LocalFrame.h" #include "core/testing/DummyModulator.h" #include "testing/gmock/include/gmock/gmock-matchers.h" #include "testing/gtest/include/gtest/gtest.h" @@ -194,6 +198,28 @@ EXPECT_EQ("b", resolver->Specifiers()[1]); } +TEST(ScriptModuleTest, Evaluate) { + V8TestingScope scope; + + auto modulator = new ScriptModuleTestModulator(); + Modulator::SetModulator(scope.GetScriptState(), modulator); + + ScriptModule module = ScriptModule::Compile( + scope.GetIsolate(), "export const a = 42; window.foo = 'bar';", "foo.js", + kSharableCrossOrigin); + ASSERT_FALSE(module.IsNull()); + ScriptValue exception = module.Instantiate(scope.GetScriptState()); + ASSERT_TRUE(exception.IsEmpty()); + + module.Evaluate(scope.GetScriptState()); + v8::Local<v8::Value> value = scope.GetFrame() + .GetScriptController() + .ExecuteScriptInMainWorldAndReturnValue( + ScriptSourceCode("window.foo")); + ASSERT_TRUE(value->IsString()); + EXPECT_EQ("bar", ToCoreString(v8::Local<v8::String>::Cast(value))); +} + } // namespace } // namespace blink
diff --git a/third_party/WebKit/Source/bindings/core/v8/ScriptWrappable.h b/third_party/WebKit/Source/bindings/core/v8/ScriptWrappable.h index 420ce172c..3989ab33 100644 --- a/third_party/WebKit/Source/bindings/core/v8/ScriptWrappable.h +++ b/third_party/WebKit/Source/bindings/core/v8/ScriptWrappable.h
@@ -126,7 +126,7 @@ wrapper_type_info->ConfigureWrapper(&main_world_wrapper_); main_world_wrapper_.SetWeak(); DCHECK(ContainsWrapper()); - ScriptWrappableVisitor::WriteBarrier(&main_world_wrapper_); + ScriptWrappableVisitor::WriteBarrier(isolate, &main_world_wrapper_); return true; }
diff --git a/third_party/WebKit/Source/bindings/core/v8/ScriptWrappableVisitor.cpp b/third_party/WebKit/Source/bindings/core/v8/ScriptWrappableVisitor.cpp index a959390..eac79f1 100644 --- a/third_party/WebKit/Source/bindings/core/v8/ScriptWrappableVisitor.cpp +++ b/third_party/WebKit/Source/bindings/core/v8/ScriptWrappableVisitor.cpp
@@ -224,6 +224,7 @@ } void ScriptWrappableVisitor::WriteBarrier( + v8::Isolate* isolate, const void* src_object, const TraceWrapperV8Reference<v8::Value>* dst_object) { if (!src_object || !dst_object || dst_object->IsEmpty()) { @@ -235,18 +236,17 @@ if (!HeapObjectHeader::FromPayload(src_object)->IsWrapperHeaderMarked()) { return; } - CurrentVisitor(ThreadState::Current()->GetIsolate()) - ->MarkWrapper(&( - const_cast<TraceWrapperV8Reference<v8::Value>*>(dst_object)->Get())); + CurrentVisitor(isolate)->MarkWrapper( + &(const_cast<TraceWrapperV8Reference<v8::Value>*>(dst_object)->Get())); } void ScriptWrappableVisitor::WriteBarrier( + v8::Isolate* isolate, const v8::Persistent<v8::Object>* dst_object) { if (!dst_object || dst_object->IsEmpty()) { return; } - CurrentVisitor(ThreadState::Current()->GetIsolate()) - ->MarkWrapper(&(dst_object->As<v8::Value>())); + CurrentVisitor(isolate)->MarkWrapper(&(dst_object->As<v8::Value>())); } void ScriptWrappableVisitor::TraceWrappers(
diff --git a/third_party/WebKit/Source/bindings/core/v8/ScriptWrappableVisitor.h b/third_party/WebKit/Source/bindings/core/v8/ScriptWrappableVisitor.h index 699aea3..50eee7f 100644 --- a/third_party/WebKit/Source/bindings/core/v8/ScriptWrappableVisitor.h +++ b/third_party/WebKit/Source/bindings/core/v8/ScriptWrappableVisitor.h
@@ -97,15 +97,16 @@ static WrapperVisitor* CurrentVisitor(v8::Isolate*); - static void WriteBarrier(const void*, + static void WriteBarrier(v8::Isolate*, + const void*, const TraceWrapperV8Reference<v8::Value>*); // TODO(mlippautz): Remove once ScriptWrappable is converted to // TraceWrapperV8Reference. - static void WriteBarrier(const v8::Persistent<v8::Object>*); + static void WriteBarrier(v8::Isolate*, const v8::Persistent<v8::Object>*); template <typename T> - static void WriteBarrier(const void* object, const Member<T> value) { + static void WriteBarrier(const void* object, const Member<T>& value) { WriteBarrier(object, value.Get()); }
diff --git a/third_party/WebKit/Source/bindings/core/v8/SerializedScriptValue.h b/third_party/WebKit/Source/bindings/core/v8/SerializedScriptValue.h index 15d211c9..9ee5682 100644 --- a/third_party/WebKit/Source/bindings/core/v8/SerializedScriptValue.h +++ b/third_party/WebKit/Source/bindings/core/v8/SerializedScriptValue.h
@@ -87,6 +87,9 @@ Transferables* transferables = nullptr; WebBlobInfoArray* blob_info = nullptr; bool write_wasm_to_stream = false; + // Set when serializing a value for storage; e.g. when writing to + // IndexedDB. + bool for_storage = false; }; static PassRefPtr<SerializedScriptValue> Serialize(v8::Isolate*, v8::Local<v8::Value>,
diff --git a/third_party/WebKit/Source/bindings/core/v8/TraceWrapperV8Reference.h b/third_party/WebKit/Source/bindings/core/v8/TraceWrapperV8Reference.h index 7305f9a..85a1882 100644 --- a/third_party/WebKit/Source/bindings/core/v8/TraceWrapperV8Reference.h +++ b/third_party/WebKit/Source/bindings/core/v8/TraceWrapperV8Reference.h
@@ -63,7 +63,7 @@ private: inline void InternalSet(v8::Isolate* isolate, v8::Local<T> handle) { handle_.Reset(isolate, handle); - ScriptWrappableVisitor::WriteBarrier(parent_, &Cast<v8::Value>()); + ScriptWrappableVisitor::WriteBarrier(isolate, parent_, &Cast<v8::Value>()); } v8::Persistent<T> handle_;
diff --git a/third_party/WebKit/Source/bindings/core/v8/serialization/V8ScriptValueSerializer.cpp b/third_party/WebKit/Source/bindings/core/v8/serialization/V8ScriptValueSerializer.cpp index bc0cf537..dee9be5 100644 --- a/third_party/WebKit/Source/bindings/core/v8/serialization/V8ScriptValueSerializer.cpp +++ b/third_party/WebKit/Source/bindings/core/v8/serialization/V8ScriptValueSerializer.cpp
@@ -51,7 +51,8 @@ serializer_(script_state_->GetIsolate(), this), transferables_(options.transferables), blob_info_array_(options.blob_info), - inline_wasm_(options.write_wasm_to_stream) {} + inline_wasm_(options.write_wasm_to_stream), + for_storage_(options.for_storage) {} RefPtr<SerializedScriptValue> V8ScriptValueSerializer::Serialize( v8::Local<v8::Value> value, @@ -117,32 +118,37 @@ void V8ScriptValueSerializer::FinalizeTransfer( ExceptionState& exception_state) { - if (!transferables_ && shared_array_buffers_.IsEmpty()) - return; - // TODO(jbroman): Strictly speaking, this is not correct; transfer should // occur in the order of the transfer list. // https://html.spec.whatwg.org/multipage/infrastructure.html#structuredclonewithtransfer + v8::Isolate* isolate = script_state_->GetIsolate(); + + // The order of ArrayBuffers and SharedArrayBuffers matters; we use the index + // into this array for deserialization. ArrayBufferArray array_buffers; - array_buffers.AppendVector(transferables_->array_buffers); + if (transferables_) + array_buffers.AppendVector(transferables_->array_buffers); array_buffers.AppendVector(shared_array_buffers_); - v8::Isolate* isolate = script_state_->GetIsolate(); - serialized_script_value_->TransferArrayBuffers(isolate, array_buffers, - exception_state); - if (exception_state.HadException()) - return; + if (!array_buffers.IsEmpty()) { + serialized_script_value_->TransferArrayBuffers(isolate, array_buffers, + exception_state); + if (exception_state.HadException()) + return; + } - serialized_script_value_->TransferImageBitmaps( - isolate, transferables_->image_bitmaps, exception_state); - if (exception_state.HadException()) - return; + if (transferables_) { + serialized_script_value_->TransferImageBitmaps( + isolate, transferables_->image_bitmaps, exception_state); + if (exception_state.HadException()) + return; - serialized_script_value_->TransferOffscreenCanvas( - isolate, transferables_->offscreen_canvases, exception_state); - if (exception_state.HadException()) - return; + serialized_script_value_->TransferOffscreenCanvas( + isolate, transferables_->offscreen_canvases, exception_state); + if (exception_state.HadException()) + return; + } } void V8ScriptValueSerializer::WriteUTF8String(const String& string) { @@ -399,6 +405,18 @@ v8::Maybe<uint32_t> V8ScriptValueSerializer::GetSharedArrayBufferId( v8::Isolate* isolate, v8::Local<v8::SharedArrayBuffer> v8_shared_array_buffer) { + if (for_storage_) { + DCHECK(exception_state_); + DCHECK_EQ(isolate, script_state_->GetIsolate()); + ExceptionState exception_state(isolate, exception_state_->Context(), + exception_state_->InterfaceName(), + exception_state_->PropertyName()); + exception_state.ThrowDOMException( + kDataCloneError, + "A SharedArrayBuffer can not be serialized for storage."); + return v8::Nothing<uint32_t>(); + } + DOMSharedArrayBuffer* shared_array_buffer = V8SharedArrayBuffer::toImpl(v8_shared_array_buffer);
diff --git a/third_party/WebKit/Source/bindings/core/v8/serialization/V8ScriptValueSerializer.h b/third_party/WebKit/Source/bindings/core/v8/serialization/V8ScriptValueSerializer.h index d01afa95..8606080 100644 --- a/third_party/WebKit/Source/bindings/core/v8/serialization/V8ScriptValueSerializer.h +++ b/third_party/WebKit/Source/bindings/core/v8/serialization/V8ScriptValueSerializer.h
@@ -99,6 +99,7 @@ WebBlobInfoArray* blob_info_array_ = nullptr; ArrayBufferArray shared_array_buffers_; bool inline_wasm_ = false; + bool for_storage_ = false; #if DCHECK_IS_ON() bool serialize_invoked_ = false; #endif
diff --git a/third_party/WebKit/Source/core/BUILD.gn b/third_party/WebKit/Source/core/BUILD.gn index 8997ff4..a6cfbfd 100644 --- a/third_party/WebKit/Source/core/BUILD.gn +++ b/third_party/WebKit/Source/core/BUILD.gn
@@ -1326,9 +1326,9 @@ "layout/ng/geometry/ng_box_strut_test.cc", "layout/ng/geometry/ng_logical_offset_test.cc", "layout/ng/geometry/ng_physical_rect_test.cc", + "layout/ng/inline/ng_inline_items_builder_test.cc", "layout/ng/inline/ng_inline_layout_algorithm_test.cc", "layout/ng/inline/ng_inline_node_test.cc", - "layout/ng/inline/ng_layout_inline_items_builder_test.cc", "layout/ng/ng_absolute_utils_test.cc", "layout/ng/ng_base_layout_algorithm_test.cc", "layout/ng/ng_base_layout_algorithm_test.h",
diff --git a/third_party/WebKit/Source/core/dom/PendingScript.cpp b/third_party/WebKit/Source/core/dom/PendingScript.cpp index cb907e2..c7ebdcd 100644 --- a/third_party/WebKit/Source/core/dom/PendingScript.cpp +++ b/third_party/WebKit/Source/core/dom/PendingScript.cpp
@@ -32,8 +32,7 @@ PendingScript::PendingScript(ScriptElementBase* element, const TextPosition& starting_position) - : watching_for_load_(false), - element_(element), + : element_(element), starting_position_(starting_position), parser_blocking_load_start_time_(0), client_(nullptr) {} @@ -56,12 +55,12 @@ CheckState(); DCHECK(!IsWatchingForLoad()); + DCHECK(client); // addClient() will call streamingFinished() if the load is complete. Callers // who do not expect to be re-entered from this call should not call // watchForLoad for a PendingScript which isReady. We also need to set // m_watchingForLoad early, since addClient() can result in calling // notifyFinished and further stopWatchingForLoad(). - watching_for_load_ = true; client_ = client; if (IsReady()) client_->PendingScriptFinished(this); @@ -73,7 +72,6 @@ CheckState(); DCHECK(IsExternal()); client_ = nullptr; - watching_for_load_ = false; } ScriptElementBase* PendingScript::GetElement() const {
diff --git a/third_party/WebKit/Source/core/dom/PendingScript.h b/third_party/WebKit/Source/core/dom/PendingScript.h index 6886b9bb..1888204 100644 --- a/third_party/WebKit/Source/core/dom/PendingScript.h +++ b/third_party/WebKit/Source/core/dom/PendingScript.h
@@ -106,13 +106,11 @@ virtual void DisposeInternal() = 0; PendingScriptClient* Client() { return client_; } - bool IsWatchingForLoad() const { return watching_for_load_; } + bool IsWatchingForLoad() const { return client_; } virtual void CheckState() const = 0; private: - bool watching_for_load_; - // |m_element| must points to the corresponding ScriptLoader's // ScriptElementBase and thus must be non-null before dispose() is called // (except for unit tests).
diff --git a/third_party/WebKit/Source/core/html/BUILD.gn b/third_party/WebKit/Source/core/html/BUILD.gn index afa717b3..bbab99ae 100644 --- a/third_party/WebKit/Source/core/html/BUILD.gn +++ b/third_party/WebKit/Source/core/html/BUILD.gn
@@ -267,6 +267,8 @@ "canvas/CanvasRenderingContext.cpp", "canvas/CanvasRenderingContext.h", "canvas/CanvasRenderingContextFactory.h", + "canvas/CanvasRenderingContextHost.cpp", + "canvas/CanvasRenderingContextHost.h", "canvas/ImageElementBase.cpp", "canvas/ImageElementBase.h", "forms/BaseButtonInputType.cpp",
diff --git a/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp b/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp index 025f81f..03686dab 100644 --- a/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp +++ b/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp
@@ -161,7 +161,7 @@ ReleasePlaceholderFrame(); if (context_) { - context_->DetachCanvas(); + context_->DetachHost(); context_ = nullptr; } @@ -201,7 +201,7 @@ } void HTMLCanvasElement::SetSize(const IntSize& new_size) { - if (new_size == size()) + if (new_size == Size()) return; ignore_reset_ = true; SetIntegralAttribute(widthAttr, new_size.Width()); @@ -301,7 +301,7 @@ bool HTMLCanvasElement::IsPaintable() const { return (context_ && context_->IsPaintable()) || - ImageBuffer::CanCreateImageBuffer(size()); + ImageBuffer::CanCreateImageBuffer(Size()); } bool HTMLCanvasElement::IsAccelerated() const { @@ -328,7 +328,7 @@ } void HTMLCanvasElement::DidDraw() { - DidDraw(FloatRect(0, 0, size().Width(), size().Height())); + DidDraw(FloatRect(0, 0, Size().Width(), Size().Height())); } void HTMLCanvasElement::FinalizeFrame() { @@ -367,7 +367,7 @@ void HTMLCanvasElement::DoDeferredPaintInvalidation() { DCHECK(!dirty_rect_.IsEmpty()); if (Is2d()) { - FloatRect src_rect(0, 0, size().Width(), size().Height()); + FloatRect src_rect(0, 0, Size().Width(), Size().Height()); dirty_rect_.Intersect(src_rect); LayoutBox* lb = GetLayoutBox(); FloatRect invalidation_rect; @@ -403,7 +403,7 @@ // Propagate the m_dirtyRect accumulated so far to the compositor // before restarting with a blank dirty rect. - FloatRect src_rect(0, 0, size().Width(), size().Height()); + FloatRect src_rect(0, 0, Size().Width(), Size().Height()); LayoutBox* ro = GetLayoutBox(); // Canvas content updates do not need to be propagated as @@ -482,7 +482,7 @@ if (Is2d()) context_->Reset(); - IntSize old_size = size(); + IntSize old_size = Size(); IntSize new_size(w, h); // If the size of an existing buffer matches, we can just clear it instead of @@ -498,12 +498,12 @@ SetSurfaceSize(new_size); - if (Is3d() && old_size != size()) + if (Is3d() && old_size != Size()) context_->Reshape(width(), height()); if (LayoutObject* layout_object = this->GetLayoutObject()) { if (layout_object->IsCanvas()) { - if (old_size != size()) { + if (old_size != Size()) { ToLayoutHTMLCanvas(layout_object)->CanvasSizeChanged(); if (GetLayoutBox() && GetLayoutBox()->HasAcceleratedCompositing()) GetLayoutBox()->ContentChanged(kCanvasChanged); @@ -812,10 +812,6 @@ listeners_.erase(listener); } -SecurityOrigin* HTMLCanvasElement::GetSecurityOrigin() const { - return GetDocument().GetSecurityOrigin(); -} - bool HTMLCanvasElement::OriginClean() const { if (GetDocument().GetSettings() && GetDocument().GetSettings()->GetDisableReadingFromCanvas()) @@ -841,8 +837,8 @@ if (GetLayoutBox() && !GetLayoutBox()->HasAcceleratedCompositing()) return false; - CheckedNumeric<int> checked_canvas_pixel_count = size().Width(); - checked_canvas_pixel_count *= size().Height(); + CheckedNumeric<int> checked_canvas_pixel_count = Size().Width(); + checked_canvas_pixel_count *= Size().Height(); if (!checked_canvas_pixel_count.IsValid()) return false; int canvas_pixel_count = checked_canvas_pixel_count.ValueOrDie(); @@ -911,7 +907,7 @@ // then make a non-accelerated ImageBuffer. This means copying the internal // Image will require a pixel readback, but that is unavoidable in this case. auto surface = WTF::MakeUnique<AcceleratedImageBufferSurface>( - size(), opacity_mode, context_->color_params()); + Size(), opacity_mode, context_->color_params()); if (surface->IsValid()) return std::move(surface); return nullptr; @@ -939,7 +935,7 @@ return nullptr; // Don't use accelerated canvas with swiftshader. auto surface = WTF::MakeUnique<Canvas2DImageBufferSurface>( - std::move(context_provider), size(), *msaa_sample_count, opacity_mode, + std::move(context_provider), Size(), *msaa_sample_count, opacity_mode, Canvas2DLayerBridge::kEnableAcceleration, context_->color_params()); if (!surface->IsValid()) { CanvasMetrics::CountCanvasContextUsage( @@ -957,7 +953,7 @@ OpacityMode opacity_mode) { if (ShouldUseDisplayList()) { auto surface = WTF::MakeUnique<RecordingImageBufferSurface>( - size(), opacity_mode, context_->color_params()); + Size(), opacity_mode, context_->color_params()); if (surface->IsValid()) { CanvasMetrics::CountCanvasContextUsage( CanvasMetrics::kDisplayList2DCanvasImageBufferCreated); @@ -968,7 +964,7 @@ } auto surface = WTF::MakeUnique<UnacceleratedImageBufferSurface>( - size(), opacity_mode, kInitializeImagePixels, context_->color_params()); + Size(), opacity_mode, kInitializeImagePixels, context_->color_params()); if (surface->IsValid()) { CanvasMetrics::CountCanvasContextUsage( CanvasMetrics::kUnaccelerated2DCanvasImageBufferCreated); @@ -982,7 +978,7 @@ void HTMLCanvasElement::CreateImageBuffer() { CreateImageBufferInternal(nullptr); - if (did_fail_to_create_image_buffer_ && Is2d() && !size().IsEmpty()) + if (did_fail_to_create_image_buffer_ && Is2d() && !Size().IsEmpty()) context_->LoseContext(CanvasRenderingContext::kSyntheticLostContext); } @@ -993,7 +989,7 @@ did_fail_to_create_image_buffer_ = true; image_buffer_is_clear_ = true; - if (!ImageBuffer::CanCreateImageBuffer(size())) + if (!ImageBuffer::CanCreateImageBuffer(Size())) return; OpacityMode opacity_mode = !context_ || context_->CreationAttributes().alpha() @@ -1138,7 +1134,7 @@ DiscardImageBuffer(); OpacityMode opacity_mode = context_->CreationAttributes().alpha() ? kNonOpaque : kOpaque; - image_buffer_ = ImageBuffer::Create(size(), opacity_mode); + image_buffer_ = ImageBuffer::Create(Size(), opacity_mode); did_fail_to_create_image_buffer_ = !image_buffer_; } @@ -1149,7 +1145,7 @@ if (!IsPaintable()) return nullptr; if (!context_) - return CreateTransparentImage(size()); + return CreateTransparentImage(Size()); if (context_->GetContextType() == CanvasRenderingContext::kContextImageBitmap) { @@ -1260,7 +1256,7 @@ } if (!context_) { - RefPtr<Image> result = CreateTransparentImage(size()); + RefPtr<Image> result = CreateTransparentImage(Size()); *status = result ? kNormalSourceImageStatus : kInvalidSourceImageStatus; return result; } @@ -1282,7 +1278,7 @@ if (HasImageBuffer()) { sk_image = Buffer()->NewSkImageSnapshot(hint, reason); } else { - sk_image = CreateTransparentSkImage(size()); + sk_image = CreateTransparentSkImage(Size()); } } else { if (ExpensiveCanvasHeuristicParameters:: @@ -1296,7 +1292,7 @@ if (image) { sk_image = image->ImageForCurrentFrame(); } else { - sk_image = CreateTransparentSkImage(size()); + sk_image = CreateTransparentSkImage(Size()); } }
diff --git a/third_party/WebKit/Source/core/html/HTMLCanvasElement.h b/third_party/WebKit/Source/core/html/HTMLCanvasElement.h index 4aa2a41c..2c443b2 100644 --- a/third_party/WebKit/Source/core/html/HTMLCanvasElement.h +++ b/third_party/WebKit/Source/core/html/HTMLCanvasElement.h
@@ -28,6 +28,7 @@ #ifndef HTMLCanvasElement_h #define HTMLCanvasElement_h +#include <memory> #include "bindings/core/v8/ScriptValue.h" #include "bindings/core/v8/ScriptWrappableVisitor.h" #include "core/CoreExport.h" @@ -38,6 +39,7 @@ #include "core/html/HTMLElement.h" #include "core/html/canvas/CanvasDrawListener.h" #include "core/html/canvas/CanvasImageSource.h" +#include "core/html/canvas/CanvasRenderingContextHost.h" #include "core/imagebitmap/ImageBitmapSource.h" #include "core/page/PageVisibilityObserver.h" #include "platform/geometry/FloatRect.h" @@ -48,7 +50,6 @@ #include "platform/graphics/ImageBufferClient.h" #include "platform/graphics/OffscreenCanvasPlaceholder.h" #include "platform/heap/Handle.h" -#include <memory> #define CanvasDefaultInterpolationQuality kInterpolationLow @@ -78,6 +79,7 @@ public ContextLifecycleObserver, public PageVisibilityObserver, public CanvasImageSource, + public CanvasRenderingContextHost, public CanvasSurfaceLayerBridgeObserver, public ImageBufferClient, public ImageBitmapSource, @@ -93,10 +95,10 @@ ~HTMLCanvasElement() override; // Attributes and functions exposed to script - int width() const { return size().Width(); } - int height() const { return size().Height(); } + int width() const { return Size().Width(); } + int height() const { return Size().Height(); } - const IntSize& size() const { return size_; } + const IntSize& Size() const override { return size_; } void setWidth(int, ExceptionState&); void setHeight(int, ExceptionState&); @@ -133,8 +135,8 @@ void RemoveListener(CanvasDrawListener*); // Used for rendering - void DidDraw(const FloatRect&); - void DidDraw(); + void DidDraw(const FloatRect&) override; + void DidDraw() override; void Paint(GraphicsContext&, const LayoutRect&); @@ -151,7 +153,6 @@ SnapshotReason) const; void ClearCopiedImage(); - SecurityOrigin* GetSecurityOrigin() const; bool OriginClean() const; void SetOriginTainted() { origin_clean_ = false; } @@ -176,7 +177,7 @@ void DoDeferredPaintInvalidation(); - void FinalizeFrame(); + void FinalizeFrame() override; // ContextLifecycleObserver and PageVisibilityObserver implementation void ContextDestroyed(ExecutionContext*) override; @@ -246,10 +247,22 @@ } void CreateLayer(); - void DetachContext() { context_ = nullptr; } + void DetachContext() override { context_ = nullptr; } void WillDrawImageTo2DContext(CanvasImageSource*); + ExecutionContext* GetTopExecutionContext() const override { + return GetDocument().GetExecutionContext(); + } + + const KURL& GetExecutionContextUrl() const override { + return GetDocument().TopDocument().Url(); + } + + DispatchEventResult HostDispatchEvent(Event* event) override { + return DispatchEvent(event); + } + protected: void DidMoveToNewDocument(Document& old_document) override;
diff --git a/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.cpp b/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.cpp index bb9f51c..6bd76fd 100644 --- a/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.cpp +++ b/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.cpp
@@ -34,11 +34,9 @@ namespace blink { CanvasRenderingContext::CanvasRenderingContext( - HTMLCanvasElement* canvas, - OffscreenCanvas* offscreen_canvas, + CanvasRenderingContextHost* host, const CanvasContextCreationAttributes& attrs) - : canvas_(canvas), - offscreen_canvas_(offscreen_canvas), + : host_(host), color_params_(kLegacyCanvasColorSpace, kRGBA8CanvasPixelFormat), creation_attributes_(attrs) { if (RuntimeEnabledFeatures::experimentalCanvasFeaturesEnabled() && @@ -118,23 +116,19 @@ // the other in order to break the circular reference. This is to avoid // an error when CanvasRenderingContext::didProcessTask() is invoked // after the HTMLCanvasElement is destroyed. - if (canvas()) { - canvas()->DetachContext(); - canvas_ = nullptr; - } - if (offscreenCanvas()) { - offscreenCanvas()->DetachContext(); - offscreen_canvas_ = nullptr; + if (host()) { + host()->DetachContext(); + host_ = nullptr; } } void CanvasRenderingContext::DidDraw(const SkIRect& dirty_rect) { - canvas()->DidDraw(SkRect::Make(dirty_rect)); + host()->DidDraw(SkRect::Make(dirty_rect)); NeedsFinalizeFrame(); } void CanvasRenderingContext::DidDraw() { - canvas()->DidDraw(); + host()->DidDraw(); NeedsFinalizeFrame(); } @@ -150,10 +144,9 @@ finalize_frame_scheduled_ = false; // The end of a script task that drew content to the canvas is the point // at which the current frame may be considered complete. - if (canvas()) - canvas()->FinalizeFrame(); - if (offscreenCanvas()) - offscreenCanvas()->FinalizeFrame(); + if (host()) { + host()->FinalizeFrame(); + } FinalizeFrame(); } @@ -208,8 +201,7 @@ } DEFINE_TRACE(CanvasRenderingContext) { - visitor->Trace(canvas_); - visitor->Trace(offscreen_canvas_); + visitor->Trace(host_); } } // namespace blink
diff --git a/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.h b/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.h index 84040416..31bf811 100644 --- a/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.h +++ b/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.h
@@ -87,7 +87,7 @@ static ContextType ContextTypeFromId(const String& id); static ContextType ResolveContextTypeAliases(ContextType); - HTMLCanvasElement* canvas() const { return canvas_; } + CanvasRenderingContextHost* host() const { return host_; } WTF::String ColorSpaceAsString() const; WTF::String PixelFormatAsString() const; @@ -104,6 +104,7 @@ virtual bool ShouldAntialias() const { return false; } virtual void SetIsHidden(bool) = 0; virtual bool isContextLost() const { return true; } + // TODO(fserb): remove SetCanvasGetContextResult. virtual void SetCanvasGetContextResult(RenderingContext&) { NOTREACHED(); }; virtual void SetOffscreenCanvasGetContextResult(OffscreenRenderingContext&) { NOTREACHED(); @@ -182,22 +183,19 @@ virtual bool Paint(GraphicsContext&, const IntRect&) { return false; } // OffscreenCanvas-specific methods - OffscreenCanvas* offscreenCanvas() const { return offscreen_canvas_; } virtual ImageBitmap* TransferToImageBitmap(ScriptState*) { return nullptr; } bool WouldTaintOrigin(CanvasImageSource*, SecurityOrigin*); void DidMoveToNewDocument(Document*); - void DetachCanvas() { canvas_ = nullptr; } - void DetachOffscreenCanvas() { offscreen_canvas_ = nullptr; } + void DetachHost() { host_ = nullptr; } const CanvasContextCreationAttributes& CreationAttributes() const { return creation_attributes_; } protected: - CanvasRenderingContext(HTMLCanvasElement*, - OffscreenCanvas*, + CanvasRenderingContext(CanvasRenderingContextHost*, const CanvasContextCreationAttributes&); DECLARE_VIRTUAL_TRACE(); virtual void Stop() = 0; @@ -205,8 +203,7 @@ private: void Dispose(); - Member<HTMLCanvasElement> canvas_; - Member<OffscreenCanvas> offscreen_canvas_; + Member<CanvasRenderingContextHost> host_; HashSet<String> clean_urls_; HashSet<String> dirty_urls_; CanvasColorParams color_params_;
diff --git a/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContextHost.cpp b/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContextHost.cpp new file mode 100644 index 0000000..8d58c41 --- /dev/null +++ b/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContextHost.cpp
@@ -0,0 +1,25 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "core/html/canvas/CanvasRenderingContextHost.h" + +#include "platform/graphics/StaticBitmapImage.h" + +namespace blink { + +CanvasRenderingContextHost::CanvasRenderingContextHost() {} + +ScriptPromise CanvasRenderingContextHost::Commit( + RefPtr<StaticBitmapImage> bitmap_image, + bool is_web_gl_software_rendering, + ScriptState* script_state, + ExceptionState& exception_state) { + exception_state.ThrowDOMException(kInvalidStateError, + "Commit() was called on a rendering " + "context that was not created from an " + "OffscreenCanvas."); + return exception_state.Reject(script_state); +} + +} // namespace blink
diff --git a/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContextHost.h b/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContextHost.h new file mode 100644 index 0000000..f123b73 --- /dev/null +++ b/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContextHost.h
@@ -0,0 +1,56 @@ +// 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 CanvasRenderingContextHost_h +#define CanvasRenderingContextHost_h + +#include "bindings/core/v8/ExceptionState.h" +#include "bindings/core/v8/ScriptPromise.h" +#include "bindings/core/v8/ScriptState.h" +#include "core/CoreExport.h" +#include "core/events/EventDispatcher.h" +#include "core/events/EventTarget.h" +#include "platform/geometry/FloatRect.h" +#include "platform/geometry/IntSize.h" +#include "platform/heap/GarbageCollected.h" + +namespace blink { + +class StaticBitmapImage; +class KURL; + +class CORE_EXPORT CanvasRenderingContextHost : public GarbageCollectedMixin { + public: + CanvasRenderingContextHost(); + + virtual void DetachContext() = 0; + + virtual void DidDraw(const FloatRect& rect) {} + virtual void DidDraw() {} + + virtual void FinalizeFrame() = 0; + + virtual bool OriginClean() const = 0; + virtual void SetOriginTainted() = 0; + virtual const IntSize& Size() const = 0; + + virtual ExecutionContext* GetTopExecutionContext() const = 0; + virtual DispatchEventResult HostDispatchEvent(Event*) = 0; + virtual const KURL& GetExecutionContextUrl() const = 0; + + virtual ScriptPromise Commit(RefPtr<StaticBitmapImage>, + bool is_web_gl_software_rendering, + ScriptState*, + ExceptionState&); + + // TODO(fserb): remove this. + virtual bool IsOffscreenCanvas() const { return false; } + + protected: + virtual ~CanvasRenderingContextHost() {} +}; + +} // namespace blink + +#endif // CanvasRenderingContextHost_h
diff --git a/third_party/WebKit/Source/core/layout/BUILD.gn b/third_party/WebKit/Source/core/layout/BUILD.gn index f8c6a02..4f7687f 100644 --- a/third_party/WebKit/Source/core/layout/BUILD.gn +++ b/third_party/WebKit/Source/core/layout/BUILD.gn
@@ -348,12 +348,14 @@ "ng/inline/ng_inline_box_state.h", "ng/inline/ng_inline_break_token.cc", "ng/inline/ng_inline_break_token.h", + "ng/inline/ng_inline_item.cc", + "ng/inline/ng_inline_item.h", + "ng/inline/ng_inline_items_builder.cc", + "ng/inline/ng_inline_items_builder.h", "ng/inline/ng_inline_layout_algorithm.cc", "ng/inline/ng_inline_layout_algorithm.h", "ng/inline/ng_inline_node.cc", "ng/inline/ng_inline_node.h", - "ng/inline/ng_layout_inline_items_builder.cc", - "ng/inline/ng_layout_inline_items_builder.h", "ng/inline/ng_line_box_fragment.cc", "ng/inline/ng_line_box_fragment.h", "ng/inline/ng_line_box_fragment_builder.cc",
diff --git a/third_party/WebKit/Source/core/layout/LayoutHTMLCanvas.cpp b/third_party/WebKit/Source/core/layout/LayoutHTMLCanvas.cpp index ef1db22..76a67da 100644 --- a/third_party/WebKit/Source/core/layout/LayoutHTMLCanvas.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutHTMLCanvas.cpp
@@ -38,7 +38,7 @@ using namespace HTMLNames; LayoutHTMLCanvas::LayoutHTMLCanvas(HTMLCanvasElement* element) - : LayoutReplaced(element, LayoutSize(element->size())) { + : LayoutReplaced(element, LayoutSize(element->Size())) { View()->GetFrameView()->SetIsVisuallyNonEmpty(); } @@ -52,7 +52,7 @@ } void LayoutHTMLCanvas::CanvasSizeChanged() { - IntSize canvas_size = toHTMLCanvasElement(GetNode())->size(); + IntSize canvas_size = toHTMLCanvasElement(GetNode())->Size(); LayoutSize zoomed_size(canvas_size.Width() * Style()->EffectiveZoom(), canvas_size.Height() * Style()->EffectiveZoom());
diff --git a/third_party/WebKit/Source/core/layout/ng/README.md b/third_party/WebKit/Source/core/layout/ng/README.md index fd24f86..38f80092 100644 --- a/third_party/WebKit/Source/core/layout/ng/README.md +++ b/third_party/WebKit/Source/core/layout/ng/README.md
@@ -53,8 +53,8 @@ all non-atomic inlines and `TextNodes`s. Atomic inlines are represented as a unicode object replacement character but are otherwise skipped. Each non-atomic inline and `TextNodes` is fed to a - [NGLayoutInlineItemsBuilder](ng_layout_inline_items_builder.h) instance - which collects the text content for all non-atomic inlines in the container. + [NGInlineItemsBuilder](ng_inline_items_builder.h) instance which collects + the text content for all non-atomic inlines in the container. During this process white-space is collapsed and normalized according to CSS white-space processing rules.
diff --git a/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_box_state.cc b/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_box_state.cc index 21633c7..ffe34569 100644 --- a/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_box_state.cc +++ b/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_box_state.cc
@@ -11,7 +11,7 @@ namespace blink { -void NGInlineBoxState::ComputeTextMetrics(const NGLayoutInlineItem& item, +void NGInlineBoxState::ComputeTextMetrics(const NGInlineItem& item, FontBaseline baseline_type) { const ComputedStyle& style = *item.Style(); text_metrics = NGLineHeightMetrics(style, baseline_type); @@ -43,7 +43,7 @@ } NGInlineBoxState* NGInlineLayoutStateStack::OnOpenTag( - const NGLayoutInlineItem& item, + const NGInlineItem& item, NGLineBoxFragmentBuilder* line_box, NGTextFragmentBuilder* text_builder) { stack_.Resize(stack_.size() + 1); @@ -55,7 +55,7 @@ } NGInlineBoxState* NGInlineLayoutStateStack::OnCloseTag( - const NGLayoutInlineItem& item, + const NGInlineItem& item, NGLineBoxFragmentBuilder* line_box, NGInlineBoxState* box) { EndBoxState(box, line_box);
diff --git a/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_box_state.h b/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_box_state.h index c09b91e1..e3675e1 100644 --- a/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_box_state.h +++ b/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_box_state.h
@@ -14,7 +14,7 @@ namespace blink { -class NGLayoutInlineItem; +class NGInlineItem; class NGLineBoxFragmentBuilder; class NGTextFragmentBuilder; @@ -40,7 +40,7 @@ bool include_used_fonts = false; // Compute text metrics for a box. All text in a box share the same metrics. - void ComputeTextMetrics(const NGLayoutInlineItem&, FontBaseline); + void ComputeTextMetrics(const NGInlineItem&, FontBaseline); }; // Represents the inline tree structure. This class provides: @@ -54,12 +54,12 @@ NGInlineBoxState* OnBeginPlaceItems(const ComputedStyle*); // Push a box state stack. - NGInlineBoxState* OnOpenTag(const NGLayoutInlineItem&, + NGInlineBoxState* OnOpenTag(const NGInlineItem&, NGLineBoxFragmentBuilder*, NGTextFragmentBuilder*); // Pop a box state stack. - NGInlineBoxState* OnCloseTag(const NGLayoutInlineItem&, + NGInlineBoxState* OnCloseTag(const NGInlineItem&, NGLineBoxFragmentBuilder*, NGInlineBoxState*);
diff --git a/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_item.cc b/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_item.cc new file mode 100644 index 0000000..a2ce14c --- /dev/null +++ b/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_item.cc
@@ -0,0 +1,118 @@ +// 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 "core/layout/ng/inline/ng_inline_item.h" + +#include "platform/fonts/CharacterRange.h" +#include "platform/fonts/shaping/ShapeResultBuffer.h" + +namespace blink { + +// Set bidi level to a list of NGInlineItem from |index| to the item that ends +// with |end_offset|. +// If |end_offset| is mid of an item, the item is split to ensure each item has +// one bidi level. +// @param items The list of NGInlineItem. +// @param index The first index of the list to set. +// @param end_offset The exclusive end offset to set. +// @param level The level to set. +// @return The index of the next item. +unsigned NGInlineItem::SetBidiLevel(Vector<NGInlineItem>& items, + unsigned index, + unsigned end_offset, + UBiDiLevel level) { + for (; items[index].end_offset_ < end_offset; index++) + items[index].bidi_level_ = level; + items[index].bidi_level_ = level; + + if (items[index].end_offset_ == end_offset) { + // Let close items have the same bidi-level as the previous item. + while (index + 1 < items.size() && + items[index + 1].Type() == NGInlineItem::kCloseTag) { + items[++index].bidi_level_ = level; + } + } else { + Split(items, index, end_offset); + } + + return index + 1; +} + +// Split |items[index]| to 2 items at |offset|. +// All properties other than offsets are copied to the new item and it is +// inserted at |items[index + 1]|. +// @param items The list of NGInlineItem. +// @param index The index to split. +// @param offset The offset to split at. +void NGInlineItem::Split(Vector<NGInlineItem>& items, + unsigned index, + unsigned offset) { + DCHECK_GT(offset, items[index].start_offset_); + DCHECK_LT(offset, items[index].end_offset_); + items.insert(index + 1, items[index]); + items[index].end_offset_ = offset; + items[index + 1].start_offset_ = offset; +} + +void NGInlineItem::SetOffset(unsigned start, unsigned end) { + DCHECK_GE(end, start); + start_offset_ = start; + end_offset_ = end; +} + +void NGInlineItem::SetEndOffset(unsigned end_offset) { + DCHECK_GE(end_offset, start_offset_); + end_offset_ = end_offset; +} + +LayoutUnit NGInlineItem::InlineSize() const { + if (Type() == NGInlineItem::kText) + return LayoutUnit(shape_result_->Width()); + + DCHECK_NE(Type(), NGInlineItem::kAtomicInline) + << "Use NGInlineLayoutAlgorithm::InlineSize"; + // Bidi controls and out-of-flow objects do not have in-flow widths. + return LayoutUnit(); +} + +LayoutUnit NGInlineItem::InlineSize(unsigned start, unsigned end) const { + DCHECK_GE(start, StartOffset()); + DCHECK_LE(start, end); + DCHECK_LE(end, EndOffset()); + + if (start == end) + return LayoutUnit(); + if (start == start_offset_ && end == end_offset_) + return InlineSize(); + + DCHECK_EQ(Type(), NGInlineItem::kText); + return LayoutUnit(ShapeResultBuffer::GetCharacterRange( + shape_result_, Direction(), shape_result_->Width(), + start - StartOffset(), end - StartOffset()) + .Width()); +} + +void NGInlineItem::GetFallbackFonts( + HashSet<const SimpleFontData*>* fallback_fonts, + unsigned start, + unsigned end) const { + DCHECK_GE(start, StartOffset()); + DCHECK_LE(start, end); + DCHECK_LE(end, EndOffset()); + + // TODO(kojii): Implement |start| and |end|. + shape_result_->FallbackFonts(fallback_fonts); +} + +NGInlineItemRange::NGInlineItemRange(Vector<NGInlineItem>* items, + unsigned start_index, + unsigned end_index) + : start_item_(&(*items)[start_index]), + size_(end_index - start_index), + start_index_(start_index) { + CHECK_LE(start_index, end_index); + CHECK_LE(end_index, items->size()); +} + +} // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_item.h b/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_item.h new file mode 100644 index 0000000..3d0365e --- /dev/null +++ b/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_item.h
@@ -0,0 +1,171 @@ +// 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 NGInlineItem_h +#define NGInlineItem_h + +#include "platform/LayoutUnit.h" +#include "platform/fonts/FontFallbackPriority.h" +#include "platform/fonts/SimpleFontData.h" +#include "platform/fonts/shaping/ShapeResult.h" +#include "platform/text/TextDirection.h" +#include "platform/wtf/HashSet.h" + +#include <unicode/ubidi.h> + +namespace blink { + +class ComputedStyle; +class LayoutObject; + +// Class representing a single text node or styled inline element with text +// content segmented by style, text direction, sideways rotation, font fallback +// priority (text, symbol, emoji, etc), and script (but not by font). +// In this representation TextNodes are merged up into their parent inline +// element where possible. +class NGInlineItem { + public: + enum NGInlineItemType { + kText, + kAtomicInline, + kOpenTag, + kCloseTag, + kFloating, + kOutOfFlowPositioned, + kBidiControl + // When adding new values, make sure the bit size of |type_| is large + // enough to store. + }; + + // Whether pre- and post-context should be used for shaping. + enum NGLayoutInlineShapeOptions { + kNoContext = 0, + kPreContext = 1, + kPostContext = 2 + }; + + NGInlineItem(NGInlineItemType type, + unsigned start, + unsigned end, + const ComputedStyle* style = nullptr, + LayoutObject* layout_object = nullptr) + : start_offset_(start), + end_offset_(end), + script_(USCRIPT_INVALID_CODE), + style_(style), + layout_object_(layout_object), + type_(type), + bidi_level_(UBIDI_LTR), + shape_options_(kPreContext | kPostContext), + rotate_sideways_(false), + fallback_priority_(FontFallbackPriority::kInvalid) { + DCHECK_GE(end, start); + } + + NGInlineItemType Type() const { return static_cast<NGInlineItemType>(type_); } + + NGLayoutInlineShapeOptions ShapeOptions() const { + return static_cast<NGLayoutInlineShapeOptions>(shape_options_); + } + + unsigned StartOffset() const { return start_offset_; } + unsigned EndOffset() const { return end_offset_; } + unsigned Length() const { return end_offset_ - start_offset_; } + TextDirection Direction() const { + return BidiLevel() & 1 ? TextDirection::kRtl : TextDirection::kLtr; + } + UBiDiLevel BidiLevel() const { return static_cast<UBiDiLevel>(bidi_level_); } + UScriptCode GetScript() const { return script_; } + const ComputedStyle* Style() const { return style_; } + LayoutObject* GetLayoutObject() const { return layout_object_; } + + void SetOffset(unsigned start, unsigned end); + void SetEndOffset(unsigned); + + LayoutUnit InlineSize() const; + LayoutUnit InlineSize(unsigned start, unsigned end) const; + + void GetFallbackFonts(HashSet<const SimpleFontData*>*, + unsigned start, + unsigned end) const; + + static void Split(Vector<NGInlineItem>&, unsigned index, unsigned offset); + static unsigned SetBidiLevel(Vector<NGInlineItem>&, + unsigned index, + unsigned end_offset, + UBiDiLevel); + + void AssertOffset(unsigned offset) const; + void AssertEndOffset(unsigned offset) const; + + private: + unsigned start_offset_; + unsigned end_offset_; + UScriptCode script_; + RefPtr<const ShapeResult> shape_result_; + const ComputedStyle* style_; + LayoutObject* layout_object_; + + unsigned type_ : 3; + unsigned bidi_level_ : 8; // UBiDiLevel is defined as uint8_t. + unsigned shape_options_ : 2; + unsigned rotate_sideways_ : 1; + + // TODO(layout-ng): Do we need fallback_priority_ here? If so we should pack + // it with the bit field above. + FontFallbackPriority fallback_priority_; + + friend class NGInlineNode; +}; + +inline void NGInlineItem::AssertOffset(unsigned offset) const { + DCHECK((offset >= start_offset_ && offset < end_offset_) || + (offset == start_offset_ && start_offset_ == end_offset_)); +} + +inline void NGInlineItem::AssertEndOffset(unsigned offset) const { + DCHECK_GE(offset, start_offset_); + DCHECK_LE(offset, end_offset_); +} + +// A vector-like object that points to a subset of an array of |NGInlineItem|. +// The source vector must keep alive and must not resize while this object +// is alive. +class NGInlineItemRange { + STACK_ALLOCATED(); + + public: + NGInlineItemRange(Vector<NGInlineItem>*, + unsigned start_index, + unsigned end_index); + + unsigned StartIndex() const { return start_index_; } + unsigned EndIndex() const { return start_index_ + size_; } + unsigned Size() const { return size_; } + + NGInlineItem& operator[](unsigned index) { + CHECK_LT(index, size_); + return start_item_[index]; + } + const NGInlineItem& operator[](unsigned index) const { + CHECK_LT(index, size_); + return start_item_[index]; + } + + using iterator = NGInlineItem*; + using const_iterator = const NGInlineItem*; + iterator begin() { return start_item_; } + iterator end() { return start_item_ + size_; } + const_iterator begin() const { return start_item_; } + const_iterator end() const { return start_item_ + size_; } + + private: + NGInlineItem* start_item_; + unsigned size_; + unsigned start_index_; +}; + +} // namespace blink + +#endif // NGInlineItem_h
diff --git a/third_party/WebKit/Source/core/layout/ng/inline/ng_layout_inline_items_builder.cc b/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_items_builder.cc similarity index 81% rename from third_party/WebKit/Source/core/layout/ng/inline/ng_layout_inline_items_builder.cc rename to third_party/WebKit/Source/core/layout/ng/inline/ng_inline_items_builder.cc index 70a5a29..2aec093 100644 --- a/third_party/WebKit/Source/core/layout/ng/inline/ng_layout_inline_items_builder.cc +++ b/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_items_builder.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "core/layout/ng/inline/ng_layout_inline_items_builder.h" +#include "core/layout/ng/inline/ng_inline_items_builder.h" #include "core/layout/LayoutObject.h" #include "core/layout/ng/inline/ng_inline_node.h" @@ -10,12 +10,12 @@ namespace blink { -NGLayoutInlineItemsBuilder::~NGLayoutInlineItemsBuilder() { +NGInlineItemsBuilder::~NGInlineItemsBuilder() { DCHECK_EQ(0u, exits_.size()); DCHECK_EQ(text_.length(), items_->IsEmpty() ? 0 : items_->back().EndOffset()); } -String NGLayoutInlineItemsBuilder::ToString() { +String NGInlineItemsBuilder::ToString() { // Segment Break Transformation Rules[1] defines to keep trailing new lines, // but it will be removed in Phase II[2]. We prefer not to add trailing new // lines and collapsible spaces in Phase I. @@ -103,14 +103,14 @@ after_style); } -static void AppendItem(Vector<NGLayoutInlineItem>* items, - NGLayoutInlineItem::NGLayoutInlineItemType type, +static void AppendItem(Vector<NGInlineItem>* items, + NGInlineItem::NGInlineItemType type, unsigned start, unsigned end, const ComputedStyle* style = nullptr, LayoutObject* layout_object = nullptr) { DCHECK(items->IsEmpty() || items->back().EndOffset() == start); - items->push_back(NGLayoutInlineItem(type, start, end, style, layout_object)); + items->push_back(NGInlineItem(type, start, end, style, layout_object)); } static inline bool IsCollapsibleSpace(UChar c, bool preserve_newline) { @@ -118,9 +118,9 @@ (!preserve_newline && c == kNewlineCharacter); } -void NGLayoutInlineItemsBuilder::Append(const String& string, - const ComputedStyle* style, - LayoutObject* layout_object) { +void NGInlineItemsBuilder::Append(const String& string, + const ComputedStyle* style, + LayoutObject* layout_object) { if (string.IsEmpty()) return; @@ -179,16 +179,15 @@ } if (text_.length() > start_offset) { - AppendItem(items_, NGLayoutInlineItem::kText, start_offset, text_.length(), - style, layout_object); + AppendItem(items_, NGInlineItem::kText, start_offset, text_.length(), style, + layout_object); } } -void NGLayoutInlineItemsBuilder::Append( - NGLayoutInlineItem::NGLayoutInlineItemType type, - UChar character, - const ComputedStyle* style, - LayoutObject* layout_object) { +void NGInlineItemsBuilder::Append(NGInlineItem::NGInlineItemType type, + UChar character, + const ComputedStyle* style, + LayoutObject* layout_object) { DCHECK_NE(character, kSpaceCharacter); DCHECK_NE(character, kTabulationCharacter); DCHECK_NE(character, kNewlineCharacter); @@ -200,15 +199,14 @@ last_collapsible_space_ = CollapsibleSpace::kNone; } -void NGLayoutInlineItemsBuilder::Append( - NGLayoutInlineItem::NGLayoutInlineItemType type, - const ComputedStyle* style, - LayoutObject* layout_object) { +void NGInlineItemsBuilder::Append(NGInlineItem::NGInlineItemType type, + const ComputedStyle* style, + LayoutObject* layout_object) { unsigned end_offset = text_.length(); AppendItem(items_, type, end_offset, end_offset, style, layout_object); } -void NGLayoutInlineItemsBuilder::RemoveTrailingCollapsibleNewlineIfNeeded( +void NGInlineItemsBuilder::RemoveTrailingCollapsibleNewlineIfNeeded( unsigned* next_start_offset, const String& after, unsigned after_index, @@ -220,7 +218,7 @@ const ComputedStyle* before_style = after_style; if (!items_->IsEmpty()) { - NGLayoutInlineItem& item = items_->back(); + NGInlineItem& item = items_->back(); if (text_.length() < item.EndOffset() + 2) before_style = item.Style(); } @@ -229,14 +227,14 @@ RemoveTrailingCollapsibleSpace(next_start_offset); } -void NGLayoutInlineItemsBuilder::RemoveTrailingCollapsibleSpaceIfExists( +void NGInlineItemsBuilder::RemoveTrailingCollapsibleSpaceIfExists( unsigned* next_start_offset) { if (last_collapsible_space_ != CollapsibleSpace::kNone && !text_.IsEmpty() && text_[text_.length() - 1] == kSpaceCharacter) RemoveTrailingCollapsibleSpace(next_start_offset); } -void NGLayoutInlineItemsBuilder::RemoveTrailingCollapsibleSpace( +void NGInlineItemsBuilder::RemoveTrailingCollapsibleSpace( unsigned* next_start_offset) { DCHECK_NE(last_collapsible_space_, CollapsibleSpace::kNone); DCHECK(!text_.IsEmpty()); @@ -252,9 +250,9 @@ // Adjust the last item if the removed space is already appended. for (unsigned i = items_->size(); i > 0;) { - NGLayoutInlineItem& item = (*items_)[--i]; + NGInlineItem& item = (*items_)[--i]; DCHECK_EQ(item.EndOffset(), new_size + 1); - if (item.Type() == NGLayoutInlineItem::kText) { + if (item.Type() == NGInlineItem::kText) { DCHECK_GE(item.Length(), 1u); if (item.Length() > 1) item.SetEndOffset(new_size); @@ -272,14 +270,14 @@ } } -void NGLayoutInlineItemsBuilder::AppendBidiControl(const ComputedStyle* style, - UChar ltr, - UChar rtl) { - Append(NGLayoutInlineItem::kBidiControl, +void NGInlineItemsBuilder::AppendBidiControl(const ComputedStyle* style, + UChar ltr, + UChar rtl) { + Append(NGInlineItem::kBidiControl, style->Direction() == TextDirection::kRtl ? rtl : ltr); } -void NGLayoutInlineItemsBuilder::EnterBlock(const ComputedStyle* style) { +void NGInlineItemsBuilder::EnterBlock(const ComputedStyle* style) { // Handle bidi-override on the block itself. switch (style->GetUnicodeBidi()) { case UnicodeBidi::kNormal: @@ -306,7 +304,7 @@ } } -void NGLayoutInlineItemsBuilder::EnterInline(LayoutObject* node) { +void NGInlineItemsBuilder::EnterInline(LayoutObject* node) { // https://drafts.csswg.org/css-writing-modes-3/#bidi-control-codes-injection-table const ComputedStyle* style = node->Style(); switch (style->GetUnicodeBidi()) { @@ -328,11 +326,11 @@ Enter(node, kPopDirectionalIsolateCharacter); break; case UnicodeBidi::kPlaintext: - Append(NGLayoutInlineItem::kBidiControl, kFirstStrongIsolateCharacter); + Append(NGInlineItem::kBidiControl, kFirstStrongIsolateCharacter); Enter(node, kPopDirectionalIsolateCharacter); break; case UnicodeBidi::kIsolateOverride: - Append(NGLayoutInlineItem::kBidiControl, kFirstStrongIsolateCharacter); + Append(NGInlineItem::kBidiControl, kFirstStrongIsolateCharacter); AppendBidiControl(style, kLeftToRightOverrideCharacter, kRightToLeftOverrideCharacter); Enter(node, kPopDirectionalIsolateCharacter); @@ -340,30 +338,29 @@ break; } - Append(NGLayoutInlineItem::kOpenTag, style, node); + Append(NGInlineItem::kOpenTag, style, node); } -void NGLayoutInlineItemsBuilder::Enter(LayoutObject* node, - UChar character_to_exit) { +void NGInlineItemsBuilder::Enter(LayoutObject* node, UChar character_to_exit) { exits_.push_back(OnExitNode{node, character_to_exit}); has_bidi_controls_ = true; } -void NGLayoutInlineItemsBuilder::ExitBlock() { +void NGInlineItemsBuilder::ExitBlock() { Exit(nullptr); } -void NGLayoutInlineItemsBuilder::ExitInline(LayoutObject* node) { +void NGInlineItemsBuilder::ExitInline(LayoutObject* node) { DCHECK(node); - Append(NGLayoutInlineItem::kCloseTag, node->Style(), node); + Append(NGInlineItem::kCloseTag, node->Style(), node); Exit(node); } -void NGLayoutInlineItemsBuilder::Exit(LayoutObject* node) { +void NGInlineItemsBuilder::Exit(LayoutObject* node) { while (!exits_.IsEmpty() && exits_.back().node == node) { - Append(NGLayoutInlineItem::kBidiControl, exits_.back().character); + Append(NGInlineItem::kBidiControl, exits_.back().character); exits_.pop_back(); } }
diff --git a/third_party/WebKit/Source/core/layout/ng/inline/ng_layout_inline_items_builder.h b/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_items_builder.h similarity index 86% rename from third_party/WebKit/Source/core/layout/ng/inline/ng_layout_inline_items_builder.h rename to third_party/WebKit/Source/core/layout/ng/inline/ng_inline_items_builder.h index 79972a45..9d3757b 100644 --- a/third_party/WebKit/Source/core/layout/ng/inline/ng_layout_inline_items_builder.h +++ b/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_items_builder.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef NGLayoutInlineItemsBuilder_h -#define NGLayoutInlineItemsBuilder_h +#ifndef NGInlineItemsBuilder_h +#define NGInlineItemsBuilder_h #include "core/CoreExport.h" #include "core/layout/ng/inline/ng_inline_node.h" @@ -16,10 +16,9 @@ class ComputedStyle; class LayoutObject; -class NGLayoutInlineItem; +class NGInlineItem; -// NGLayoutInlineItemsBuilder builds a string and a list of NGLayoutInlineItem -// from inlines. +// NGInlineItemsBuilder builds a string and a list of NGInlineItem from inlines. // // When appending, spaces are collapsed according to CSS Text, The white space // processing rules @@ -28,13 +27,12 @@ // By calling EnterInline/ExitInline, it inserts bidirectional control // characters as defined in: // https://drafts.csswg.org/css-writing-modes-3/#bidi-control-codes-injection-table -class CORE_EXPORT NGLayoutInlineItemsBuilder { +class CORE_EXPORT NGInlineItemsBuilder { STACK_ALLOCATED(); public: - explicit NGLayoutInlineItemsBuilder(Vector<NGLayoutInlineItem>* items) - : items_(items) {} - ~NGLayoutInlineItemsBuilder(); + explicit NGInlineItemsBuilder(Vector<NGInlineItem>* items) : items_(items) {} + ~NGInlineItemsBuilder(); String ToString(); @@ -60,13 +58,13 @@ // as its String version does. // See the String version for using nullptr for ComputedStyle and // LayoutObject. - void Append(NGLayoutInlineItem::NGLayoutInlineItemType, + void Append(NGInlineItem::NGInlineItemType, UChar, const ComputedStyle* = nullptr, LayoutObject* = nullptr); // Append a non-character item. - void Append(NGLayoutInlineItem::NGLayoutInlineItemType, + void Append(NGInlineItem::NGInlineItemType, const ComputedStyle* = nullptr, LayoutObject* = nullptr); @@ -79,7 +77,7 @@ void ExitInline(LayoutObject*); private: - Vector<NGLayoutInlineItem>* items_; + Vector<NGInlineItem>* items_; StringBuilder text_; typedef struct OnExitNode { @@ -115,4 +113,4 @@ } // namespace blink -#endif // NGLayoutInlineItemsBuilder_h +#endif // NGInlineItemsBuilder_h
diff --git a/third_party/WebKit/Source/core/layout/ng/inline/ng_layout_inline_items_builder_test.cc b/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_items_builder_test.cc similarity index 81% rename from third_party/WebKit/Source/core/layout/ng/inline/ng_layout_inline_items_builder_test.cc rename to third_party/WebKit/Source/core/layout/ng/inline/ng_inline_items_builder_test.cc index 97df728..5fee20f 100644 --- a/third_party/WebKit/Source/core/layout/ng/inline/ng_layout_inline_items_builder_test.cc +++ b/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_items_builder_test.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "core/layout/ng/inline/ng_layout_inline_items_builder.h" +#include "core/layout/ng/inline/ng_inline_items_builder.h" #include "core/layout/LayoutInline.h" #include "core/layout/ng/inline/ng_inline_node.h" @@ -19,7 +19,7 @@ return style.Release(); } -class NGLayoutInlineItemsBuilderTest : public ::testing::Test { +class NGInlineItemsBuilderTest : public ::testing::Test { protected: void SetUp() override { style_ = ComputedStyle::Create(); } @@ -29,7 +29,7 @@ const String& TestAppend(const String inputs[], int size) { items_.clear(); - NGLayoutInlineItemsBuilder builder(&items_); + NGInlineItemsBuilder builder(&items_); for (int i = 0; i < size; i++) builder.Append(inputs[i], style_.Get()); text_ = builder.ToString(); @@ -57,7 +57,7 @@ void ValidateItems() { unsigned current_offset = 0; for (unsigned i = 0; i < items_.size(); i++) { - const NGLayoutInlineItem& item = items_[i]; + const NGInlineItem& item = items_[i]; EXPECT_EQ(current_offset, item.StartOffset()); EXPECT_LT(item.StartOffset(), item.EndOffset()); current_offset = item.EndOffset(); @@ -65,7 +65,7 @@ EXPECT_EQ(current_offset, text_.length()); } - Vector<NGLayoutInlineItem> items_; + Vector<NGInlineItem> items_; String text_; RefPtr<ComputedStyle> style_; }; @@ -74,7 +74,7 @@ SetWhiteSpace(whitespace); \ EXPECT_EQ(expected, TestAppend(input)) << "white-space: " #whitespace; -TEST_F(NGLayoutInlineItemsBuilderTest, CollapseSpaces) { +TEST_F(NGInlineItemsBuilderTest, CollapseSpaces) { String input("text text text text"); String collapsed("text text text text"); TestWhitespaceValue(collapsed, input, EWhiteSpace::kNormal); @@ -85,7 +85,7 @@ TestWhitespaceValue(input, input, EWhiteSpace::kPreWrap); } -TEST_F(NGLayoutInlineItemsBuilderTest, CollapseTabs) { +TEST_F(NGInlineItemsBuilderTest, CollapseTabs) { String input("text\ttext\t text \t text"); String collapsed("text text text text"); TestWhitespaceValue(collapsed, input, EWhiteSpace::kNormal); @@ -96,7 +96,7 @@ TestWhitespaceValue(input, input, EWhiteSpace::kPreWrap); } -TEST_F(NGLayoutInlineItemsBuilderTest, CollapseNewLines) { +TEST_F(NGInlineItemsBuilderTest, CollapseNewLines) { String input("text\ntext \n text\n\ntext"); String collapsed("text text text text"); TestWhitespaceValue(collapsed, input, EWhiteSpace::kNormal); @@ -106,38 +106,38 @@ TestWhitespaceValue(input, input, EWhiteSpace::kPreWrap); } -TEST_F(NGLayoutInlineItemsBuilderTest, CollapseNewlinesAsSpaces) { +TEST_F(NGInlineItemsBuilderTest, CollapseNewlinesAsSpaces) { EXPECT_EQ("text text", TestAppend("text\ntext")); EXPECT_EQ("text text", TestAppend("text\n\ntext")); EXPECT_EQ("text text", TestAppend("text \n\n text")); EXPECT_EQ("text text", TestAppend("text \n \n text")); } -TEST_F(NGLayoutInlineItemsBuilderTest, CollapseAcrossElements) { +TEST_F(NGInlineItemsBuilderTest, CollapseAcrossElements) { EXPECT_EQ("text text", TestAppend("text ", " text")) << "Spaces are collapsed even when across elements."; } -TEST_F(NGLayoutInlineItemsBuilderTest, CollapseLeadingSpaces) { +TEST_F(NGInlineItemsBuilderTest, CollapseLeadingSpaces) { EXPECT_EQ("text", TestAppend(" text")); EXPECT_EQ("text", TestAppend(" ", "text")); EXPECT_EQ("text", TestAppend(" ", " text")); } -TEST_F(NGLayoutInlineItemsBuilderTest, CollapseTrailingSpaces) { +TEST_F(NGInlineItemsBuilderTest, CollapseTrailingSpaces) { EXPECT_EQ("text", TestAppend("text ")); EXPECT_EQ("text", TestAppend("text", " ")); EXPECT_EQ("text", TestAppend("text ", " ")); } -TEST_F(NGLayoutInlineItemsBuilderTest, CollapseAllSpaces) { +TEST_F(NGInlineItemsBuilderTest, CollapseAllSpaces) { EXPECT_EQ("", TestAppend(" ")); EXPECT_EQ("", TestAppend(" ", " ")); EXPECT_EQ("", TestAppend(" ", "\n")); EXPECT_EQ("", TestAppend("\n", " ")); } -TEST_F(NGLayoutInlineItemsBuilderTest, CollapseLeadingNewlines) { +TEST_F(NGInlineItemsBuilderTest, CollapseLeadingNewlines) { EXPECT_EQ("text", TestAppend("\ntext")); EXPECT_EQ("text", TestAppend("\n\ntext")); EXPECT_EQ("text", TestAppend("\n", "text")); @@ -151,7 +151,7 @@ EXPECT_EQ("text", TestAppend(" \n", "\ntext")); } -TEST_F(NGLayoutInlineItemsBuilderTest, CollapseTrailingNewlines) { +TEST_F(NGInlineItemsBuilderTest, CollapseTrailingNewlines) { EXPECT_EQ("text", TestAppend("text\n")); EXPECT_EQ("text", TestAppend("text", "\n")); EXPECT_EQ("text", TestAppend("text\n", "\n")); @@ -159,20 +159,20 @@ EXPECT_EQ("text", TestAppend("text ", "\n")); } -TEST_F(NGLayoutInlineItemsBuilderTest, CollapseBeforeNewlineAcrossElements) { +TEST_F(NGInlineItemsBuilderTest, CollapseBeforeNewlineAcrossElements) { EXPECT_EQ("text text", TestAppend("text ", "\ntext")); EXPECT_EQ("text text", TestAppend("text", " ", "\ntext")); } -TEST_F(NGLayoutInlineItemsBuilderTest, CollapseBeforeAndAfterNewline) { +TEST_F(NGInlineItemsBuilderTest, CollapseBeforeAndAfterNewline) { SetWhiteSpace(EWhiteSpace::kPreLine); EXPECT_EQ("text\ntext", TestAppend("text \n text")) << "Spaces before and after newline are removed."; } -TEST_F(NGLayoutInlineItemsBuilderTest, +TEST_F(NGInlineItemsBuilderTest, CollapsibleSpaceAfterNonCollapsibleSpaceAcrossElements) { - NGLayoutInlineItemsBuilder builder(&items_); + NGInlineItemsBuilder builder(&items_); RefPtr<ComputedStyle> pre_wrap(CreateWhitespaceStyle(EWhiteSpace::kPreWrap)); builder.Append("text ", pre_wrap.Get()); builder.Append(" text", style_.Get()); @@ -181,7 +181,7 @@ "pre-wrap\">text <span><span> text</span>' does not collapse."; } -TEST_F(NGLayoutInlineItemsBuilderTest, CollapseZeroWidthSpaces) { +TEST_F(NGInlineItemsBuilderTest, CollapseZeroWidthSpaces) { EXPECT_EQ(String(u"text\u200Btext"), TestAppend(u"text\u200B\ntext")) << "Newline is removed if the character before is ZWS."; EXPECT_EQ(String(u"text\u200Btext"), TestAppend(u"text\n\u200Btext")) @@ -204,7 +204,7 @@ "newline was removed."; } -TEST_F(NGLayoutInlineItemsBuilderTest, CollapseEastAsianWidth) { +TEST_F(NGInlineItemsBuilderTest, CollapseEastAsianWidth) { EXPECT_EQ(String(u"\u4E00\u4E00"), TestAppend(u"\u4E00\n\u4E00")) << "Newline is removed when both sides are Wide."; @@ -220,22 +220,19 @@ "when both sides are Wide."; } -TEST_F(NGLayoutInlineItemsBuilderTest, CollapseAroundReplacedElement) { - NGLayoutInlineItemsBuilder builder(&items_); +TEST_F(NGInlineItemsBuilderTest, CollapseAroundReplacedElement) { + NGInlineItemsBuilder builder(&items_); builder.Append("Hello ", style_.Get()); - builder.Append(NGLayoutInlineItem::kAtomicInline, - kObjectReplacementCharacter); + builder.Append(NGInlineItem::kAtomicInline, kObjectReplacementCharacter); builder.Append(" World", style_.Get()); EXPECT_EQ(String(u"Hello \uFFFC World"), builder.ToString()); } -TEST_F(NGLayoutInlineItemsBuilderTest, CollapseNewlineAfterObject) { - NGLayoutInlineItemsBuilder builder(&items_); - builder.Append(NGLayoutInlineItem::kAtomicInline, - kObjectReplacementCharacter); +TEST_F(NGInlineItemsBuilderTest, CollapseNewlineAfterObject) { + NGInlineItemsBuilder builder(&items_); + builder.Append(NGInlineItem::kAtomicInline, kObjectReplacementCharacter); builder.Append("\n", style_.Get()); - builder.Append(NGLayoutInlineItem::kAtomicInline, - kObjectReplacementCharacter); + builder.Append(NGInlineItem::kAtomicInline, kObjectReplacementCharacter); EXPECT_EQ(String(u"\uFFFC \uFFFC"), builder.ToString()); EXPECT_EQ(3u, items_.size()); EXPECT_EQ(nullptr, items_[0].Style()); @@ -243,14 +240,14 @@ EXPECT_EQ(nullptr, items_[2].Style()); } -TEST_F(NGLayoutInlineItemsBuilderTest, AppendEmptyString) { +TEST_F(NGInlineItemsBuilderTest, AppendEmptyString) { EXPECT_EQ("", TestAppend("")); EXPECT_EQ(0u, items_.size()); } -TEST_F(NGLayoutInlineItemsBuilderTest, Empty) { - Vector<NGLayoutInlineItem> items; - NGLayoutInlineItemsBuilder builder(&items); +TEST_F(NGInlineItemsBuilderTest, Empty) { + Vector<NGInlineItem> items; + NGInlineItemsBuilder builder(&items); RefPtr<ComputedStyle> block_style(ComputedStyle::Create()); builder.EnterBlock(block_style.Get()); builder.ExitBlock(); @@ -258,9 +255,9 @@ EXPECT_EQ("", builder.ToString()); } -TEST_F(NGLayoutInlineItemsBuilderTest, BidiBlockOverride) { - Vector<NGLayoutInlineItem> items; - NGLayoutInlineItemsBuilder builder(&items); +TEST_F(NGInlineItemsBuilderTest, BidiBlockOverride) { + Vector<NGInlineItem> items; + NGInlineItemsBuilder builder(&items); RefPtr<ComputedStyle> block_style(ComputedStyle::Create()); block_style->SetUnicodeBidi(UnicodeBidi::kBidiOverride); block_style->SetDirection(TextDirection::kRtl); @@ -285,9 +282,9 @@ return node; } -TEST_F(NGLayoutInlineItemsBuilderTest, BidiIsolate) { - Vector<NGLayoutInlineItem> items; - NGLayoutInlineItemsBuilder builder(&items); +TEST_F(NGInlineItemsBuilderTest, BidiIsolate) { + Vector<NGInlineItem> items; + NGInlineItemsBuilder builder(&items); builder.Append("Hello ", style_.Get()); std::unique_ptr<LayoutInline> isolate_rtl( CreateLayoutInline([](ComputedStyle* style) { @@ -309,9 +306,9 @@ builder.ToString()); } -TEST_F(NGLayoutInlineItemsBuilderTest, BidiIsolateOverride) { - Vector<NGLayoutInlineItem> items; - NGLayoutInlineItemsBuilder builder(&items); +TEST_F(NGInlineItemsBuilderTest, BidiIsolateOverride) { + Vector<NGInlineItem> items; + NGInlineItemsBuilder builder(&items); builder.Append("Hello ", style_.Get()); std::unique_ptr<LayoutInline> isolate_override_rtl( CreateLayoutInline([](ComputedStyle* style) {
diff --git a/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_layout_algorithm.cc b/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_layout_algorithm.cc index c81a44a..5e92c1ca 100644 --- a/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_layout_algorithm.cc +++ b/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_layout_algorithm.cc
@@ -124,12 +124,12 @@ void NGInlineLayoutAlgorithm::SetEnd(unsigned new_end_offset) { DCHECK_GT(new_end_offset, end_offset_); - const Vector<NGLayoutInlineItem>& items = Node()->Items(); + const Vector<NGInlineItem>& items = Node()->Items(); DCHECK_LE(new_end_offset, items.back().EndOffset()); // SetEnd() while |new_end_offset| is beyond the current last item. unsigned index = last_index_; - const NGLayoutInlineItem* item = &items[index]; + const NGInlineItem* item = &items[index]; if (new_end_offset > item->EndOffset()) { if (end_offset_ < item->EndOffset()) { SetEnd(index, item->EndOffset(), @@ -148,7 +148,7 @@ // Include closing elements. while (new_end_offset == item->EndOffset() && index < items.size() - 1) { item = &items[++index]; - if (item->Type() != NGLayoutInlineItem::kCloseTag) + if (item->Type() != NGInlineItem::kCloseTag) break; SetEnd(index, new_end_offset, InlineSize(*item)); } @@ -157,7 +157,7 @@ void NGInlineLayoutAlgorithm::SetEnd(unsigned index, unsigned new_end_offset, LayoutUnit inline_size_since_current_end) { - const Vector<NGLayoutInlineItem>& items = Node()->Items(); + const Vector<NGInlineItem>& items = Node()->Items(); DCHECK_LE(new_end_offset, items.back().EndOffset()); // |new_end_offset| should be in the current item or next. @@ -165,10 +165,10 @@ DCHECK((index == last_index_ && new_end_offset > end_offset_) || (index == last_index_ + 1 && new_end_offset >= end_offset_ && end_offset_ == items[last_index_].EndOffset())); - const NGLayoutInlineItem& item = items[index]; + const NGInlineItem& item = items[index]; item.AssertEndOffset(new_end_offset); - if (item.Type() == NGLayoutInlineItem::kFloating) { + if (item.Type() == NGInlineItem::kFloating) { LayoutAndPositionFloat( LayoutUnit(end_position_) + inline_size_since_current_end, item.GetLayoutObject()); @@ -189,13 +189,13 @@ // TODO(kojii): Implement. } -LayoutUnit NGInlineLayoutAlgorithm::InlineSize(const NGLayoutInlineItem& item) { - if (item.Type() == NGLayoutInlineItem::kAtomicInline) +LayoutUnit NGInlineLayoutAlgorithm::InlineSize(const NGInlineItem& item) { + if (item.Type() == NGInlineItem::kAtomicInline) return InlineSizeFromLayout(item); return item.InlineSize(); } -LayoutUnit NGInlineLayoutAlgorithm::InlineSize(const NGLayoutInlineItem& item, +LayoutUnit NGInlineLayoutAlgorithm::InlineSize(const NGInlineItem& item, unsigned start_offset, unsigned end_offset) { if (item.StartOffset() == start_offset && item.EndOffset() == end_offset) @@ -204,7 +204,7 @@ } LayoutUnit NGInlineLayoutAlgorithm::InlineSizeFromLayout( - const NGLayoutInlineItem& item) { + const NGInlineItem& item) { return NGBoxFragment(ConstraintSpace().WritingMode(), ToNGPhysicalBoxFragment( LayoutItem(item)->PhysicalFragment().Get())) @@ -212,9 +212,9 @@ } const NGLayoutResult* NGInlineLayoutAlgorithm::LayoutItem( - const NGLayoutInlineItem& item) { + const NGInlineItem& item) { // Returns the cached NGLayoutResult if available. - const Vector<NGLayoutInlineItem>& items = Node()->Items(); + const Vector<NGInlineItem>& items = Node()->Items(); if (layout_results_.IsEmpty()) layout_results_.Resize(items.size()); unsigned index = std::distance(items.begin(), &item); @@ -222,9 +222,9 @@ if (*layout_result) return layout_result->Get(); - DCHECK_EQ(item.Type(), NGLayoutInlineItem::kAtomicInline); + DCHECK_EQ(item.Type(), NGInlineItem::kAtomicInline); NGBlockNode* node = new NGBlockNode(item.GetLayoutObject()); - // TODO(kojii): Keep node in NGLayoutInlineItem. + // TODO(kojii): Keep node in NGInlineItem. const ComputedStyle& style = node->Style(); NGConstraintSpaceBuilder constraint_space_builder(&ConstraintSpace()); RefPtr<NGConstraintSpace> constraint_space = @@ -243,7 +243,7 @@ } bool NGInlineLayoutAlgorithm::CreateLineUpToLastBreakOpportunity() { - const Vector<NGLayoutInlineItem>& items = Node()->Items(); + const Vector<NGInlineItem>& items = Node()->Items(); // Create a list of LineItemChunk from |start| and |last_break_opportunity|. // TODO(kojii): Consider refactoring LineItemChunk once NGLineBuilder's public @@ -251,7 +251,7 @@ Vector<LineItemChunk, 32> line_item_chunks; unsigned start_offset = start_offset_; for (unsigned i = start_index_; i <= last_break_opportunity_index_; i++) { - const NGLayoutInlineItem& item = items[i]; + const NGInlineItem& item = items[i]; unsigned end_offset = std::min(item.EndOffset(), last_break_opportunity_offset_); line_item_chunks.push_back( @@ -309,7 +309,7 @@ // runs instead of characters. Vector<UBiDiLevel, 32> levels; levels.ReserveInitialCapacity(line_item_chunks->size()); - const Vector<NGLayoutInlineItem>& items = Node()->Items(); + const Vector<NGInlineItem>& items = Node()->Items(); for (const auto& chunk : *line_item_chunks) levels.push_back(items[chunk.index].BidiLevel()); Vector<int32_t, 32> indices_in_visual_order(line_item_chunks->size()); @@ -329,13 +329,13 @@ HashMap<LayoutObject*, unsigned> first_index; for (unsigned i = 0; i < line_item_chunks_in_visual_order.size(); i++) { LineItemChunk& chunk = line_item_chunks_in_visual_order[i]; - const NGLayoutInlineItem& item = items[chunk.index]; - if (item.Type() != NGLayoutInlineItem::kOpenTag && - item.Type() != NGLayoutInlineItem::kCloseTag) { + const NGInlineItem& item = items[chunk.index]; + if (item.Type() != NGInlineItem::kOpenTag && + item.Type() != NGInlineItem::kCloseTag) { continue; } auto result = first_index.insert(item.GetLayoutObject(), i); - if (!result.is_new_entry && item.Type() == NGLayoutInlineItem::kOpenTag) { + if (!result.is_new_entry && item.Type() == NGInlineItem::kOpenTag) { std::swap(line_item_chunks_in_visual_order[i], line_item_chunks_in_visual_order[result.stored_value->value]); } @@ -392,7 +392,7 @@ bool NGInlineLayoutAlgorithm::PlaceItems( const Vector<LineItemChunk, 32>& line_item_chunks) { - const Vector<NGLayoutInlineItem>& items = Node()->Items(); + const Vector<NGInlineItem>& items = Node()->Items(); // Use a "strut" (a zero-width inline box with the element's font and // line height properties) as the initial metrics for the line box. @@ -409,9 +409,9 @@ NGInlineBoxState* box = box_states_.OnBeginPlaceItems(&LineStyle()); LayoutUnit inline_size; for (const auto& line_item_chunk : line_item_chunks) { - const NGLayoutInlineItem& item = items[line_item_chunk.index]; + const NGInlineItem& item = items[line_item_chunk.index]; LayoutUnit line_top; - if (item.Type() == NGLayoutInlineItem::kText) { + if (item.Type() == NGInlineItem::kText) { DCHECK(item.GetLayoutObject()->IsText()); if (box->text_metrics.IsEmpty()) box->ComputeTextMetrics(item, baseline_type_); @@ -421,15 +421,15 @@ // Take all used fonts into account if 'line-height: normal'. if (box->include_used_fonts) AccumulateUsedFonts(item, line_item_chunk, &line_box); - } else if (item.Type() == NGLayoutInlineItem::kOpenTag) { + } else if (item.Type() == NGInlineItem::kOpenTag) { box = box_states_.OnOpenTag(item, &line_box, &text_builder); continue; - } else if (item.Type() == NGLayoutInlineItem::kCloseTag) { + } else if (item.Type() == NGInlineItem::kCloseTag) { box = box_states_.OnCloseTag(item, &line_box, box); continue; - } else if (item.Type() == NGLayoutInlineItem::kAtomicInline) { + } else if (item.Type() == NGInlineItem::kAtomicInline) { line_top = PlaceAtomicInline(item, &line_box, box, &text_builder); - } else if (item.Type() == NGLayoutInlineItem::kOutOfFlowPositioned) { + } else if (item.Type() == NGInlineItem::kOutOfFlowPositioned) { // TODO(layout-dev): Report the correct static position for the out of // flow descendant. We can't do this here yet as it doesn't know the // size of the line box. @@ -500,7 +500,7 @@ } void NGInlineLayoutAlgorithm::AccumulateUsedFonts( - const NGLayoutInlineItem& item, + const NGInlineItem& item, const LineItemChunk& line_item_chunk, NGLineBoxFragmentBuilder* line_box) { HashSet<const SimpleFontData*> fallback_fonts; @@ -515,7 +515,7 @@ } LayoutUnit NGInlineLayoutAlgorithm::PlaceAtomicInline( - const NGLayoutInlineItem& item, + const NGInlineItem& item, NGLineBoxFragmentBuilder* line_box, NGInlineBoxState* state, NGTextFragmentBuilder* text_builder) {
diff --git a/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_layout_algorithm.h b/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_layout_algorithm.h index 5639fc9..2f9b4f2 100644 --- a/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_layout_algorithm.h +++ b/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_layout_algorithm.h
@@ -22,7 +22,7 @@ class NGConstraintSpace; class NGInlineBreakToken; class NGInlineNode; -class NGLayoutInlineItem; +class NGInlineItem; class NGLineBoxFragmentBuilder; class NGTextFragmentBuilder; @@ -91,10 +91,10 @@ // part of layout operations and modifies the state of |this|. MinMaxContentSize ComputeMinMaxContentSizeByLayout(); - // Compute inline size of an NGLayoutInlineItem. - // Same as NGLayoutInlineItem::InlineSize(), except that this function can - // compute atomic inlines by performing layout. - LayoutUnit InlineSize(const NGLayoutInlineItem&); + // Compute inline size of an NGInlineItem. + // Same as NGInlineItem::InlineSize(), except that this function can compute + // atomic inlines by performing layout. + LayoutUnit InlineSize(const NGInlineItem&); private: bool IsHorizontalWritingMode() const { return is_horizontal_writing_mode_; } @@ -107,11 +107,11 @@ // This empties the current line. void Initialize(unsigned index, unsigned offset); - LayoutUnit InlineSize(const NGLayoutInlineItem&, + LayoutUnit InlineSize(const NGInlineItem&, unsigned start_offset, unsigned end_offset); - LayoutUnit InlineSizeFromLayout(const NGLayoutInlineItem&); - const NGLayoutResult* LayoutItem(const NGLayoutInlineItem&); + LayoutUnit InlineSizeFromLayout(const NGInlineItem&); + const NGLayoutResult* LayoutItem(const NGInlineItem&); struct LineItemChunk { unsigned index; @@ -131,10 +131,10 @@ void LayoutAndPositionFloat(LayoutUnit end_position, LayoutObject*); bool PlaceItems(const Vector<LineItemChunk, 32>&); - void AccumulateUsedFonts(const NGLayoutInlineItem&, + void AccumulateUsedFonts(const NGInlineItem&, const LineItemChunk&, NGLineBoxFragmentBuilder*); - LayoutUnit PlaceAtomicInline(const NGLayoutInlineItem&, + LayoutUnit PlaceAtomicInline(const NGInlineItem&, NGLineBoxFragmentBuilder*, NGInlineBoxState*, NGTextFragmentBuilder*);
diff --git a/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_node.cc b/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_node.cc index 8cd19d8..907ee827 100644 --- a/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_node.cc +++ b/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_node.cc
@@ -12,8 +12,9 @@ #include "core/layout/line/RootInlineBox.h" #include "core/layout/ng/inline/ng_bidi_paragraph.h" #include "core/layout/ng/inline/ng_inline_break_token.h" +#include "core/layout/ng/inline/ng_inline_item.h" +#include "core/layout/ng/inline/ng_inline_items_builder.h" #include "core/layout/ng/inline/ng_inline_layout_algorithm.h" -#include "core/layout/ng/inline/ng_layout_inline_items_builder.h" #include "core/layout/ng/inline/ng_line_box_fragment.h" #include "core/layout/ng/inline/ng_physical_line_box_fragment.h" #include "core/layout/ng/inline/ng_physical_text_fragment.h" @@ -23,11 +24,7 @@ #include "core/layout/ng/ng_fragment_builder.h" #include "core/layout/ng/ng_physical_box_fragment.h" #include "core/style/ComputedStyle.h" -#include "platform/fonts/CharacterRange.h" -#include "platform/fonts/shaping/CachingWordShapeIterator.h" -#include "platform/fonts/shaping/CachingWordShaper.h" #include "platform/fonts/shaping/HarfBuzzShaper.h" -#include "platform/fonts/shaping/ShapeResultBuffer.h" #include "platform/wtf/text/CharacterNames.h" namespace blink { @@ -47,8 +44,8 @@ NGInlineNode::~NGInlineNode() {} -NGLayoutInlineItemRange NGInlineNode::Items(unsigned start, unsigned end) { - return NGLayoutInlineItemRange(&items_, start, end); +NGInlineItemRange NGInlineNode::Items(unsigned start, unsigned end) { + return NGInlineItemRange(&items_, start, end); } void NGInlineNode::InvalidatePrepareLayout() { @@ -72,7 +69,7 @@ void NGInlineNode::CollectInlines(LayoutObject* start, LayoutBlockFlow* block) { DCHECK(text_content_.IsNull()); DCHECK(items_.IsEmpty()); - NGLayoutInlineItemsBuilder builder(&items_); + NGInlineItemsBuilder builder(&items_); builder.EnterBlock(block->Style()); LayoutObject* next_sibling = CollectInlines(start, block, &builder); builder.ExitBlock(); @@ -84,10 +81,9 @@ !(text_content_.Is8Bit() && !builder.HasBidiControls()); } -LayoutObject* NGInlineNode::CollectInlines( - LayoutObject* start, - LayoutBlockFlow* block, - NGLayoutInlineItemsBuilder* builder) { +LayoutObject* NGInlineNode::CollectInlines(LayoutObject* start, + LayoutBlockFlow* block, + NGInlineItemsBuilder* builder) { LayoutObject* node = start; while (node) { if (node->IsText()) { @@ -99,10 +95,10 @@ // Add floats and positioned objects in the same way as atomic inlines. // Because these objects need positions, they will be handled in // NGInlineLayoutAlgorithm. - builder->Append(NGLayoutInlineItem::kFloating, - kObjectReplacementCharacter, nullptr, node); + builder->Append(NGInlineItem::kFloating, kObjectReplacementCharacter, + nullptr, node); } else if (node->IsOutOfFlowPositioned()) { - builder->Append(NGLayoutInlineItem::kOutOfFlowPositioned, + builder->Append(NGInlineItem::kOutOfFlowPositioned, kObjectReplacementCharacter, nullptr, node); } else if (!node->IsInline()) { @@ -115,7 +111,7 @@ // For atomic inlines add a unicode "object replacement character" to // signal the presence of a non-text object to the unicode bidi algorithm. if (node->IsAtomicInlineLevel()) { - builder->Append(NGLayoutInlineItem::kAtomicInline, + builder->Append(NGInlineItem::kAtomicInline, kObjectReplacementCharacter, nullptr, node); } @@ -169,109 +165,12 @@ UBiDiLevel level; unsigned end = bidi.GetLogicalRun(start, &level); DCHECK_EQ(items_[item_index].start_offset_, start); - item_index = - NGLayoutInlineItem::SetBidiLevel(items_, item_index, end, level); + item_index = NGInlineItem::SetBidiLevel(items_, item_index, end, level); start = end; } DCHECK_EQ(item_index, items_.size()); } -// Set bidi level to a list of NGLayoutInlineItem from |index| to the item that -// ends with |end_offset|. -// If |end_offset| is mid of an item, the item is split to ensure each item has -// one bidi level. -// @param items The list of NGLayoutInlineItem. -// @param index The first index of the list to set. -// @param end_offset The exclusive end offset to set. -// @param level The level to set. -// @return The index of the next item. -unsigned NGLayoutInlineItem::SetBidiLevel(Vector<NGLayoutInlineItem>& items, - unsigned index, - unsigned end_offset, - UBiDiLevel level) { - for (; items[index].end_offset_ < end_offset; index++) - items[index].bidi_level_ = level; - items[index].bidi_level_ = level; - - if (items[index].end_offset_ == end_offset) { - // Let close items have the same bidi-level as the previous item. - while (index + 1 < items.size() && - items[index + 1].Type() == NGLayoutInlineItem::kCloseTag) { - items[++index].bidi_level_ = level; - } - } else { - Split(items, index, end_offset); - } - - return index + 1; -} - -// Split |items[index]| to 2 items at |offset|. -// All properties other than offsets are copied to the new item and it is -// inserted at |items[index + 1]|. -// @param items The list of NGLayoutInlineItem. -// @param index The index to split. -// @param offset The offset to split at. -void NGLayoutInlineItem::Split(Vector<NGLayoutInlineItem>& items, - unsigned index, - unsigned offset) { - DCHECK_GT(offset, items[index].start_offset_); - DCHECK_LT(offset, items[index].end_offset_); - items.insert(index + 1, items[index]); - items[index].end_offset_ = offset; - items[index + 1].start_offset_ = offset; -} - -void NGLayoutInlineItem::SetOffset(unsigned start, unsigned end) { - DCHECK_GE(end, start); - start_offset_ = start; - end_offset_ = end; -} - -void NGLayoutInlineItem::SetEndOffset(unsigned end_offset) { - DCHECK_GE(end_offset, start_offset_); - end_offset_ = end_offset; -} - -LayoutUnit NGLayoutInlineItem::InlineSize() const { - if (Type() == NGLayoutInlineItem::kText) - return LayoutUnit(shape_result_->Width()); - - DCHECK_NE(Type(), NGLayoutInlineItem::kAtomicInline) - << "Use NGInlineLayoutAlgorithm::InlineSize"; - // Bidi controls and out-of-flow objects do not have in-flow widths. - return LayoutUnit(); -} - -LayoutUnit NGLayoutInlineItem::InlineSize(unsigned start, unsigned end) const { - DCHECK_GE(start, StartOffset()); - DCHECK_LE(start, end); - DCHECK_LE(end, EndOffset()); - - if (start == end) - return LayoutUnit(); - if (start == start_offset_ && end == end_offset_) - return InlineSize(); - - DCHECK_EQ(Type(), NGLayoutInlineItem::kText); - return LayoutUnit(ShapeResultBuffer::GetCharacterRange( - shape_result_, Direction(), shape_result_->Width(), - start - StartOffset(), end - StartOffset()) - .Width()); -} - -void NGLayoutInlineItem::GetFallbackFonts( - HashSet<const SimpleFontData*>* fallback_fonts, - unsigned start, - unsigned end) const { - DCHECK_GE(start, StartOffset()); - DCHECK_LE(start, end); - DCHECK_LE(end, EndOffset()); - - // TODO(kojii): Implement |start| and |end|. - shape_result_->FallbackFonts(fallback_fonts); -} - void NGInlineNode::ShapeText() { // TODO(eae): Add support for shaping latin-1 text? text_content_.Ensure16Bit(); @@ -279,7 +178,7 @@ // Shape each item with the full context of the entire node. HarfBuzzShaper shaper(text_content_.Characters16(), text_content_.length()); for (auto& item : items_) { - if (item.Type() != NGLayoutInlineItem::kText) + if (item.Type() != NGInlineItem::kText) continue; item.shape_result_ = @@ -335,7 +234,7 @@ LayoutBlockFlow* block_flow = GetLayoutBlockFlow(); block_flow->DeleteLineBoxTree(); - Vector<NGLayoutInlineItem>& items = Items(); + Vector<NGInlineItem>& items = Items(); Vector<unsigned, 32> text_offsets(items.size()); GetLayoutTextOffsets(&text_offsets); @@ -356,9 +255,9 @@ // Create a BidiRunList for this line. for (const auto& line_child : physical_line_box->Children()) { const auto* text_fragment = ToNGPhysicalTextFragment(line_child.Get()); - const NGLayoutInlineItem& item = items[text_fragment->ItemIndex()]; + const NGInlineItem& item = items[text_fragment->ItemIndex()]; BidiRun* run; - if (item.Type() == NGLayoutInlineItem::kText) { + if (item.Type() == NGInlineItem::kText) { LayoutObject* layout_object = item.GetLayoutObject(); DCHECK(layout_object->IsText()); unsigned text_offset = text_offsets[text_fragment->ItemIndex()]; @@ -366,7 +265,7 @@ text_fragment->EndOffset() - text_offset, item.BidiLevel(), LineLayoutItem(layout_object)); layout_object->ClearNeedsLayout(); - } else if (item.Type() == NGLayoutInlineItem::kAtomicInline) { + } else if (item.Type() == NGInlineItem::kAtomicInline) { LayoutObject* layout_object = item.GetLayoutObject(); DCHECK(layout_object->IsAtomicInlineLevel()); run = @@ -437,7 +336,7 @@ LayoutText* current_text = nullptr; unsigned current_offset = 0; for (unsigned i = 0; i < items_.size(); i++) { - const NGLayoutInlineItem& item = items_[i]; + const NGInlineItem& item = items_[i]; LayoutObject* next_object = item.GetLayoutObject(); LayoutText* next_text = next_object && next_object->IsText() ? ToLayoutText(next_object) @@ -465,15 +364,4 @@ NGLayoutInputNode::Trace(visitor); } -NGLayoutInlineItemRange::NGLayoutInlineItemRange( - Vector<NGLayoutInlineItem>* items, - unsigned start_index, - unsigned end_index) - : start_item_(&(*items)[start_index]), - size_(end_index - start_index), - start_index_(start_index) { - CHECK_LE(start_index, end_index); - CHECK_LE(end_index, items->size()); -} - } // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_node.h b/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_node.h index 4e7ac3b3..366aeda 100644 --- a/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_node.h +++ b/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_node.h
@@ -7,27 +7,21 @@ #include "core/CoreExport.h" #include "core/layout/LayoutBlockFlow.h" +#include "core/layout/ng/inline/ng_inline_item.h" #include "core/layout/ng/ng_layout_input_node.h" -#include "platform/fonts/FontFallbackPriority.h" -#include "platform/fonts/shaping/ShapeResult.h" #include "platform/heap/Handle.h" -#include "platform/text/TextDirection.h" #include "platform/wtf/text/WTFString.h" -#include <unicode/ubidi.h> -#include <unicode/uscript.h> - namespace blink { class ComputedStyle; class LayoutBlockFlow; class LayoutObject; -class LayoutUnit; struct MinMaxContentSize; class NGConstraintSpace; -class NGLayoutInlineItem; -class NGLayoutInlineItemRange; -class NGLayoutInlineItemsBuilder; +class NGInlineItem; +class NGInlineItemRange; +class NGInlineItemsBuilder; class NGLayoutResult; // Represents an anonymous block box to be laid out, that contains consecutive @@ -60,9 +54,9 @@ return StringView(text_content_, start_offset, end_offset - start_offset); } - Vector<NGLayoutInlineItem>& Items() { return items_; } - const Vector<NGLayoutInlineItem>& Items() const { return items_; } - NGLayoutInlineItemRange Items(unsigned start_index, unsigned end_index); + Vector<NGInlineItem>& Items() { return items_; } + const Vector<NGInlineItem>& Items() const { return items_; } + NGInlineItemRange Items(unsigned start_index, unsigned end_index); void GetLayoutTextOffsets(Vector<unsigned, 32>*); @@ -84,7 +78,7 @@ void CollectInlines(LayoutObject* start, LayoutBlockFlow*); LayoutObject* CollectInlines(LayoutObject* start, LayoutBlockFlow*, - NGLayoutInlineItemsBuilder*); + NGInlineItemsBuilder*); void SegmentText(); void ShapeText(); @@ -95,127 +89,13 @@ // Text content for all inline items represented by a single NGInlineNode // instance. Encoded either as UTF-16 or latin-1 depending on content. String text_content_; - Vector<NGLayoutInlineItem> items_; + Vector<NGInlineItem> items_; // TODO(kojii): This should move to somewhere else when we move PrepareLayout // to the correct place. bool is_bidi_enabled_ = false; }; -// Class representing a single text node or styled inline element with text -// content segmented by style, text direction, sideways rotation, font fallback -// priority (text, symbol, emoji, etc) and script (but not by font). -// In this representation TextNodes are merged up into their parent inline -// element where possible. -class NGLayoutInlineItem { - public: - enum NGLayoutInlineItemType { - kText, - kAtomicInline, - kOpenTag, - kCloseTag, - kFloating, - kOutOfFlowPositioned, - kBidiControl - // When adding new values, make sure the bit size of |type_| is large - // enough to store. - }; - - // Whether pre- and post-context should be used for shaping. - enum NGLayoutInlineShapeOptions { - kNoContext = 0, - kPreContext = 1, - kPostContext = 2 - }; - - NGLayoutInlineItem(NGLayoutInlineItemType type, - unsigned start, - unsigned end, - const ComputedStyle* style = nullptr, - LayoutObject* layout_object = nullptr) - : start_offset_(start), - end_offset_(end), - script_(USCRIPT_INVALID_CODE), - style_(style), - layout_object_(layout_object), - type_(type), - bidi_level_(UBIDI_LTR), - shape_options_(kPreContext | kPostContext), - rotate_sideways_(false), - fallback_priority_(FontFallbackPriority::kInvalid) { - DCHECK_GE(end, start); - } - - NGLayoutInlineItemType Type() const { - return static_cast<NGLayoutInlineItemType>(type_); - } - - NGLayoutInlineShapeOptions ShapeOptions() const { - return static_cast<NGLayoutInlineShapeOptions>(shape_options_); - } - - unsigned StartOffset() const { return start_offset_; } - unsigned EndOffset() const { return end_offset_; } - unsigned Length() const { return end_offset_ - start_offset_; } - TextDirection Direction() const { - return BidiLevel() & 1 ? TextDirection::kRtl : TextDirection::kLtr; - } - UBiDiLevel BidiLevel() const { return static_cast<UBiDiLevel>(bidi_level_); } - UScriptCode GetScript() const { return script_; } - const ComputedStyle* Style() const { return style_; } - LayoutObject* GetLayoutObject() const { return layout_object_; } - - void SetOffset(unsigned start, unsigned end); - void SetEndOffset(unsigned); - - LayoutUnit InlineSize() const; - LayoutUnit InlineSize(unsigned start, unsigned end) const; - - void GetFallbackFonts(HashSet<const SimpleFontData*>*, - unsigned start, - unsigned end) const; - - static void Split(Vector<NGLayoutInlineItem>&, - unsigned index, - unsigned offset); - static unsigned SetBidiLevel(Vector<NGLayoutInlineItem>&, - unsigned index, - unsigned end_offset, - UBiDiLevel); - - void AssertOffset(unsigned offset) const; - void AssertEndOffset(unsigned offset) const; - - private: - unsigned start_offset_; - unsigned end_offset_; - UScriptCode script_; - RefPtr<const ShapeResult> shape_result_; - const ComputedStyle* style_; - LayoutObject* layout_object_; - - unsigned type_ : 3; - unsigned bidi_level_ : 8; // UBiDiLevel is defined as uint8_t. - unsigned shape_options_ : 2; - unsigned rotate_sideways_ : 1; - - // TODO(layout-ng): Do we need fallback_priority_ here? If so we should pack - // it with the bit field above. - FontFallbackPriority fallback_priority_; - - friend class NGInlineNode; -}; - -inline void NGLayoutInlineItem::AssertOffset(unsigned offset) const { - DCHECK((offset >= start_offset_ && offset < end_offset_) || - (offset == start_offset_ && start_offset_ == end_offset_)); -} - -inline void NGLayoutInlineItem::AssertEndOffset(unsigned offset) const { - DCHECK_GE(offset, start_offset_); - DCHECK_LE(offset, end_offset_); -} - inline void NGInlineNode::AssertOffset(unsigned index, unsigned offset) const { items_[index].AssertOffset(offset); } @@ -231,44 +111,6 @@ node->IsInline(), node.IsInline()); -// A vector-like object that points to a subset of an array of -// |NGLayoutInlineItem|. -// The source vector must keep alive and must not resize while this object -// is alive. -class NGLayoutInlineItemRange { - STACK_ALLOCATED(); - - public: - NGLayoutInlineItemRange(Vector<NGLayoutInlineItem>*, - unsigned start_index, - unsigned end_index); - - unsigned StartIndex() const { return start_index_; } - unsigned EndIndex() const { return start_index_ + size_; } - unsigned Size() const { return size_; } - - NGLayoutInlineItem& operator[](unsigned index) { - CHECK_LT(index, size_); - return start_item_[index]; - } - const NGLayoutInlineItem& operator[](unsigned index) const { - CHECK_LT(index, size_); - return start_item_[index]; - } - - using iterator = NGLayoutInlineItem*; - using const_iterator = const NGLayoutInlineItem*; - iterator begin() { return start_item_; } - iterator end() { return start_item_ + size_; } - const_iterator begin() const { return start_item_; } - const_iterator end() const { return start_item_ + size_; } - - private: - NGLayoutInlineItem* start_item_; - unsigned size_; - unsigned start_index_; -}; - } // namespace blink #endif // NGInlineNode_h
diff --git a/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_node_test.cc b/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_node_test.cc index dd482de7..13e6616 100644 --- a/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_node_test.cc +++ b/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_node_test.cc
@@ -23,23 +23,22 @@ using NGInlineNode::NGInlineNode; String& Text() { return text_content_; } - Vector<NGLayoutInlineItem>& Items() { return items_; } + Vector<NGInlineItem>& Items() { return items_; } void Append(const String& text, const ComputedStyle* style = nullptr, LayoutObject* layout_object = nullptr) { unsigned start = text_content_.length(); text_content_.Append(text); - items_.push_back(NGLayoutInlineItem(NGLayoutInlineItem::kText, start, - start + text.length(), style, - layout_object)); + items_.push_back(NGInlineItem(NGInlineItem::kText, start, + start + text.length(), style, layout_object)); } void Append(UChar character) { text_content_.Append(character); unsigned end = text_content_.length(); - items_.push_back(NGLayoutInlineItem(NGLayoutInlineItem::kBidiControl, - end - 1, end, nullptr)); + items_.push_back( + NGInlineItem(NGInlineItem::kBidiControl, end - 1, end, nullptr)); is_bidi_enabled_ = true; } @@ -110,12 +109,12 @@ }; #define TEST_ITEM_TYPE_OFFSET(item, type, start, end) \ - EXPECT_EQ(NGLayoutInlineItem::type, item.Type()); \ + EXPECT_EQ(NGInlineItem::type, item.Type()); \ EXPECT_EQ(start, item.StartOffset()); \ EXPECT_EQ(end, item.EndOffset()) #define TEST_ITEM_TYPE_OFFSET_LEVEL(item, type, start, end, level) \ - EXPECT_EQ(NGLayoutInlineItem::type, item.Type()); \ + EXPECT_EQ(NGInlineItem::type, item.Type()); \ EXPECT_EQ(start, item.StartOffset()); \ EXPECT_EQ(end, item.EndOffset()); \ EXPECT_EQ(level, item.BidiLevel()) @@ -129,7 +128,7 @@ SetupHtml("t", "<div id=t>Hello <span>inline</span> world.</div>"); NGInlineNodeForTest* node = CreateInlineNode(); node->CollectInlines(layout_object_, layout_block_flow_); - Vector<NGLayoutInlineItem>& items = node->Items(); + Vector<NGInlineItem>& items = node->Items(); TEST_ITEM_TYPE_OFFSET(items[0], kText, 0u, 6u); TEST_ITEM_TYPE_OFFSET(items[1], kOpenTag, 6u, 6u); TEST_ITEM_TYPE_OFFSET(items[2], kText, 6u, 12u); @@ -145,7 +144,7 @@ EXPECT_TRUE(node->IsBidiEnabled()); node->SegmentText(); EXPECT_TRUE(node->IsBidiEnabled()); - Vector<NGLayoutInlineItem>& items = node->Items(); + Vector<NGInlineItem>& items = node->Items(); TEST_ITEM_TYPE_OFFSET_LEVEL(items[0], kText, 0u, 2u, 1u); TEST_ITEM_TYPE_OFFSET_LEVEL(items[1], kOpenTag, 2u, 2u, 1u); TEST_ITEM_TYPE_OFFSET_LEVEL(items[2], kText, 2u, 3u, 1u); @@ -161,7 +160,7 @@ EXPECT_TRUE(node->IsBidiEnabled()); node->SegmentText(); EXPECT_TRUE(node->IsBidiEnabled()); - Vector<NGLayoutInlineItem>& items = node->Items(); + Vector<NGInlineItem>& items = node->Items(); TEST_ITEM_TYPE_OFFSET_LEVEL(items[0], kText, 0u, 7u, 0u); TEST_ITEM_TYPE_OFFSET_LEVEL(items[1], kText, 7u, 9u, 1u); TEST_ITEM_TYPE_OFFSET_LEVEL(items[2], kOpenTag, 9u, 9u, 1u); @@ -177,7 +176,7 @@ EXPECT_TRUE(node->IsBidiEnabled()); node->SegmentText(); EXPECT_TRUE(node->IsBidiEnabled()); - Vector<NGLayoutInlineItem>& items = node->Items(); + Vector<NGInlineItem>& items = node->Items(); TEST_ITEM_TYPE_OFFSET_LEVEL(items[0], kText, 0u, 7u, 0u); TEST_ITEM_TYPE_OFFSET_LEVEL(items[1], kText, 7u, 9u, 1u); TEST_ITEM_TYPE_OFFSET_LEVEL(items[2], kOpenTag, 9u, 9u, 1u); @@ -191,7 +190,7 @@ NGInlineNodeForTest* node = CreateInlineNode(); node->Append("Hello"); node->SegmentText(); - Vector<NGLayoutInlineItem>& items = node->Items(); + Vector<NGInlineItem>& items = node->Items(); ASSERT_EQ(1u, items.size()); TEST_ITEM_OFFSET_DIR(items[0], 0u, 5u, TextDirection::kLtr); } @@ -201,7 +200,7 @@ node->Append(u"\u05E2\u05D1\u05E8\u05D9\u05EA"); node->SegmentText(); ASSERT_EQ(1u, node->Items().size()); - Vector<NGLayoutInlineItem>& items = node->Items(); + Vector<NGInlineItem>& items = node->Items(); ASSERT_EQ(1u, items.size()); TEST_ITEM_OFFSET_DIR(items[0], 0u, 5u, TextDirection::kRtl); } @@ -211,7 +210,7 @@ node->Append(u"Hello \u05E2\u05D1\u05E8\u05D9\u05EA"); node->SegmentText(); ASSERT_EQ(2u, node->Items().size()); - Vector<NGLayoutInlineItem>& items = node->Items(); + Vector<NGInlineItem>& items = node->Items(); ASSERT_EQ(2u, items.size()); TEST_ITEM_OFFSET_DIR(items[0], 0u, 6u, TextDirection::kLtr); TEST_ITEM_OFFSET_DIR(items[1], 6u, 11u, TextDirection::kRtl); @@ -223,7 +222,7 @@ node->Append(u"lo \u05E2"); node->Append(u"\u05D1\u05E8\u05D9\u05EA"); node->SegmentText(); - Vector<NGLayoutInlineItem>& items = node->Items(); + Vector<NGInlineItem>& items = node->Items(); ASSERT_EQ(4u, items.size()); TEST_ITEM_OFFSET_DIR(items[0], 0u, 3u, TextDirection::kLtr); TEST_ITEM_OFFSET_DIR(items[1], 3u, 6u, TextDirection::kLtr); @@ -238,7 +237,7 @@ node->Append("ABC"); node->Append(kPopDirectionalFormattingCharacter); node->SegmentText(); - Vector<NGLayoutInlineItem>& items = node->Items(); + Vector<NGInlineItem>& items = node->Items(); ASSERT_EQ(4u, items.size()); TEST_ITEM_OFFSET_DIR(items[0], 0u, 6u, TextDirection::kLtr); TEST_ITEM_OFFSET_DIR(items[1], 6u, 7u, TextDirection::kRtl); @@ -265,7 +264,7 @@ TEST_F(NGInlineNodeTest, SegmentBidiIsolate) { NGInlineNodeForTest* node = CreateBidiIsolateNode(CreateInlineNode(), style_.Get(), layout_object_); - Vector<NGLayoutInlineItem>& items = node->Items(); + Vector<NGInlineItem>& items = node->Items(); ASSERT_EQ(9u, items.size()); TEST_ITEM_OFFSET_DIR(items[0], 0u, 6u, TextDirection::kLtr); TEST_ITEM_OFFSET_DIR(items[1], 6u, 7u, TextDirection::kLtr);
diff --git a/third_party/WebKit/Source/core/offscreencanvas/OffscreenCanvas.cpp b/third_party/WebKit/Source/core/offscreencanvas/OffscreenCanvas.cpp index 20b98d6..5f641a1 100644 --- a/third_party/WebKit/Source/core/offscreencanvas/OffscreenCanvas.cpp +++ b/third_party/WebKit/Source/core/offscreencanvas/OffscreenCanvas.cpp
@@ -36,7 +36,7 @@ void OffscreenCanvas::Dispose() { if (context_) { - context_->DetachOffscreenCanvas(); + context_->DetachHost(); context_ = nullptr; } if (commit_promise_resolver_) { @@ -238,7 +238,17 @@ ScriptPromise OffscreenCanvas::Commit(RefPtr<StaticBitmapImage> image, bool is_web_gl_software_rendering, - ScriptState* script_state) { + ScriptState* script_state, + ExceptionState& exception_state) { + if (!HasPlaceholderCanvas()) { + exception_state.ThrowDOMException( + kInvalidStateError, + "Commit() was called on a context whose " + "OffscreenCanvas is not associated with a " + "canvas element."); + return exception_state.Reject(script_state); + } + GetOrCreateFrameDispatcher()->SetNeedsBeginFrame(true); if (!commit_promise_resolver_) {
diff --git a/third_party/WebKit/Source/core/offscreencanvas/OffscreenCanvas.h b/third_party/WebKit/Source/core/offscreencanvas/OffscreenCanvas.h index 810045a7..5f9cf10 100644 --- a/third_party/WebKit/Source/core/offscreencanvas/OffscreenCanvas.h +++ b/third_party/WebKit/Source/core/offscreencanvas/OffscreenCanvas.h
@@ -5,17 +5,18 @@ #ifndef OffscreenCanvas_h #define OffscreenCanvas_h +#include <memory> #include "bindings/core/v8/ScriptPromise.h" #include "bindings/core/v8/ScriptState.h" #include "bindings/core/v8/ScriptWrappable.h" #include "core/events/EventTarget.h" #include "core/html/HTMLCanvasElement.h" #include "core/html/canvas/CanvasImageSource.h" +#include "core/html/canvas/CanvasRenderingContextHost.h" #include "core/offscreencanvas/ImageEncodeOptions.h" #include "platform/geometry/IntSize.h" #include "platform/graphics/OffscreenCanvasFrameDispatcher.h" #include "platform/heap/Handle.h" -#include <memory> namespace blink { @@ -30,8 +31,10 @@ : public EventTargetWithInlineData, public CanvasImageSource, public ImageBitmapSource, + public CanvasRenderingContextHost, public OffscreenCanvasFrameDispatcherClient { DEFINE_WRAPPERTYPEINFO(); + USING_GARBAGE_COLLECTED_MIXIN(OffscreenCanvas); USING_PRE_FINALIZER(OffscreenCanvas, Dispose); public: @@ -39,6 +42,7 @@ ~OffscreenCanvas() override; void Dispose(); + bool IsOffscreenCanvas() const override { return true; } // IDL attributes unsigned width() const { return size_.Width(); } unsigned height() const { return size_.Height(); } @@ -51,7 +55,7 @@ const ImageEncodeOptions&, ExceptionState&); - IntSize Size() const { return size_; } + const IntSize& Size() const override { return size_; } void SetSize(const IntSize&); void SetPlaceholderCanvasId(int canvas_id) { @@ -92,10 +96,11 @@ ScriptPromise Commit(RefPtr<StaticBitmapImage>, bool is_web_gl_software_rendering, - ScriptState*); - void FinalizeFrame(); + ScriptState*, + ExceptionState&) override; + void FinalizeFrame() override; - void DetachContext() { context_ = nullptr; } + void DetachContext() override { context_ = nullptr; } // OffscreenCanvasFrameDispatcherClient implementation void BeginFrame() final; @@ -104,10 +109,18 @@ const AtomicString& InterfaceName() const final { return EventTargetNames::OffscreenCanvas; } - ExecutionContext* GetExecutionContext() const { + ExecutionContext* GetExecutionContext() const override { return execution_context_.Get(); } + ExecutionContext* GetTopExecutionContext() const override { + return execution_context_.Get(); + } + + const KURL& GetExecutionContextUrl() const override { + return GetExecutionContext()->Url(); + } + // ImageBitmapSource implementation IntSize BitmapSourceSize() const final; ScriptPromise CreateImageBitmap(ScriptState*, @@ -122,7 +135,6 @@ SnapshotReason, const FloatSize&) const final; bool WouldTaintOrigin(SecurityOrigin*) const final { return !origin_clean_; } - bool IsOffscreenCanvas() const final { return true; } FloatSize ElementSize(const FloatSize& default_object_size) const final { return FloatSize(width(), height()); } @@ -131,6 +143,10 @@ int SourceWidth() final { return width(); } int SourceHeight() final { return height(); } + DispatchEventResult HostDispatchEvent(Event* event) { + return DispatchEvent(event); + } + DECLARE_VIRTUAL_TRACE(); private:
diff --git a/third_party/WebKit/Source/devtools/front_end/components/DOMBreakpointsSidebarPane.js b/third_party/WebKit/Source/devtools/front_end/components/DOMBreakpointsSidebarPane.js index 083ffbd..2b55e54 100644 --- a/third_party/WebKit/Source/devtools/front_end/components/DOMBreakpointsSidebarPane.js +++ b/third_party/WebKit/Source/devtools/front_end/components/DOMBreakpointsSidebarPane.js
@@ -27,20 +27,32 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + /** * @implements {UI.ContextFlavorListener} - * @unrestricted */ Components.DOMBreakpointsSidebarPane = class extends Components.BreakpointsSidebarPaneBase { constructor() { super(); - this._domBreakpointsSetting = Common.settings.createLocalSetting('domBreakpoints', []); + this.registerRequiredCSS('components/breakpointsList.css'); this.listElement.classList.add('dom-breakpoints-list'); - /** @type {!Map<string, !Element>} */ - this._breakpointElements = new Map(); + /** @type {!Map<!SDK.DOMDebuggerModel.DOMBreakpoint, !Components.DOMBreakpointsSidebarPane.Item>} */ + this._items = new Map(); + SDK.targetManager.addModelListener( + SDK.DOMDebuggerModel, SDK.DOMDebuggerModel.Events.DOMBreakpointAdded, this._breakpointAdded, this); + SDK.targetManager.addModelListener( + SDK.DOMDebuggerModel, SDK.DOMDebuggerModel.Events.DOMBreakpointToggled, this._breakpointToggled, this); + SDK.targetManager.addModelListener( + SDK.DOMDebuggerModel, SDK.DOMDebuggerModel.Events.DOMBreakpointsRemoved, this._breakpointsRemoved, this); - SDK.targetManager.addModelListener(SDK.DOMModel, SDK.DOMModel.Events.NodeRemoved, this._nodeRemoved, this); + for (var domDebuggerModel of SDK.targetManager.models(SDK.DOMDebuggerModel)) { + domDebuggerModel.retrieveDOMBreakpoints(); + for (var breakpoint of domDebuggerModel.domBreakpoints()) + this._addBreakpoint(breakpoint); + } + + this._highlightedElement = null; this._update(); } @@ -50,225 +62,126 @@ */ static createBreakpointHitMessage(details) { var messageWrapper = createElement('span'); + var domDebuggerModel = details.debuggerModel.target().model(SDK.DOMDebuggerModel); + if (!details.auxData || !domDebuggerModel) + return messageWrapper; + var data = domDebuggerModel.resolveDOMBreakpointData(/** @type {!Object} */ (details.auxData)); + if (!data) + return messageWrapper; + var mainElement = messageWrapper.createChild('div', 'status-main'); mainElement.appendChild(UI.Icon.create('smallicon-info', 'status-icon')); - var auxData = /** @type {!Object} */ (details.auxData); mainElement.appendChild(createTextNode( - String.sprintf('Paused on %s', Components.DOMBreakpointsSidebarPane.BreakpointTypeNouns[auxData['type']]))); + String.sprintf('Paused on %s', Components.DOMBreakpointsSidebarPane.BreakpointTypeNouns.get(data.type)))); - var domModel = details.debuggerModel.target().model(SDK.DOMModel); - if (domModel) { - var subElement = messageWrapper.createChild('div', 'status-sub monospace'); - var node = domModel.nodeForId(auxData['nodeId']); - var linkifiedNode = Components.DOMPresentationUtils.linkifyNodeReference(node); - subElement.appendChild(linkifiedNode); + var subElement = messageWrapper.createChild('div', 'status-sub monospace'); + var linkifiedNode = Components.DOMPresentationUtils.linkifyNodeReference(data.node); + subElement.appendChild(linkifiedNode); - var targetNode = auxData['targetNodeId'] ? domModel.nodeForId(auxData['targetNodeId']) : null; - var targetNodeLink = targetNode ? Components.DOMPresentationUtils.linkifyNodeReference(targetNode) : ''; + if (data.targetNode) { + var targetNodeLink = Components.DOMPresentationUtils.linkifyNodeReference(data.targetNode); var message; - if (auxData.type === Components.DOMBreakpointsSidebarPane.BreakpointTypes.SubtreeModified) { - if (auxData['insertion']) - message = targetNode === node ? 'Child %s added' : 'Descendant %s added'; - else - message = 'Descendant %s removed'; - subElement.appendChild(createElement('br')); - subElement.appendChild(UI.formatLocalized(message, [targetNodeLink])); - } + if (data.insertion) + message = data.targetNode === data.node ? 'Child %s added' : 'Descendant %s added'; + else + message = 'Descendant %s removed'; + subElement.appendChild(createElement('br')); + subElement.appendChild(UI.formatLocalized(message, [targetNodeLink])); } return messageWrapper; } /** - * @param {!SDK.DOMNode} node - * @param {!UI.ContextMenu} contextMenu - * @param {boolean} createSubMenu + * @param {!Common.Event} event */ - populateNodeContextMenu(node, contextMenu, createSubMenu) { - if (node.pseudoType()) - return; + _breakpointAdded(event) { + this._addBreakpoint(/** @type {!SDK.DOMDebuggerModel.DOMBreakpoint} */ (event.data)); + } - var nodeBreakpoints = this._nodeBreakpoints(node); + /** + * @param {!Common.Event} event + */ + _breakpointToggled(event) { + var breakpoint = /** @type {!SDK.DOMDebuggerModel.DOMBreakpoint} */ (event.data); + var item = this._items.get(breakpoint); + if (item) + item.checkbox.checked = breakpoint.enabled; + } - /** - * @param {!Protocol.DOMDebugger.DOMBreakpointType} type - * @this {Components.DOMBreakpointsSidebarPane} - */ - function toggleBreakpoint(type) { - if (!nodeBreakpoints.has(type)) - this._setBreakpoint(node, type, true); - else - this._removeBreakpoint(node, type); - this._saveBreakpoints(); - } - - var breakpointsMenu = createSubMenu ? contextMenu.appendSubMenuItem(Common.UIString('Break on...')) : contextMenu; - for (var key in Components.DOMBreakpointsSidebarPane.BreakpointTypes) { - var type = Components.DOMBreakpointsSidebarPane.BreakpointTypes[key]; - var label = Components.DOMBreakpointsSidebarPane.BreakpointTypeNouns[type]; - breakpointsMenu.appendCheckboxItem(label, toggleBreakpoint.bind(this, type), nodeBreakpoints.has(type)); + /** + * @param {!Common.Event} event + */ + _breakpointsRemoved(event) { + var breakpoints = /** @type {!Array<!SDK.DOMDebuggerModel.DOMBreakpoint>} */ (event.data); + for (var breakpoint of breakpoints) { + var item = this._items.get(breakpoint); + if (item) { + this._items.delete(breakpoint); + this.removeListElement(item.element); + } } } /** - * @param {!SDK.DOMNode} node - * @return {!Set<!Protocol.DOMDebugger.DOMBreakpointType>} + * @param {!SDK.DOMDebuggerModel.DOMBreakpoint} breakpoint */ - _nodeBreakpoints(node) { - /** @type {!Set<!Protocol.DOMDebugger.DOMBreakpointType>} */ - var nodeBreakpoints = new Set(); - for (var element of this._breakpointElements.values()) { - if (element._node === node && element._checkboxElement.checked) - nodeBreakpoints.add(element._type); - } - return nodeBreakpoints; - } - - /** - * @param {!SDK.DOMNode} node - * @return {boolean} - */ - hasBreakpoints(node) { - for (var element of this._breakpointElements.values()) { - if (element._node === node && element._checkboxElement.checked) - return true; - } - return false; - } - - _nodeRemoved(event) { - var node = event.data.node; - this._removeBreakpointsForNode(event.data.node); - var children = node.children(); - if (!children) - return; - for (var i = 0; i < children.length; ++i) - this._removeBreakpointsForNode(children[i]); - this._saveBreakpoints(); - } - - /** - * @param {!SDK.DOMNode} node - */ - _removeBreakpointsForNode(node) { - for (var element of this._breakpointElements.values()) { - if (element._node === node) - this._removeBreakpoint(element._node, element._type); - } - } - - /** - * @param {!SDK.DOMNode} node - * @param {!Protocol.DOMDebugger.DOMBreakpointType} type - * @param {boolean} enabled - */ - _setBreakpoint(node, type, enabled) { - var breakpointId = this._createBreakpointId(node.id, type); - var breakpointElement = this._breakpointElements.get(breakpointId); - if (!breakpointElement) { - breakpointElement = this._createBreakpointElement(node, type, enabled); - this._breakpointElements.set(breakpointId, breakpointElement); - } else { - breakpointElement._checkboxElement.checked = enabled; - } - if (enabled) - node.domModel().target().domdebuggerAgent().setDOMBreakpoint(node.id, type); - node.setMarker(Components.DOMBreakpointsSidebarPane.Marker, true); - } - - /** - * @param {!SDK.DOMNode} node - * @param {!Protocol.DOMDebugger.DOMBreakpointType} type - * @param {boolean} enabled - */ - _createBreakpointElement(node, type, enabled) { + _addBreakpoint(breakpoint) { var element = createElement('li'); - element._node = node; - element._type = type; - element.addEventListener('contextmenu', this._contextMenu.bind(this, node, type), true); + element.addEventListener('contextmenu', this._contextMenu.bind(this, breakpoint), true); - var checkboxLabel = UI.CheckboxLabel.create('', enabled); + var checkboxLabel = UI.CheckboxLabel.create('', breakpoint.enabled); var checkboxElement = checkboxLabel.checkboxElement; - checkboxElement.addEventListener('click', this._checkboxClicked.bind(this, node, type), false); - element._checkboxElement = checkboxElement; + checkboxElement.addEventListener('click', this._checkboxClicked.bind(this, breakpoint), false); element.appendChild(checkboxLabel); var labelElement = createElementWithClass('div', 'dom-breakpoint'); element.appendChild(labelElement); - var linkifiedNode = Components.DOMPresentationUtils.linkifyNodeReference(node); + var linkifiedNode = Components.DOMPresentationUtils.linkifyNodeReference(breakpoint.node); linkifiedNode.classList.add('monospace'); linkifiedNode.style.display = 'block'; labelElement.appendChild(linkifiedNode); var description = createElement('div'); - description.textContent = Components.DOMBreakpointsSidebarPane.BreakpointTypeLabels[type]; + description.textContent = Components.DOMBreakpointsSidebarPane.BreakpointTypeLabels.get(breakpoint.type); labelElement.appendChild(description); + var item = {breakpoint: breakpoint, element: element, checkbox: checkboxElement}; + element._item = item; + this._items.set(breakpoint, item); + var currentElement = this.listElement.firstChild; while (currentElement) { - if (currentElement._type && currentElement._type < element._type) + if (currentElement._item && currentElement._item.breakpoint.type < breakpoint.type) break; currentElement = currentElement.nextSibling; } this.addListElement(element, currentElement); - return element; - } - - _removeAllBreakpoints() { - for (var element of this._breakpointElements.values()) - this._removeBreakpoint(element._node, element._type); - this._saveBreakpoints(); } /** - * @param {!SDK.DOMNode} node - * @param {!Protocol.DOMDebugger.DOMBreakpointType} type - */ - _removeBreakpoint(node, type) { - var breakpointId = this._createBreakpointId(node.id, type); - var element = this._breakpointElements.get(breakpointId); - if (!element) - return; - - this.removeListElement(element); - this._breakpointElements.delete(breakpointId); - if (element._checkboxElement.checked) - node.domModel().target().domdebuggerAgent().removeDOMBreakpoint(node.id, type); - node.setMarker(Components.DOMBreakpointsSidebarPane.Marker, this.hasBreakpoints(node) ? true : null); - } - - /** - * @param {!SDK.DOMNode} node - * @param {!Protocol.DOMDebugger.DOMBreakpointType} type + * @param {!SDK.DOMDebuggerModel.DOMBreakpoint} breakpoint * @param {!Event} event */ - _contextMenu(node, type, event) { + _contextMenu(breakpoint, event) { var contextMenu = new UI.ContextMenu(event); - - /** - * @this {Components.DOMBreakpointsSidebarPane} - */ - function removeBreakpoint() { - this._removeBreakpoint(node, type); - this._saveBreakpoints(); - } - contextMenu.appendItem(Common.UIString.capitalize('Remove ^breakpoint'), removeBreakpoint.bind(this)); - contextMenu.appendItem( - Common.UIString.capitalize('Remove ^all DOM breakpoints'), this._removeAllBreakpoints.bind(this)); + contextMenu.appendItem(Common.UIString.capitalize('Remove ^breakpoint'), () => { + breakpoint.domDebuggerModel.removeDOMBreakpoint(breakpoint.node, breakpoint.type); + }); + contextMenu.appendItem(Common.UIString.capitalize('Remove ^all DOM breakpoints'), () => { + breakpoint.domDebuggerModel.removeAllDOMBreakpoints(); + }); contextMenu.show(); } /** - * @param {!SDK.DOMNode} node - * @param {!Protocol.DOMDebugger.DOMBreakpointType} type - * @param {!Event} event + * @param {!SDK.DOMDebuggerModel.DOMBreakpoint} breakpoint */ - _checkboxClicked(node, type, event) { - if (event.target.checked) - node.domModel().target().domdebuggerAgent().setDOMBreakpoint(node.id, type); - else - node.domModel().target().domdebuggerAgent().removeDOMBreakpoint(node.id, type); - this._saveBreakpoints(); + _checkboxClicked(breakpoint) { + var item = this._items.get(breakpoint); + if (!item) + return; + breakpoint.domDebuggerModel.toggleDOMBreakpoint(breakpoint, item.checkbox.checked); } /** @@ -281,133 +194,82 @@ _update() { var details = UI.context.flavor(SDK.DebuggerPausedDetails); - if (!details || details.reason !== SDK.DebuggerModel.BreakReason.DOM) { + if (!details || !details.auxData || details.reason !== SDK.DebuggerModel.BreakReason.DOM) { if (this._highlightedElement) { this._highlightedElement.classList.remove('breakpoint-hit'); delete this._highlightedElement; } return; } - var auxData = details.auxData; - var breakpointId = this._createBreakpointId(auxData.nodeId, auxData.type); - var element = this._breakpointElements.get(breakpointId); + var domDebuggerModel = details.debuggerModel.target().model(SDK.DOMDebuggerModel); + if (!domDebuggerModel) + return; + var data = domDebuggerModel.resolveDOMBreakpointData(/** @type {!Object} */ (details.auxData)); + if (!data) + return; + + var element = null; + for (var item of this._items.values()) { + if (item.breakpoint.node === data.node && item.breakpoint.type === data.type) + element = item.element; + } if (!element) return; UI.viewManager.showView('sources.domBreakpoints'); element.classList.add('breakpoint-hit'); this._highlightedElement = element; } - - /** - * @param {number} nodeId - * @param {!Protocol.DOMDebugger.DOMBreakpointType} type - */ - _createBreakpointId(nodeId, type) { - return nodeId + ':' + type; - } - - _saveBreakpoints() { - var breakpoints = []; - var storedBreakpoints = this._domBreakpointsSetting.get(); - for (var i = 0; i < storedBreakpoints.length; ++i) { - var breakpoint = storedBreakpoints[i]; - if (breakpoint.url !== this._inspectedURL) - breakpoints.push(breakpoint); - } - for (var element of this._breakpointElements.values()) { - breakpoints.push({ - url: this._inspectedURL, - path: element._node.path(), - type: element._type, - enabled: element._checkboxElement.checked - }); - } - this._domBreakpointsSetting.set(breakpoints); - } - - /** - * @param {!SDK.DOMDocument} domDocument - */ - restoreBreakpoints(domDocument) { - this._breakpointElements.clear(); - this.reset(); - this._inspectedURL = domDocument.documentURL; - var domModel = domDocument.domModel(); - /** @type {!Map<string, !Array<!Object>>} */ - var pathToBreakpoints = new Map(); - - /** - * @param {string} path - * @param {?Protocol.DOM.NodeId} nodeId - * @this {Components.DOMBreakpointsSidebarPane} - */ - function didPushNodeByPathToFrontend(path, nodeId) { - var node = nodeId ? domModel.nodeForId(nodeId) : null; - if (!node) - return; - - var breakpoints = pathToBreakpoints.get(path); - for (var i = 0; i < breakpoints.length; ++i) - this._setBreakpoint(node, breakpoints[i].type, breakpoints[i].enabled); - } - - var breakpoints = this._domBreakpointsSetting.get(); - for (var i = 0; i < breakpoints.length; ++i) { - var breakpoint = breakpoints[i]; - if (breakpoint.url !== this._inspectedURL) - continue; - var path = breakpoint.path; - if (!pathToBreakpoints.has(path)) { - pathToBreakpoints.set(path, []); - domModel.pushNodeByPathToFrontend(path, didPushNodeByPathToFrontend.bind(this, path)); - } - pathToBreakpoints.get(path).push(breakpoint); - } - } }; -Components.DOMBreakpointsSidebarPane.BreakpointTypes = { - SubtreeModified: 'subtree-modified', - AttributeModified: 'attribute-modified', - NodeRemoved: 'node-removed' -}; +/** @typedef {!{element: !Element, checkbox: !Element, breakpoint: !SDK.DOMDebuggerModel.DOMBreakpoint}} */ +Components.DOMBreakpointsSidebarPane.Item; -Components.DOMBreakpointsSidebarPane.BreakpointTypeLabels = { - 'subtree-modified': Common.UIString('Subtree Modified'), - 'attribute-modified': Common.UIString('Attribute Modified'), - 'node-removed': Common.UIString('Node Removed') -}; +Components.DOMBreakpointsSidebarPane.BreakpointTypeLabels = new Map([ + [SDK.DOMDebuggerModel.DOMBreakpoint.Type.SubtreeModified, Common.UIString('Subtree Modified')], + [SDK.DOMDebuggerModel.DOMBreakpoint.Type.AttributeModified, Common.UIString('Attribute Modified')], + [SDK.DOMDebuggerModel.DOMBreakpoint.Type.NodeRemoved, Common.UIString('Node Removed')], +]); -Components.DOMBreakpointsSidebarPane.BreakpointTypeNouns = { - 'subtree-modified': Common.UIString('subtree modifications'), - 'attribute-modified': Common.UIString('attribute modifications'), - 'node-removed': Common.UIString('node removal') -}; - -Components.DOMBreakpointsSidebarPane.Marker = 'breakpoint-marker'; - +Components.DOMBreakpointsSidebarPane.BreakpointTypeNouns = new Map([ + [SDK.DOMDebuggerModel.DOMBreakpoint.Type.SubtreeModified, Common.UIString('subtree modifications')], + [SDK.DOMDebuggerModel.DOMBreakpoint.Type.AttributeModified, Common.UIString('attribute modifications')], + [SDK.DOMDebuggerModel.DOMBreakpoint.Type.NodeRemoved, Common.UIString('node removal')], +]); /** - * @unrestricted + * @implements {UI.ContextMenu.Provider} */ -Components.DOMBreakpointsSidebarPane.Proxy = class extends UI.VBox { - constructor() { - super(); - this.registerRequiredCSS('components/breakpointsList.css'); - } - +Components.DOMBreakpointsSidebarPane.ContextMenuProvider = class { /** * @override + * @param {!Event} event + * @param {!UI.ContextMenu} contextMenu + * @param {!Object} object */ - wasShown() { - super.wasShown(); - var pane = Components.domBreakpointsSidebarPane; - if (pane.element.parentNode !== this.element) - pane.show(this.element); + appendApplicableItems(event, contextMenu, object) { + var node = /** @type {!SDK.DOMNode} */ (object); + if (node.pseudoType()) + return; + var domDebuggerModel = node.domModel().target().model(SDK.DOMDebuggerModel); + if (!domDebuggerModel) + return; + + /** + * @param {!SDK.DOMDebuggerModel.DOMBreakpoint.Type} type + */ + function toggleBreakpoint(type) { + if (domDebuggerModel.hasDOMBreakpoint(node, type)) + domDebuggerModel.removeDOMBreakpoint(node, type); + else + domDebuggerModel.setDOMBreakpoint(node, type); + } + + var breakpointsMenu = contextMenu.appendSubMenuItem(Common.UIString('Break on...')); + for (var key in SDK.DOMDebuggerModel.DOMBreakpoint.Type) { + var type = SDK.DOMDebuggerModel.DOMBreakpoint.Type[key]; + var label = Components.DOMBreakpointsSidebarPane.BreakpointTypeNouns.get(type); + breakpointsMenu.appendCheckboxItem( + label, toggleBreakpoint.bind(null, type), domDebuggerModel.hasDOMBreakpoint(node, type)); + } } }; - -/** - * @type {!Components.DOMBreakpointsSidebarPane} - */ -Components.domBreakpointsSidebarPane;
diff --git a/third_party/WebKit/Source/devtools/front_end/components/module.json b/third_party/WebKit/Source/devtools/front_end/components/module.json index 5e0823f3f..73db852 100644 --- a/third_party/WebKit/Source/devtools/front_end/components/module.json +++ b/third_party/WebKit/Source/devtools/front_end/components/module.json
@@ -6,6 +6,36 @@ "marker": "breakpoint-marker", "title": "DOM Breakpoint", "color": "rgb(105, 140, 254)" + }, + { + "type": "@UI.ContextMenu.Provider", + "contextTypes": [ "SDK.DOMNode" ], + "className": "Components.DOMBreakpointsSidebarPane.ContextMenuProvider" + }, + { + "type": "@UI.ContextFlavorListener", + "contextTypes": [ + "SDK.DebuggerPausedDetails" + ], + "className": "Components.DOMBreakpointsSidebarPane" + }, + { + "type": "view", + "location": "sources-sidebar", + "id": "sources.domBreakpoints", + "title": "DOM Breakpoints", + "order": 7, + "persistence": "permanent", + "factoryName": "Components.DOMBreakpointsSidebarPane" + }, + { + "type": "view", + "location": "elements-sidebar", + "id": "elements.domBreakpoints", + "title": "DOM Breakpoints", + "order": 6, + "persistence": "permanent", + "factoryName": "Components.DOMBreakpointsSidebarPane" } ], "dependencies": [
diff --git a/third_party/WebKit/Source/devtools/front_end/elements/ElementsPanel.js b/third_party/WebKit/Source/devtools/front_end/elements/ElementsPanel.js index 3f3c33d..343e5e8 100644 --- a/third_party/WebKit/Source/devtools/front_end/elements/ElementsPanel.js +++ b/third_party/WebKit/Source/devtools/front_end/elements/ElementsPanel.js
@@ -417,7 +417,6 @@ } this._hasNonDefaultSelectedNode = false; - Components.domBreakpointsSidebarPane.restoreBreakpoints(inspectedRootDocument); if (this._omitDefaultSelection) return; @@ -965,13 +964,6 @@ !(object instanceof SDK.DOMNode) && !(object instanceof SDK.DeferredDOMNode)) return; - - // Add debbuging-related actions - if (object instanceof SDK.DOMNode) { - contextMenu.appendSeparator(); - Components.domBreakpointsSidebarPane.populateNodeContextMenu(object, contextMenu, true); - } - // Skip adding "Reveal..." menu item for our own tree outline. if (Elements.ElementsPanel.instance().element.isAncestor(/** @type {!Node} */ (event.target))) return;
diff --git a/third_party/WebKit/Source/devtools/front_end/elements/module.json b/third_party/WebKit/Source/devtools/front_end/elements/module.json index 684632f..7fe5b5a 100644 --- a/third_party/WebKit/Source/devtools/front_end/elements/module.json +++ b/third_party/WebKit/Source/devtools/front_end/elements/module.json
@@ -235,15 +235,6 @@ { "type": "view", "location": "elements-sidebar", - "id": "elements.domBreakpoints", - "title": "DOM Breakpoints", - "order": 6, - "persistence": "permanent", - "factoryName": "Components.DOMBreakpointsSidebarPane.Proxy" - }, - { - "type": "view", - "location": "elements-sidebar", "id": "elements.domProperties", "title": "Properties", "order": 7,
diff --git a/third_party/WebKit/Source/devtools/front_end/main/Main.js b/third_party/WebKit/Source/devtools/front_end/main/Main.js index 2aa82f7..991a9be7 100644 --- a/third_party/WebKit/Source/devtools/front_end/main/Main.js +++ b/third_party/WebKit/Source/devtools/front_end/main/Main.js
@@ -205,7 +205,6 @@ new Main.NetworkPanelIndicator(); new Main.SourcesPanelIndicator(); new Main.BackendSettingsSync(); - Components.domBreakpointsSidebarPane = new Components.DOMBreakpointsSidebarPane(); UI.actionRegistry = new UI.ActionRegistry(); UI.shortcutRegistry = new UI.ShortcutRegistry(UI.actionRegistry, document);
diff --git a/third_party/WebKit/Source/devtools/front_end/sdk/DOMDebuggerModel.js b/third_party/WebKit/Source/devtools/front_end/sdk/DOMDebuggerModel.js index a87bea1..069e2c861 100644 --- a/third_party/WebKit/Source/devtools/front_end/sdk/DOMDebuggerModel.js +++ b/third_party/WebKit/Source/devtools/front_end/sdk/DOMDebuggerModel.js
@@ -11,6 +11,14 @@ this._agent = target.domdebuggerAgent(); this._runtimeModel = /** @type {!SDK.RuntimeModel} */ (target.model(SDK.RuntimeModel)); this._domModel = /** @type {!SDK.DOMModel} */ (target.model(SDK.DOMModel)); + this._domModel.addEventListener(SDK.DOMModel.Events.DocumentUpdated, this._documentUpdated, this); + this._domModel.addEventListener(SDK.DOMModel.Events.NodeRemoved, this._nodeRemoved, this); + + /** @type {!Array<!SDK.DOMDebuggerModel.DOMBreakpoint>} */ + this._domBreakpoints = []; + this._domBreakpointsSetting = Common.settings.createLocalSetting('domBreakpoints', []); + if (this._domModel.existingDocument()) + this._documentUpdated(); } /** @@ -44,10 +52,225 @@ } return eventListeners; } + + retrieveDOMBreakpoints() { + this._domModel.requestDocument(); + } + + /** + * @return {!Array<!SDK.DOMDebuggerModel.DOMBreakpoint>} + */ + domBreakpoints() { + return this._domBreakpoints.slice(); + } + + /** + * @param {!SDK.DOMNode} node + * @param {!SDK.DOMDebuggerModel.DOMBreakpoint.Type} type + * @return {boolean} + */ + hasDOMBreakpoint(node, type) { + return this._domBreakpoints.some(breakpoint => (breakpoint.node === node && breakpoint.type === type)); + } + + /** + * @param {!SDK.DOMNode} node + * @param {!SDK.DOMDebuggerModel.DOMBreakpoint.Type} type + * @return {!SDK.DOMDebuggerModel.DOMBreakpoint} + */ + setDOMBreakpoint(node, type) { + for (var breakpoint of this._domBreakpoints) { + if (breakpoint.node === node && breakpoint.type === type) { + this.toggleDOMBreakpoint(breakpoint, true); + return breakpoint; + } + } + var breakpoint = new SDK.DOMDebuggerModel.DOMBreakpoint(this, node, type, true); + this._domBreakpoints.push(breakpoint); + this._saveDOMBreakpoints(); + this._enableDOMBreakpoint(breakpoint); + this.dispatchEventToListeners(SDK.DOMDebuggerModel.Events.DOMBreakpointAdded, breakpoint); + return breakpoint; + } + + /** + * @param {!SDK.DOMNode} node + * @param {!SDK.DOMDebuggerModel.DOMBreakpoint.Type} type + */ + removeDOMBreakpoint(node, type) { + this._removeDOMBreakpoints(breakpoint => breakpoint.node === node && breakpoint.type === type); + } + + removeAllDOMBreakpoints() { + this._removeDOMBreakpoints(breakpoint => true); + } + + /** + * @param {!SDK.DOMDebuggerModel.DOMBreakpoint} breakpoint + * @param {boolean} enabled + */ + toggleDOMBreakpoint(breakpoint, enabled) { + if (enabled === breakpoint.enabled) + return; + breakpoint.enabled = enabled; + if (enabled) + this._enableDOMBreakpoint(breakpoint); + else + this._disableDOMBreakpoint(breakpoint); + this.dispatchEventToListeners(SDK.DOMDebuggerModel.Events.DOMBreakpointToggled, breakpoint); + } + + /** + * @param {!SDK.DOMDebuggerModel.DOMBreakpoint} breakpoint + */ + _enableDOMBreakpoint(breakpoint) { + this._agent.setDOMBreakpoint(breakpoint.node.id, breakpoint.type); + breakpoint.node.setMarker(SDK.DOMDebuggerModel.DOMBreakpoint.Marker, true); + } + + /** + * @param {!SDK.DOMDebuggerModel.DOMBreakpoint} breakpoint + */ + _disableDOMBreakpoint(breakpoint) { + this._agent.removeDOMBreakpoint(breakpoint.node.id, breakpoint.type); + breakpoint.node.setMarker( + SDK.DOMDebuggerModel.DOMBreakpoint.Marker, this._nodeHasBreakpoints(breakpoint.node) ? true : null); + } + + /** + * @param {!SDK.DOMNode} node + * @return {boolean} + */ + _nodeHasBreakpoints(node) { + for (var breakpoint of this._domBreakpoints) { + if (breakpoint.node === node && breakpoint.enabled) + return true; + } + return false; + } + + /** + * @param {!Object} auxData + * @return {?{type: !SDK.DOMDebuggerModel.DOMBreakpoint.Type, node: !SDK.DOMNode, targetNode: ?SDK.DOMNode, insertion: boolean}} + */ + resolveDOMBreakpointData(auxData) { + var type = auxData['type']; + var node = this._domModel.nodeForId(auxData['nodeId']); + if (!type || !node) + return null; + var targetNode = null; + var insertion = false; + if (type === SDK.DOMDebuggerModel.DOMBreakpoint.Type.SubtreeModified) { + insertion = auxData['insertion'] || false; + targetNode = this._domModel.nodeForId(auxData['targetNodeId']); + } + return {type: type, node: node, targetNode: targetNode, insertion: insertion}; + } + + /** + * @return {string} + */ + _currentURL() { + var domDocument = this._domModel.existingDocument(); + return domDocument ? domDocument.documentURL : ''; + } + + _documentUpdated() { + var removed = this._domBreakpoints; + this._domBreakpoints = []; + this.dispatchEventToListeners(SDK.DOMDebuggerModel.Events.DOMBreakpointsRemoved, removed); + + var currentURL = this._currentURL(); + for (var breakpoint of this._domBreakpointsSetting.get()) { + if (breakpoint.url !== currentURL) + continue; + this._domModel.pushNodeByPathToFrontend(breakpoint.path, nodeId => { + var node = nodeId ? this._domModel.nodeForId(nodeId) : null; + if (!node) + return; + var domBreakpoint = new SDK.DOMDebuggerModel.DOMBreakpoint(this, node, breakpoint.type, breakpoint.enabled); + this._domBreakpoints.push(domBreakpoint); + if (breakpoint.enabled) + this._enableDOMBreakpoint(domBreakpoint); + this.dispatchEventToListeners(SDK.DOMDebuggerModel.Events.DOMBreakpointAdded, domBreakpoint); + }); + } + } + + /** + * @param {function(!SDK.DOMDebuggerModel.DOMBreakpoint):boolean} filter + */ + _removeDOMBreakpoints(filter) { + var removed = []; + var left = []; + for (var breakpoint of this._domBreakpoints) { + if (filter(breakpoint)) { + removed.push(breakpoint); + if (breakpoint.enabled) { + breakpoint.enabled = false; + this._disableDOMBreakpoint(breakpoint); + } + } else { + left.push(breakpoint); + } + } + + if (!removed.length) + return; + this._domBreakpoints = left; + this._saveDOMBreakpoints(); + this.dispatchEventToListeners(SDK.DOMDebuggerModel.Events.DOMBreakpointsRemoved, removed); + } + + /** + * @param {!Common.Event} event + */ + _nodeRemoved(event) { + var node = /** @type {!SDK.DOMNode} */ (event.data.node); + var children = node.children() || []; + this._removeDOMBreakpoints(breakpoint => breakpoint.node === node || children.indexOf(breakpoint.node) !== -1); + } + + _saveDOMBreakpoints() { + var currentURL = this._currentURL(); + var breakpoints = this._domBreakpointsSetting.get().filter(breakpoint => breakpoint.url !== currentURL); + for (var breakpoint of this._domBreakpoints) { + breakpoints.push( + {url: currentURL, path: breakpoint.node.path(), type: breakpoint.type, enabled: breakpoint.enabled}); + } + this._domBreakpointsSetting.set(breakpoints); + } }; SDK.SDKModel.register(SDK.DOMDebuggerModel, SDK.Target.Capability.DOM, false); +/** @enum {symbol} */ +SDK.DOMDebuggerModel.Events = { + DOMBreakpointAdded: Symbol('DOMBreakpointAdded'), + DOMBreakpointToggled: Symbol('DOMBreakpointToggled'), + DOMBreakpointsRemoved: Symbol('DOMBreakpointsRemoved'), +}; + +SDK.DOMDebuggerModel.DOMBreakpoint = class { + /** + * @param {!SDK.DOMDebuggerModel} domDebuggerModel + * @param {!SDK.DOMNode} node + * @param {!SDK.DOMDebuggerModel.DOMBreakpoint.Type} type + * @param {boolean} enabled + */ + constructor(domDebuggerModel, node, type, enabled) { + this.domDebuggerModel = domDebuggerModel; + this.node = node; + this.type = type; + this.enabled = enabled; + } +}; + +/** @typedef {Protocol.DOMDebugger.DOMBreakpointType} */ +SDK.DOMDebuggerModel.DOMBreakpoint.Type = Protocol.DOMDebugger.DOMBreakpointType; + +SDK.DOMDebuggerModel.DOMBreakpoint.Marker = 'breakpoint-marker'; + SDK.EventListener = class { /** * @param {!SDK.DOMDebuggerModel} domDebuggerModel
diff --git a/third_party/WebKit/Source/devtools/front_end/sources/module.json b/third_party/WebKit/Source/devtools/front_end/sources/module.json index 8a9d43c..41d5798 100644 --- a/third_party/WebKit/Source/devtools/front_end/sources/module.json +++ b/third_party/WebKit/Source/devtools/front_end/sources/module.json
@@ -519,15 +519,6 @@ { "type": "view", "location": "sources-sidebar", - "id": "sources.domBreakpoints", - "title": "DOM Breakpoints", - "order": 7, - "persistence": "permanent", - "factoryName": "Components.DOMBreakpointsSidebarPane.Proxy" - }, - { - "type": "view", - "location": "sources-sidebar", "id": "sources.globalListeners", "title": "Global Listeners", "order": 8, @@ -592,13 +583,6 @@ "contextTypes": [ "SDK.DebuggerPausedDetails" ], - "className": "Components.DOMBreakpointsSidebarPane" - }, - { - "type": "@UI.ContextFlavorListener", - "contextTypes": [ - "SDK.DebuggerPausedDetails" - ], "className": "Sources.CallStackSidebarPane" }, {
diff --git a/third_party/WebKit/Source/devtools/front_end/timeline/TimelineUIUtils.js b/third_party/WebKit/Source/devtools/front_end/timeline/TimelineUIUtils.js index 3a8ec1a4..1567c91 100644 --- a/third_party/WebKit/Source/devtools/front_end/timeline/TimelineUIUtils.js +++ b/third_party/WebKit/Source/devtools/front_end/timeline/TimelineUIUtils.js
@@ -1046,13 +1046,14 @@ */ static _buildRangeStatsCacheIfNeeded(model) { var tasks = model.mainThreadTasks(); - if (tasks.length && tasks[0][Timeline.TimelineUIUtils._categoryBreakdownCacheSymbol]) + var filter = Timeline.TimelineUIUtils._filterForStats(); + var firstTask = tasks.find(filter); + if (!firstTask || firstTask[Timeline.TimelineUIUtils._categoryBreakdownCacheSymbol]) return; var aggregatedStats = {}; var ownTimes = []; TimelineModel.TimelineModel.forEachEvent( - model.mainThreadEvents(), onStartEvent, onEndEvent, undefined, undefined, undefined, - Timeline.TimelineUIUtils._filterForStats()); + model.mainThreadEvents(), onStartEvent, onEndEvent, undefined, undefined, undefined, filter); /** * @param {!SDK.TracingModel.Event} e
diff --git a/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2D.cpp b/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2D.cpp index 7d1aa49..7110a2f5 100644 --- a/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2D.cpp +++ b/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2D.cpp
@@ -115,7 +115,7 @@ HTMLCanvasElement* canvas, const CanvasContextCreationAttributes& attrs, Document& document) - : CanvasRenderingContext(canvas, nullptr, attrs), + : CanvasRenderingContext(canvas, attrs), context_lost_mode_(kNotLostContext), context_restorable_(true), try_restore_context_attempt_count_(0), @@ -365,11 +365,11 @@ } bool CanvasRenderingContext2D::StateHasFilter() { - return GetState().HasFilter(canvas(), canvas()->size(), this); + return GetState().HasFilter(canvas(), canvas()->Size(), this); } sk_sp<SkImageFilter> CanvasRenderingContext2D::StateGetFilter() { - return GetState().GetFilter(canvas(), canvas()->size(), this); + return GetState().GetFilter(canvas(), canvas()->Size(), this); } void CanvasRenderingContext2D::SnapshotStateForFilter() {
diff --git a/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2D.h b/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2D.h index ee5bcb65..8782be3 100644 --- a/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2D.h +++ b/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2D.h
@@ -91,6 +91,10 @@ ~CanvasRenderingContext2D() override; + HTMLCanvasElement* canvas() const { + DCHECK(!host() || !host()->IsOffscreenCanvas()); + return static_cast<HTMLCanvasElement*>(host()); + } void SetCanvasGetContextResult(RenderingContext&) final; bool isContextLost() const override; @@ -266,11 +270,12 @@ ListHashSet<String> font_lru_list_; }; +// TODO(fserb): remove this? DEFINE_TYPE_CASTS(CanvasRenderingContext2D, CanvasRenderingContext, context, - context->Is2d() && context->canvas(), - context.Is2d() && context.canvas()); + context->Is2d() && context->host(), + context.Is2d() && context.host()); } // namespace blink
diff --git a/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2DTest.cpp b/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2DTest.cpp index 96fedcf..2f1c1f4 100644 --- a/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2DTest.cpp +++ b/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2DTest.cpp
@@ -927,9 +927,9 @@ CreateContext(kNonOpaque); Context2d()->fillRect(0, 0, 1, 1); // results in task observer registration - Context2d()->DetachCanvas(); + Context2d()->DetachHost(); - // This is the only method that is callable after detachCanvas + // This is the only method that is callable after DetachHost // Test passes by not crashing. Context2d()->DidProcessTask();
diff --git a/third_party/WebKit/Source/modules/encryptedmedia/MediaKeySession.cpp b/third_party/WebKit/Source/modules/encryptedmedia/MediaKeySession.cpp index 02128d9..7036d519 100644 --- a/third_party/WebKit/Source/modules/encryptedmedia/MediaKeySession.cpp +++ b/third_party/WebKit/Source/modules/encryptedmedia/MediaKeySession.cpp
@@ -813,37 +813,27 @@ if (!is_callable_) return CreateRejectedPromiseNotCallable(script_state); - // 3. If the result of running the "Is persistent session type?" algorithm - // on this object's session type is false, return a promise rejected - // with a newly created TypeError. - if (!IsPersistentSessionType(session_type_)) { - return ScriptPromise::Reject( - script_state, - V8ThrowException::CreateTypeError( - script_state->GetIsolate(), "The session type is not persistent.")); - } - - // 4. Let promise be a new promise. + // 3. Let promise be a new promise. SimpleResultPromise* result = new SimpleResultPromise(script_state, this); ScriptPromise promise = result->Promise(); - // 5. Run the following steps asynchronously (done in removeTask()). + // 4. Run the following steps asynchronously (done in removeTask()). pending_actions_.push_back(PendingAction::CreatePendingRemove(result)); if (!action_timer_.IsActive()) action_timer_.StartOneShot(0, BLINK_FROM_HERE); - // 6. Return promise. + // 5. Return promise. return promise; } void MediaKeySession::RemoveTask(ContentDecryptionModuleResult* result) { - // NOTE: Continue step 5 of MediaKeySession::remove(). + // NOTE: Continue step 4 of MediaKeySession::remove(). DVLOG(MEDIA_KEY_SESSION_LOG_LEVEL) << __func__ << "(" << this << ")"; - // remove() in Chromium will execute steps 5.1 through 5.3. + // remove() in Chromium will execute steps 4.1 through 4.5. session_->Remove(result->Result()); - // Last step (5.3.6 Resolve promise) will be done when |result| is resolved. + // Last step (4.5.6 Resolve promise) will be done when |result| is resolved. } void MediaKeySession::ActionTimerFired(TimerBase*) {
diff --git a/third_party/WebKit/Source/modules/imagebitmap/ImageBitmapRenderingContext.cpp b/third_party/WebKit/Source/modules/imagebitmap/ImageBitmapRenderingContext.cpp index cda44a03..96e1ea6 100644 --- a/third_party/WebKit/Source/modules/imagebitmap/ImageBitmapRenderingContext.cpp +++ b/third_party/WebKit/Source/modules/imagebitmap/ImageBitmapRenderingContext.cpp
@@ -18,7 +18,7 @@ HTMLCanvasElement* canvas, const CanvasContextCreationAttributes& attrs, Document& document) - : CanvasRenderingContext(canvas, nullptr, attrs), + : CanvasRenderingContext(canvas, attrs), image_layer_bridge_( new ImageLayerBridge(attrs.alpha() ? kNonOpaque : kOpaque)) {}
diff --git a/third_party/WebKit/Source/modules/imagebitmap/ImageBitmapRenderingContext.h b/third_party/WebKit/Source/modules/imagebitmap/ImageBitmapRenderingContext.h index 3ae29a0..35f17a1 100644 --- a/third_party/WebKit/Source/modules/imagebitmap/ImageBitmapRenderingContext.h +++ b/third_party/WebKit/Source/modules/imagebitmap/ImageBitmapRenderingContext.h
@@ -40,6 +40,11 @@ // Script API void transferFromImageBitmap(ImageBitmap*, ExceptionState&); + HTMLCanvasElement* canvas() { + DCHECK(!host() || !host()->IsOffscreenCanvas()); + return static_cast<HTMLCanvasElement*>(host()); + } + // CanvasRenderingContext implementation ContextType GetContextType() const override { return CanvasRenderingContext::kContextImageBitmap;
diff --git a/third_party/WebKit/Source/modules/indexeddb/IDBCursor.idl b/third_party/WebKit/Source/modules/indexeddb/IDBCursor.idl index 17e55e5..6c556ef 100644 --- a/third_party/WebKit/Source/modules/indexeddb/IDBCursor.idl +++ b/third_party/WebKit/Source/modules/indexeddb/IDBCursor.idl
@@ -42,9 +42,10 @@ [CallWith=ScriptState, CachedAttribute=isKeyDirty] readonly attribute any key; [CallWith=ScriptState, CachedAttribute=isPrimaryKeyDirty] readonly attribute any primaryKey; - [CallWith=ScriptState, RaisesException] IDBRequest update(any value); [RaisesException] void advance([EnforceRange] unsigned long count); [CallWith=ScriptState, ImplementedAs=continueFunction, RaisesException] void continue([Default=Undefined] optional any key); [CallWith=ScriptState, RaisesException] void continuePrimaryKey(any key, any primaryKey); - [CallWith=ScriptState, ImplementedAs=deleteFunction, RaisesException] IDBRequest delete(); + + [NewObject, CallWith=ScriptState, RaisesException] IDBRequest update(any value); + [NewObject, CallWith=ScriptState, ImplementedAs=deleteFunction, RaisesException] IDBRequest delete(); };
diff --git a/third_party/WebKit/Source/modules/indexeddb/IDBDatabase.idl b/third_party/WebKit/Source/modules/indexeddb/IDBDatabase.idl index 12f3aea..3febcf1 100644 --- a/third_party/WebKit/Source/modules/indexeddb/IDBDatabase.idl +++ b/third_party/WebKit/Source/modules/indexeddb/IDBDatabase.idl
@@ -35,11 +35,14 @@ readonly attribute unsigned long long version; readonly attribute DOMStringList objectStoreNames; - [RaisesException] IDBObjectStore createObjectStore(DOMString name, optional IDBObjectStoreParameters options); - [RaisesException] void deleteObjectStore(DOMString name); - [CallWith=ScriptState, RaisesException] IDBTransaction transaction((DOMString or sequence<DOMString> or DOMStringList) storeNames, optional IDBTransactionMode mode = "readonly"); + [NewObject, CallWith=ScriptState, RaisesException] IDBTransaction transaction((DOMString or sequence<DOMString> or DOMStringList) storeNames, + optional IDBTransactionMode mode = "readonly"); void close(); + [NewObject, RaisesException] IDBObjectStore createObjectStore(DOMString name, + optional IDBObjectStoreParameters options); + [RaisesException] void deleteObjectStore(DOMString name); + attribute EventHandler onabort; attribute EventHandler onclose; attribute EventHandler onerror;
diff --git a/third_party/WebKit/Source/modules/indexeddb/IDBFactory.idl b/third_party/WebKit/Source/modules/indexeddb/IDBFactory.idl index 7ba7cfc..d220022 100644 --- a/third_party/WebKit/Source/modules/indexeddb/IDBFactory.idl +++ b/third_party/WebKit/Source/modules/indexeddb/IDBFactory.idl
@@ -30,8 +30,9 @@ ] interface IDBFactory { [CallWith=ScriptState, ImplementedAs=getDatabaseNames, RaisesException, DeprecateAs=V8IDBFactory_WebkitGetDatabaseNames_Method] IDBRequest webkitGetDatabaseNames(); - [CallWith=ScriptState, RaisesException] IDBOpenDBRequest open(DOMString name, [EnforceRange] optional unsigned long long version); - [CallWith=ScriptState, RaisesException] IDBOpenDBRequest deleteDatabase(DOMString name); + [NewObject, CallWith=ScriptState, RaisesException] IDBOpenDBRequest open(DOMString name, + [EnforceRange] optional unsigned long long version); + [NewObject, CallWith=ScriptState, RaisesException] IDBOpenDBRequest deleteDatabase(DOMString name); [CallWith=ScriptState, RaisesException] short cmp(any first, any second); };
diff --git a/third_party/WebKit/Source/modules/indexeddb/IDBIndex.idl b/third_party/WebKit/Source/modules/indexeddb/IDBIndex.idl index 1d33c93..5e1bace 100644 --- a/third_party/WebKit/Source/modules/indexeddb/IDBIndex.idl +++ b/third_party/WebKit/Source/modules/indexeddb/IDBIndex.idl
@@ -29,19 +29,23 @@ Exposed=(Window,Worker), ] interface IDBIndex { [RaisesException=Setter] attribute DOMString name; - readonly attribute IDBObjectStore objectStore; + [SameObject] readonly attribute IDBObjectStore objectStore; [CallWith=ScriptState] readonly attribute any keyPath; readonly attribute boolean multiEntry; readonly attribute boolean unique; - [CallWith=ScriptState, RaisesException] IDBRequest get(any key); - [CallWith=ScriptState, RaisesException] IDBRequest getKey(any key); + [NewObject, CallWith=ScriptState, RaisesException] IDBRequest get(any key); + [NewObject, CallWith=ScriptState, RaisesException] IDBRequest getKey(any key); // TODO(cmumford): 0xFFFFFFFF is not necessary. Remove once crbug.com/335871 is fixed. - [CallWith=ScriptState, RaisesException] IDBRequest getAll([Default=Undefined] optional any range, [EnforceRange] optional unsigned long maxCount = 0xFFFFFFFF); + [NewObject, CallWith=ScriptState, RaisesException] IDBRequest getAll([Default=Undefined] optional any range, + [EnforceRange] optional unsigned long maxCount = 0xFFFFFFFF); // TODO(cmumford): 0xFFFFFFFF is not necessary. Remove once crbug.com/335871 is fixed. - [CallWith=ScriptState, RaisesException] IDBRequest getAllKeys([Default=Undefined] optional any range, [EnforceRange] optional unsigned long maxCount = 0xFFFFFFFF); - [CallWith=ScriptState, RaisesException] IDBRequest count([Default=Undefined] optional any key); - [CallWith=ScriptState, RaisesException] IDBRequest openCursor([Default=Undefined] optional any range, optional IDBCursorDirection direction = "next"); - [CallWith=ScriptState, RaisesException] IDBRequest openKeyCursor([Default=Undefined] optional any range, optional IDBCursorDirection direction = "next"); + [NewObject, CallWith=ScriptState, RaisesException] IDBRequest getAllKeys([Default=Undefined] optional any range, + [EnforceRange] optional unsigned long maxCount = 0xFFFFFFFF); + [NewObject, CallWith=ScriptState, RaisesException] IDBRequest count([Default=Undefined] optional any key); + [NewObject, CallWith=ScriptState, RaisesException] IDBRequest openCursor([Default=Undefined] optional any range, + optional IDBCursorDirection direction = "next"); + [NewObject, CallWith=ScriptState, RaisesException] IDBRequest openKeyCursor([Default=Undefined] optional any range, + optional IDBCursorDirection direction = "next"); };
diff --git a/third_party/WebKit/Source/modules/indexeddb/IDBKeyRange.idl b/third_party/WebKit/Source/modules/indexeddb/IDBKeyRange.idl index 2f34914..38eb019 100644 --- a/third_party/WebKit/Source/modules/indexeddb/IDBKeyRange.idl +++ b/third_party/WebKit/Source/modules/indexeddb/IDBKeyRange.idl
@@ -33,10 +33,13 @@ readonly attribute boolean lowerOpen; readonly attribute boolean upperOpen; - [CallWith=ScriptState, RaisesException] static IDBKeyRange only(any value); - [CallWith=ScriptState, RaisesException] static IDBKeyRange lowerBound(any bound, optional boolean open = false); - [CallWith=ScriptState, RaisesException] static IDBKeyRange upperBound(any bound, optional boolean open = false); - [CallWith=ScriptState, RaisesException] static IDBKeyRange bound(any lower, any upper, optional boolean lowerOpen = false, optional boolean upperOpen = false); + [NewObject, CallWith=ScriptState, RaisesException] static IDBKeyRange only(any value); + [NewObject, CallWith=ScriptState, RaisesException] static IDBKeyRange lowerBound(any bound, optional boolean open = false); + [NewObject, CallWith=ScriptState, RaisesException] static IDBKeyRange upperBound(any bound, optional boolean open = false); + [NewObject, CallWith=ScriptState, RaisesException] static IDBKeyRange bound(any lower, + any upper, + optional boolean lowerOpen = false, + optional boolean upperOpen = false); [CallWith=ScriptState, RaisesException] boolean includes(any key); };
diff --git a/third_party/WebKit/Source/modules/indexeddb/IDBObjectStore.cpp b/third_party/WebKit/Source/modules/indexeddb/IDBObjectStore.cpp index e535711..6c2834d 100644 --- a/third_party/WebKit/Source/modules/indexeddb/IDBObjectStore.cpp +++ b/third_party/WebKit/Source/modules/indexeddb/IDBObjectStore.cpp
@@ -381,6 +381,7 @@ options.blob_info = &blob_info; options.write_wasm_to_stream = ExecutionContext::From(script_state)->IsSecureContext(); + options.for_storage = true; RefPtr<SerializedScriptValue> serialized_value = SerializedScriptValue::Serialize(isolate, value.V8Value(), options, exception_state);
diff --git a/third_party/WebKit/Source/modules/indexeddb/IDBObjectStore.idl b/third_party/WebKit/Source/modules/indexeddb/IDBObjectStore.idl index 9f98ec0..2c4a8cd 100644 --- a/third_party/WebKit/Source/modules/indexeddb/IDBObjectStore.idl +++ b/third_party/WebKit/Source/modules/indexeddb/IDBObjectStore.idl
@@ -31,23 +31,31 @@ [RaisesException=Setter] attribute DOMString name; [CallWith=ScriptState] readonly attribute any keyPath; readonly attribute DOMStringList indexNames; - readonly attribute IDBTransaction transaction; + [SameObject] readonly attribute IDBTransaction transaction; readonly attribute boolean autoIncrement; - [CallWith=ScriptState, RaisesException] IDBRequest put(any value, [Default=Undefined] optional any key); - [CallWith=ScriptState, RaisesException] IDBRequest add(any value, [Default=Undefined] optional any key); - [CallWith=ScriptState, ImplementedAs=deleteFunction, RaisesException] IDBRequest delete(any key); - [CallWith=ScriptState, RaisesException] IDBRequest clear(); - [CallWith=ScriptState, RaisesException] IDBRequest get(any key); - [CallWith=ScriptState, RaisesException] IDBRequest getKey(any key); + [NewObject, CallWith=ScriptState, RaisesException] IDBRequest put(any value, [Default=Undefined] optional any key); + [NewObject, CallWith=ScriptState, RaisesException] IDBRequest add(any value, [Default=Undefined] optional any key); + [NewObject, CallWith=ScriptState, ImplementedAs=deleteFunction, RaisesException] IDBRequest delete(any key); + [NewObject, CallWith=ScriptState, RaisesException] IDBRequest clear(); + [NewObject, CallWith=ScriptState, RaisesException] IDBRequest get(any key); + [NewObject, CallWith=ScriptState, RaisesException] IDBRequest getKey(any key); // TODO(cmumford): 0xFFFFFFFF is not necessary. Remove once crbug.com/335871 is fixed. - [CallWith=ScriptState, RaisesException] IDBRequest getAll([Default=Undefined] optional any range, [EnforceRange] optional unsigned long maxCount = 0xFFFFFFFF); + [NewObject, CallWith=ScriptState, RaisesException] IDBRequest getAll([Default=Undefined] optional any range, + [EnforceRange] optional unsigned long maxCount = 0xFFFFFFFF); // TODO(cmumford): 0xFFFFFFFF is not necessary. Remove once crbug.com/335871 is fixed. - [CallWith=ScriptState, RaisesException] IDBRequest getAllKeys([Default=Undefined] optional any range, [EnforceRange] optional unsigned long maxCount = 0xFFFFFFFF); - [CallWith=ScriptState, RaisesException] IDBRequest count([Default=Undefined] optional any key); - [CallWith=ScriptState, RaisesException] IDBRequest openCursor([Default=Undefined] optional any range, optional IDBCursorDirection direction = "next"); - [CallWith=ScriptState, RaisesException] IDBRequest openKeyCursor([Default=Undefined] optional any range, optional IDBCursorDirection direction = "next"); - [CallWith=ScriptState, RaisesException] IDBIndex createIndex(DOMString name, (DOMString or sequence<DOMString>) keyPath, optional IDBIndexParameters options); + [NewObject, CallWith=ScriptState, RaisesException] IDBRequest getAllKeys([Default=Undefined] optional any range, + [EnforceRange] optional unsigned long maxCount = 0xFFFFFFFF); + [NewObject, CallWith=ScriptState, RaisesException] IDBRequest count([Default=Undefined] optional any key); + + [NewObject, CallWith=ScriptState, RaisesException] IDBRequest openCursor([Default=Undefined] optional any range, + optional IDBCursorDirection direction = "next"); + [NewObject, CallWith=ScriptState, RaisesException] IDBRequest openKeyCursor([Default=Undefined] optional any range, + optional IDBCursorDirection direction = "next"); + [RaisesException] IDBIndex index(DOMString name); + [NewObject, CallWith=ScriptState, RaisesException] IDBIndex createIndex(DOMString name, + (DOMString or sequence<DOMString>) keyPath, + optional IDBIndexParameters options); [RaisesException] void deleteIndex(DOMString name); };
diff --git a/third_party/WebKit/Source/modules/indexeddb/IDBRequest.idl b/third_party/WebKit/Source/modules/indexeddb/IDBRequest.idl index 7fbbbc04..ad3ea2f 100644 --- a/third_party/WebKit/Source/modules/indexeddb/IDBRequest.idl +++ b/third_party/WebKit/Source/modules/indexeddb/IDBRequest.idl
@@ -43,11 +43,8 @@ ] interface IDBRequest : EventTarget { [CallWith=ScriptState, RaisesException=Getter, CachedAttribute=isResultDirty] readonly attribute any result; [RaisesException=Getter] readonly attribute DOMException error; - [CallWith=ScriptState] readonly attribute any source; readonly attribute IDBTransaction transaction; - - // States readonly attribute IDBRequestReadyState readyState; // Events
diff --git a/third_party/WebKit/Source/modules/indexeddb/IDBTransaction.idl b/third_party/WebKit/Source/modules/indexeddb/IDBTransaction.idl index d35641a..cefcce2 100644 --- a/third_party/WebKit/Source/modules/indexeddb/IDBTransaction.idl +++ b/third_party/WebKit/Source/modules/indexeddb/IDBTransaction.idl
@@ -43,7 +43,7 @@ // Properties readonly attribute DOMStringList objectStoreNames; readonly attribute IDBTransactionMode mode; - readonly attribute IDBDatabase db; + [SameObject] readonly attribute IDBDatabase db; readonly attribute DOMException error; // Methods
diff --git a/third_party/WebKit/Source/modules/offscreencanvas2d/OffscreenCanvasRenderingContext2D.cpp b/third_party/WebKit/Source/modules/offscreencanvas2d/OffscreenCanvasRenderingContext2D.cpp index 47d43f0..a3f2088e 100644 --- a/third_party/WebKit/Source/modules/offscreencanvas2d/OffscreenCanvasRenderingContext2D.cpp +++ b/third_party/WebKit/Source/modules/offscreencanvas2d/OffscreenCanvasRenderingContext2D.cpp
@@ -26,7 +26,7 @@ ScriptState* script_state, OffscreenCanvas* canvas, const CanvasContextCreationAttributes& attrs) - : CanvasRenderingContext(nullptr, canvas, attrs) { + : CanvasRenderingContext(canvas, attrs) { ExecutionContext* execution_context = ExecutionContext::From(script_state); if (execution_context->IsDocument()) { if (ToDocument(execution_context) @@ -52,30 +52,19 @@ ExceptionState& exception_state) { UseCounter::Feature feature = UseCounter::kOffscreenCanvasCommit2D; UseCounter::Count(ExecutionContext::From(script_state), feature); - if (!offscreenCanvas()->HasPlaceholderCanvas()) { - // If an OffscreenCanvas has no associated canvas Id, it indicates that - // it is not an OffscreenCanvas created by transfering control from html - // canvas. - exception_state.ThrowDOMException( - kInvalidStateError, - "Commit() was called on a context whose " - "OffscreenCanvas is not associated with a " - "canvas element."); - return exception_state.Reject(script_state); - } - bool is_web_gl_software_rendering = false; - return offscreenCanvas()->Commit(TransferToStaticBitmapImage(), - is_web_gl_software_rendering, script_state); + return host()->Commit(TransferToStaticBitmapImage(), + is_web_gl_software_rendering, script_state, + exception_state); } // BaseRenderingContext2D implementation bool OffscreenCanvasRenderingContext2D::OriginClean() const { - return offscreenCanvas()->OriginClean(); + return host()->OriginClean(); } void OffscreenCanvasRenderingContext2D::SetOriginTainted() { - return offscreenCanvas()->SetOriginTainted(); + return host()->SetOriginTainted(); } bool OffscreenCanvasRenderingContext2D::WouldTaintOrigin( @@ -93,11 +82,11 @@ } int OffscreenCanvasRenderingContext2D::Width() const { - return offscreenCanvas()->width(); + return host()->Size().Width(); } int OffscreenCanvasRenderingContext2D::Height() const { - return offscreenCanvas()->height(); + return host()->Size().Height(); } bool OffscreenCanvasRenderingContext2D::HasImageBuffer() const { @@ -186,7 +175,7 @@ image_buffer_->NewSkImageSnapshot(kPreferNoAcceleration, reason); ImageData* image_data = nullptr; if (snapshot) { - image_data = ImageData::Create(offscreenCanvas()->Size()); + image_data = ImageData::Create(host()->Size()); SkImageInfo image_info = SkImageInfo::Make(this->Width(), this->Height(), kRGBA_8888_SkColorType, kUnpremul_SkAlphaType); @@ -232,11 +221,11 @@ void OffscreenCanvasRenderingContext2D::DidDraw(const SkIRect& dirty_rect) {} bool OffscreenCanvasRenderingContext2D::StateHasFilter() { - return GetState().HasFilterForOffscreenCanvas(offscreenCanvas()->Size()); + return GetState().HasFilterForOffscreenCanvas(host()->Size()); } sk_sp<SkImageFilter> OffscreenCanvasRenderingContext2D::StateGetFilter() { - return GetState().GetFilterForOffscreenCanvas(offscreenCanvas()->Size()); + return GetState().GetFilterForOffscreenCanvas(host()->Size()); } void OffscreenCanvasRenderingContext2D::ValidateStateStack() const {
diff --git a/third_party/WebKit/Source/modules/offscreencanvas2d/OffscreenCanvasRenderingContext2D.h b/third_party/WebKit/Source/modules/offscreencanvas2d/OffscreenCanvasRenderingContext2D.h index 440d987..ede146f 100644 --- a/third_party/WebKit/Source/modules/offscreencanvas2d/OffscreenCanvasRenderingContext2D.h +++ b/third_party/WebKit/Source/modules/offscreencanvas2d/OffscreenCanvasRenderingContext2D.h
@@ -37,6 +37,10 @@ } }; + OffscreenCanvas* offscreenCanvas() const { + DCHECK(!host() || host()->IsOffscreenCanvas()); + return static_cast<OffscreenCanvas*>(host()); + } ScriptPromise commit(ScriptState*, ExceptionState&); // CanvasRenderingContext implementation @@ -111,11 +115,12 @@ RefPtr<StaticBitmapImage> TransferToStaticBitmapImage(); }; +// TODO(fserb): remove this. DEFINE_TYPE_CASTS(OffscreenCanvasRenderingContext2D, CanvasRenderingContext, context, - context->Is2d() && context->offscreenCanvas(), - context.Is2d() && context.offscreenCanvas()); + context->Is2d() && context->host(), + context.Is2d() && context.host()); } // namespace blink
diff --git a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp index b1115150..cfaf7d2 100644 --- a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp +++ b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp
@@ -749,24 +749,10 @@ ExceptionState& exception_state) { UseCounter::Feature feature = UseCounter::kOffscreenCanvasCommitWebGL; UseCounter::Count(ExecutionContext::From(script_state), feature); - if (!offscreenCanvas()) { - exception_state.ThrowDOMException(kInvalidStateError, - "Commit() was called on a rendering " - "context that was not created from an " - "OffscreenCanvas."); - return exception_state.Reject(script_state); - } - // no HTMLCanvas associated, thrown InvalidStateError - if (!offscreenCanvas()->HasPlaceholderCanvas()) { - exception_state.ThrowDOMException( - kInvalidStateError, - "Commit() was called on a context whose " - "OffscreenCanvas is not associated with a " - "canvas element."); - return exception_state.Reject(script_state); - } if (!GetDrawingBuffer()) { - return offscreenCanvas()->Commit(nullptr, false, script_state); + bool is_web_gl_software_rendering = false; + return host()->Commit(nullptr, is_web_gl_software_rendering, script_state, + exception_state); } RefPtr<StaticBitmapImage> image; @@ -782,10 +768,10 @@ image = GetDrawingBuffer()->TransferToStaticBitmapImage(); } - return offscreenCanvas()->Commit( + return host()->Commit( std::move(image), GetDrawingBuffer()->ContextProvider()->IsSoftwareRendering(), - script_state); + script_state, exception_state); } PassRefPtr<Image> WebGLRenderingContextBase::GetImage( @@ -1002,43 +988,25 @@ } // namespace WebGLRenderingContextBase::WebGLRenderingContextBase( - OffscreenCanvas* passed_offscreen_canvas, + CanvasRenderingContextHost* host, std::unique_ptr<WebGraphicsContext3DProvider> context_provider, const CanvasContextCreationAttributes& requested_attributes, unsigned version) : WebGLRenderingContextBase( - nullptr, - passed_offscreen_canvas, + host, TaskRunnerHelper::Get(TaskType::kWebGL, - passed_offscreen_canvas->GetExecutionContext()), + host->GetTopExecutionContext()), std::move(context_provider), requested_attributes, version) {} WebGLRenderingContextBase::WebGLRenderingContextBase( - HTMLCanvasElement* passed_canvas, - std::unique_ptr<WebGraphicsContext3DProvider> context_provider, - const CanvasContextCreationAttributes& requested_attributes, - unsigned version) - : WebGLRenderingContextBase( - passed_canvas, - nullptr, - TaskRunnerHelper::Get(TaskType::kWebGL, - &passed_canvas->GetDocument()), - std::move(context_provider), - requested_attributes, - version) {} - -WebGLRenderingContextBase::WebGLRenderingContextBase( - HTMLCanvasElement* passed_canvas, - OffscreenCanvas* passed_offscreen_canvas, + CanvasRenderingContextHost* host, RefPtr<WebTaskRunner> task_runner, std::unique_ptr<WebGraphicsContext3DProvider> context_provider, const CanvasContextCreationAttributes& requested_attributes, unsigned version) - : CanvasRenderingContext(passed_canvas, - passed_offscreen_canvas, - requested_attributes), + : CanvasRenderingContext(host, requested_attributes), context_group_(this, new WebGLContextGroup()), is_hidden_(false), context_lost_mode_(kNotLostContext), @@ -1078,20 +1046,7 @@ max_viewport_dims_); RefPtr<DrawingBuffer> buffer; - // On Mac OS, DrawingBuffer is using an IOSurface as its backing storage, this - // allows WebGL-rendered canvases to be composited by the OS rather than - // Chrome. - // IOSurfaces are only compatible with the GL_TEXTURE_RECTANGLE_ARB binding - // target. So to avoid the knowledge of GL_TEXTURE_RECTANGLE_ARB type textures - // being introduced into more areas of the code, we use the code path of - // non-WebGLImageChromium for OffscreenCanvas. - // See detailed discussion in crbug.com/649668. - if (passed_offscreen_canvas) - buffer = CreateDrawingBuffer(std::move(context_provider), - DrawingBuffer::kDisallowChromiumImage); - else - buffer = CreateDrawingBuffer(std::move(context_provider), - DrawingBuffer::kAllowChromiumImage); + buffer = CreateDrawingBuffer(std::move(context_provider)); if (!buffer) { context_lost_mode_ = kSyntheticLostContext; return; @@ -1121,8 +1076,7 @@ } PassRefPtr<DrawingBuffer> WebGLRenderingContextBase::CreateDrawingBuffer( - std::unique_ptr<WebGraphicsContext3DProvider> context_provider, - DrawingBuffer::ChromiumImageUsage chromium_image_usage) { + std::unique_ptr<WebGraphicsContext3DProvider> context_provider) { bool premultiplied_alpha = CreationAttributes().premultipliedAlpha(); bool want_alpha_channel = CreationAttributes().alpha(); bool want_depth_buffer = CreationAttributes().depth(); @@ -1139,6 +1093,19 @@ } else { NOTREACHED(); } + + // On Mac OS, DrawingBuffer is using an IOSurface as its backing storage, this + // allows WebGL-rendered canvases to be composited by the OS rather than + // Chrome. + // IOSurfaces are only compatible with the GL_TEXTURE_RECTANGLE_ARB binding + // target. So to avoid the knowledge of GL_TEXTURE_RECTANGLE_ARB type textures + // being introduced into more areas of the code, we use the code path of + // non-WebGLImageChromium for OffscreenCanvas. + // See detailed discussion in crbug.com/649668. + DrawingBuffer::ChromiumImageUsage chromium_image_usage = + host()->IsOffscreenCanvas() ? DrawingBuffer::kDisallowChromiumImage + : DrawingBuffer::kAllowChromiumImage; + return DrawingBuffer::Create( std::move(context_provider), this, ClampedCanvasSize(), premultiplied_alpha, want_alpha_channel, want_depth_buffer, @@ -4146,7 +4113,7 @@ return; // Due to WebGL's same-origin restrictions, it is not possible to // taint the origin using the WebGL API. - DCHECK(canvas() ? canvas()->OriginClean() : offscreenCanvas()->OriginClean()); + DCHECK(host()->OriginClean()); // Validate input parameters. if (!pixels) { @@ -7483,10 +7450,7 @@ void WebGLRenderingContextBase::DispatchContextLostEvent(TimerBase*) { WebGLContextEvent* event = WebGLContextEvent::Create( EventTypeNames::webglcontextlost, false, true, ""); - if (offscreenCanvas()) - offscreenCanvas()->DispatchEvent(event); - else - canvas()->DispatchEvent(event); + host()->HostDispatchEvent(event); restore_allowed_ = event->defaultPrevented(); if (restore_allowed_ && !is_hidden_) { if (auto_recovery_method_ == kAuto) @@ -7526,16 +7490,14 @@ drawing_buffer_.Clear(); } - auto execution_context = canvas() - ? canvas()->GetDocument().GetExecutionContext() - : offscreenCanvas()->GetExecutionContext(); + auto execution_context = host()->GetTopExecutionContext(); Platform::ContextAttributes attributes = ToPlatformContextAttributes( CreationAttributes(), Version(), SupportOwnOffscreenSurface(execution_context)); Platform::GraphicsInfo gl_info; std::unique_ptr<WebGraphicsContext3DProvider> context_provider; - const auto& url = canvas() ? canvas()->GetDocument().TopDocument().Url() - : offscreenCanvas()->GetExecutionContext()->Url(); + const auto& url = host()->GetExecutionContextUrl(); + if (IsMainThread()) { context_provider = WTF::WrapUnique( Platform::Current()->CreateOffscreenGraphicsContext3DProvider( @@ -7547,14 +7509,7 @@ RefPtr<DrawingBuffer> buffer; if (context_provider && context_provider->BindToCurrentThread()) { // Construct a new drawing buffer with the new GL context. - if (canvas()) { - buffer = CreateDrawingBuffer(std::move(context_provider), - DrawingBuffer::kAllowChromiumImage); - } else { - // Please refer to comment at Line 1040 in this file. - buffer = CreateDrawingBuffer(std::move(context_provider), - DrawingBuffer::kDisallowChromiumImage); - } + buffer = CreateDrawingBuffer(std::move(context_provider)); // If DrawingBuffer::create() fails to allocate a fbo, |drawingBuffer| is // set to null. } @@ -7587,10 +7542,7 @@ MarkContextChanged(kCanvasContextChanged); WebGLContextEvent* event = WebGLContextEvent::Create( EventTypeNames::webglcontextrestored, false, true, ""); - if (canvas()) - canvas()->DispatchEvent(event); - else - offscreenCanvas()->DispatchEvent(event); + host()->HostDispatchEvent(event); } String WebGLRenderingContextBase::EnsureNotNull(const String& text) const { @@ -7711,14 +7663,8 @@ } IntSize WebGLRenderingContextBase::ClampedCanvasSize() const { - int width, height; - if (canvas()) { - width = canvas()->width(); - height = canvas()->height(); - } else { - width = offscreenCanvas()->width(); - height = offscreenCanvas()->height(); - } + int width = host()->Size().Width(); + int height = host()->Size().Height(); return IntSize(Clamp(width, 1, max_viewport_dims_[0]), Clamp(height, 1, max_viewport_dims_[1])); } @@ -7876,10 +7822,11 @@ void WebGLRenderingContextBase::getHTMLOrOffscreenCanvas( HTMLCanvasElementOrOffscreenCanvas& result) const { - if (canvas()) - result.setHTMLCanvasElement(canvas()); - else - result.setOffscreenCanvas(offscreenCanvas()); + if (canvas()) { + result.setHTMLCanvasElement(static_cast<HTMLCanvasElement*>(host())); + } else { + result.setOffscreenCanvas(static_cast<OffscreenCanvas*>(host())); + } } } // namespace blink
diff --git a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.h b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.h index d8855b5..1e72043 100644 --- a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.h +++ b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.h
@@ -127,6 +127,12 @@ public: ~WebGLRenderingContextBase() override; + HTMLCanvasElement* canvas() const { + if (host()->IsOffscreenCanvas()) + return nullptr; + return static_cast<HTMLCanvasElement*>(host()); + } + virtual String ContextName() const = 0; virtual void RegisterContextExtensions() = 0; @@ -618,17 +624,12 @@ friend class ScopedFramebufferRestorer; friend class ScopedUnpackParametersResetRestore; - WebGLRenderingContextBase(HTMLCanvasElement*, - std::unique_ptr<WebGraphicsContext3DProvider>, - const CanvasContextCreationAttributes&, - unsigned); - WebGLRenderingContextBase(OffscreenCanvas*, + WebGLRenderingContextBase(CanvasRenderingContextHost*, std::unique_ptr<WebGraphicsContext3DProvider>, const CanvasContextCreationAttributes&, unsigned); PassRefPtr<DrawingBuffer> CreateDrawingBuffer( - std::unique_ptr<WebGraphicsContext3DProvider>, - DrawingBuffer::ChromiumImageUsage); + std::unique_ptr<WebGraphicsContext3DProvider>); void SetupFlags(); // CanvasRenderingContext implementation. @@ -1652,8 +1653,7 @@ GLuint offset); private: - WebGLRenderingContextBase(HTMLCanvasElement*, - OffscreenCanvas*, + WebGLRenderingContextBase(CanvasRenderingContextHost*, RefPtr<WebTaskRunner>, std::unique_ptr<WebGraphicsContext3DProvider>, const CanvasContextCreationAttributes&, @@ -1685,6 +1685,7 @@ bool IsPaintable() const final { return GetDrawingBuffer(); } }; +// TODO(fserb): remove this. DEFINE_TYPE_CASTS(WebGLRenderingContextBase, CanvasRenderingContext, context,
diff --git a/third_party/WebKit/Source/web/tests/MHTMLTest.cpp b/third_party/WebKit/Source/web/tests/MHTMLTest.cpp index 494f071..e303756 100644 --- a/third_party/WebKit/Source/web/tests/MHTMLTest.cpp +++ b/third_party/WebKit/Source/web/tests/MHTMLTest.cpp
@@ -35,6 +35,7 @@ #include "platform/SerializedResource.h" #include "platform/SharedBuffer.h" #include "platform/mhtml/MHTMLArchive.h" +#include "platform/mhtml/MHTMLParser.h" #include "platform/testing/URLTestHelpers.h" #include "platform/testing/UnitTestHelpers.h" #include "platform/weborigin/KURL.h" @@ -161,6 +162,15 @@ } MHTMLArchive::GenerateMHTMLFooterForTesting(boundary, *mhtml_data->MutableData()); + + // Validate the generated MHTML. + MHTMLParser parser( + SharedBuffer::Create(mhtml_data->data(), mhtml_data->length())); + if (parser.ParseArchive().IsEmpty()) { + ADD_FAILURE() << "Invalid MHTML"; + return RawData::Create(); + } + return mhtml_data.Release(); } @@ -206,6 +216,7 @@ AddTestResources(); RefPtr<RawData> data = Serialize("Test Serialization", "text/html", MHTMLArchive::kUseDefaultEncoding); + ASSERT_FALSE(HasFailure()); // Read the MHTML data line per line and do some pseudo-parsing to make sure // the right encoding is used for the different sections. @@ -242,6 +253,8 @@ AddTestResources(); RefPtr<RawData> raw_data = Serialize("Test Serialization", "text/html", MHTMLArchive::kUseDefaultEncoding); + ASSERT_FALSE(HasFailure()); + RefPtr<SharedBuffer> data = SharedBuffer::Create(raw_data->data(), raw_data->length()); KURL http_url = ToKURL("http://www.example.com");
diff --git a/third_party/libaddressinput/README.chromium b/third_party/libaddressinput/README.chromium index c6b2068c..a44f4cc 100644 --- a/third_party/libaddressinput/README.chromium +++ b/third_party/libaddressinput/README.chromium
@@ -6,7 +6,7 @@ Revision: 4d18a0d4be9add0dc479e7b939ed8d39f6ec0d73 License: Apache 2.0 License File: LICENSE -Security Critical: no +Security Critical: yes Description:
diff --git a/third_party/libwebm/README.chromium b/third_party/libwebm/README.chromium index 51cd120..7d3b804 100644 --- a/third_party/libwebm/README.chromium +++ b/third_party/libwebm/README.chromium
@@ -4,7 +4,7 @@ Version: unknown License: BSD License File: source/LICENSE.TXT -Security Critical: No +Security Critical: yes Description: libwebm is a library to read and write WebM files. It's used by MediaStream
diff --git a/tools/android/eclipse/.classpath b/tools/android/eclipse/.classpath index c124299..3a0c57c 100644 --- a/tools/android/eclipse/.classpath +++ b/tools/android/eclipse/.classpath
@@ -51,6 +51,7 @@ <classpathentry kind="src" path="components/cronet/android/test/javatests/src"/> <classpathentry kind="src" path="components/cronet/android/test/src"/> <classpathentry kind="src" path="components/gcm_driver/android/java/src"/> + <classpathentry kind="src" path="components/feature_engagement_tracker/public/android/java/src"/> <classpathentry kind="src" path="components/invalidation/impl/android/java/src"/> <classpathentry kind="src" path="components/invalidation/impl/android/javatests/src"/> <classpathentry kind="src" path="components/invalidation/impl/android/junit/src"/>
diff --git a/tools/binary_size/diagnose_apk_bloat.py b/tools/binary_size/diagnose_apk_bloat.py index e31ae24..a49f5b7 100755 --- a/tools/binary_size/diagnose_apk_bloat.py +++ b/tools/binary_size/diagnose_apk_bloat.py
@@ -44,6 +44,10 @@ _global_restore_checkout_func = lambda: _GitCmd(['checkout', branch], subrepo) +_DiffResult = collections.namedtuple( + 'DiffResult', ['name', 'value', 'units']) + + class BaseDiff(object): """Base class capturing binary size diffs.""" def __init__(self, name): @@ -58,6 +62,10 @@ _PrintAndWriteToFile(logfile, '\nDetails:') _PrintAndWriteToFile(logfile, self.DetailedResults()) + @property + def summary_stat(self): + return None + def Summary(self): """A short description that summarizes the source of binary size bloat.""" raise NotImplementedError() @@ -79,6 +87,9 @@ _RE_SUMMARY = re.compile( r'.*(Section Sizes .*? object files added, \d+ removed).*', flags=re.DOTALL) + _RE_SUMMARY_STAT = re.compile( + r'Section Sizes \(Total=(?P<value>\d+) (?P<units>\w+)\)') + _SUMMARY_STAT_NAME = 'Native Library Delta' def __init__(self, size_name, supersize_path): self._size_name = size_name @@ -86,6 +97,14 @@ self._diff = [] super(NativeDiff, self).__init__('Native Diff') + @property + def summary_stat(self): + m = NativeDiff._RE_SUMMARY_STAT.search(self._diff) + if m: + return _DiffResult( + NativeDiff._SUMMARY_STAT_NAME, m.group('value'), m.group('units')) + return None + def DetailedResults(self): return self._diff.splitlines() @@ -99,10 +118,6 @@ self._diff = _RunCmd(cmd)[0].replace('{', '{{').replace('}', '}}') -_ResourceSizesDiffResult = collections.namedtuple( - 'ResourceSizesDiffResult', ['section', 'value', 'units']) - - class ResourceSizesDiff(BaseDiff): _RESOURCE_SIZES_PATH = os.path.join( _SRC_ROOT, 'build', 'android', 'resource_sizes.py') @@ -113,15 +128,20 @@ self._diff = None # Set by |ProduceDiff()| super(ResourceSizesDiff, self).__init__('Resource Sizes Diff') + @property + def summary_stat(self): + for s in self._diff: + if 'normalized' in s.name: + return s + return None + def DetailedResults(self): - return ['{:>+10,} {} {}'.format(value, units, section) - for section, value, units in self._diff] + return ['{:>+10,} {} {}'.format(value, units, name) + for name, value, units in self._diff] def Summary(self): - for s in self._diff: - if 'normalized' in s.section: - return 'Normalized APK size: {:+,} {}'.format(s.value, s.units) - return '' + return 'Normalized APK size: {:+,} {}'.format( + self.summary_stat.value, self.summary_stat.units) def ProduceDiff(self, archive_dirs): chartjsons = self._RunResourceSizes(archive_dirs) @@ -138,7 +158,7 @@ 'skipping {} {}', section, subsection) else: diff.append( - _ResourceSizesDiffResult( + _DiffResult( '%s %s' % (section, subsection), v['value'] - without_patch[section][subsection]['value'], v['units'])) @@ -307,6 +327,7 @@ for rev in revs] self.diffs = diffs self.subrepo = subrepo + self._summary_stats = [] def IterArchives(self): return iter(self.build_archives) @@ -333,8 +354,32 @@ with open(diff_path, 'a') as diff_file: for d in self.diffs: d.RunDiff(diff_file, archive_dirs) - _Print('See detailed diff results here: {}.', diff_path) + _Print('\nSee detailed diff results here: {}.', diff_path) _WriteMetadata(metadata) + self._AddDiffSummaryStat(archives) + + def Summarize(self): + if self._summary_stats: + path = os.path.join(self.archive_dir, 'last_diff_summary.txt') + with open(path, 'w') as f: + stats = sorted( + self._summary_stats, key=lambda x: x[0].value, reverse=True) + _PrintAndWriteToFile(f, '\nDiff Summary') + for s, before, after in stats: + _PrintAndWriteToFile(f, '{:>+10} {} {} for range: {}..{}', + s.value, s.units, s.name, before, after) + + def _AddDiffSummaryStat(self, archives): + stat = None + if self.build.IsAndroid(): + summary_diff_type = ResourceSizesDiff + else: + summary_diff_type = NativeDiff + for d in self.diffs: + if isinstance(d, summary_diff_type): + stat = d.summary_stat + if stat: + self._summary_stats.append((stat, archives[1].rev, archives[0].rev)) def _CanDiff(self, archives): return all(a.Exists() for a in archives) @@ -346,8 +391,8 @@ return os.path.join(self._DiffDir(archives), 'metadata.txt') def _DiffDir(self, archives): - diff_path = os.path.join( - self.archive_dir, 'diffs', '_'.join(a.rev for a in archives)) + archive_range = '%s..%s' % (archives[1].rev, archives[0].rev) + diff_path = os.path.join(self.archive_dir, 'diffs', archive_range) _EnsureDirsExist(diff_path) return diff_path @@ -569,9 +614,10 @@ print s.format(*args, **kwargs) -def _PrintAndWriteToFile(logfile, s): +def _PrintAndWriteToFile(logfile, s, *args, **kwargs): """Write and print |s| thottling output if |s| is a large list.""" if isinstance(s, basestring): + s = s.format(*args, **kwargs) _Print(s) logfile.write('%s\n' % s) else: @@ -707,6 +753,8 @@ if i != 0: diff_mngr.MaybeDiff(i - 1, i) + diff_mngr.Summarize() + _global_restore_checkout_func() if __name__ == '__main__':
diff --git a/tools/json_schema_compiler/cc_generator.py b/tools/json_schema_compiler/cc_generator.py index 0cde6cab..b434df5 100644 --- a/tools/json_schema_compiler/cc_generator.py +++ b/tools/json_schema_compiler/cc_generator.py
@@ -888,8 +888,7 @@ dst_var, failure_value)) elif underlying_type.property_type == PropertyType.BINARY: - (c.Append('const base::Value* binary_value = NULL;') - .Sblock('if (!%(src_var)s->IsType(base::Value::Type::BINARY)) {') + (c.Sblock('if (!%(src_var)s->IsType(base::Value::Type::BINARY)) {') .Concat(self._GenerateError( '"\'%%(key)s\': expected binary, got " + ' + self._util_cc_helper.GetValueTypeString('%%(src_var)s', True))) @@ -898,19 +897,12 @@ c.Append('return %(failure_value)s;') (c.Eblock('}') .Sblock('else {') - .Append(' binary_value =') - .Append(' static_cast<const base::Value*>(%(src_var)s);') ) if is_ptr: - (c.Append('%(dst_var)s.reset(new std::vector<char>(') - .Append(' binary_value->GetBuffer(),') - .Append(' binary_value->GetBuffer() + binary_value->GetSize()));') - ) + c.Append( + '%(dst_var)s.reset(new std::vector<char>(%(src_var)s->GetBlob()));') else: - (c.Append('%(dst_var)s.assign(') - .Append(' binary_value->GetBuffer(),') - .Append(' binary_value->GetBuffer() + binary_value->GetSize());') - ) + c.Append('%(dst_var)s = %(src_var)s->GetBlob();') c.Eblock('}') else: raise NotImplementedError(type_)
diff --git a/tools/json_schema_compiler/util.cc b/tools/json_schema_compiler/util.cc index 983dc66..441fc25 100644 --- a/tools/json_schema_compiler/util.cc +++ b/tools/json_schema_compiler/util.cc
@@ -69,20 +69,18 @@ } bool PopulateItem(const base::Value& from, std::vector<char>* out) { - const base::Value* binary = nullptr; - if (!from.GetAsBinary(&binary)) + if (!from.is_blob()) return false; - out->assign(binary->GetBuffer(), binary->GetBuffer() + binary->GetSize()); + *out = from.GetBlob(); return true; } bool PopulateItem(const base::Value& from, std::vector<char>* out, base::string16* error) { - const base::Value* binary = nullptr; - if (!from.GetAsBinary(&binary)) + if (!from.is_blob()) return ReportError(from, base::Value::Type::BINARY, error); - out->assign(binary->GetBuffer(), binary->GetBuffer() + binary->GetSize()); + *out = from.GetBlob(); return true; }
diff --git a/tools/mb/mb_unittest.py b/tools/mb/mb_unittest.py index 690b5a2b..29b75cf 100755 --- a/tools/mb/mb_unittest.py +++ b/tools/mb/mb_unittest.py
@@ -558,26 +558,3 @@ if __name__ == '__main__': unittest.main() - - def test_validate(self): - mbw = self.fake_mbw() - self.check(['validate'], mbw=mbw, ret=0) - - def test_bad_validate(self): - mbw = self.fake_mbw() - mbw.files[mbw.default_config] = TEST_BAD_CONFIG - self.check(['validate'], mbw=mbw, ret=1) - - def test_gyp_env_hacks(self): - mbw = self.fake_mbw() - mbw.files[mbw.default_config] = GYP_HACKS_CONFIG - self.check(['lookup', '-c', 'fake_config'], mbw=mbw, - ret=0, - out=("GYP_DEFINES='foo=bar baz=1'\n" - "GYP_LINK_CONCURRENCY=1\n" - "LLVM_FORCE_HEAD_REVISION=1\n" - "python build/gyp_chromium -G output_dir=_path_\n")) - - -if __name__ == '__main__': - unittest.main()
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index 1c64fa2..f8590d48 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -2283,6 +2283,26 @@ </summary> </histogram> +<histogram name="Ash.Wallpaper.ColorExtraction.Durations" units="ms"> + <owner>bruthig@chromium.org</owner> + <owner>tbuckley@chromium.org</owner> + <summary> + The time taken to extract colors from wallpapers. Recorded each time the + wallpaper image changes. + </summary> +</histogram> + +<histogram name="Ash.Wallpaper.ColorExtraction.UserDelay" units="ms"> + <owner>bruthig@chromium.org</owner> + <owner>tbuckley@chromium.org</owner> + <summary> + The time taken to extract colors from 'expensive' wallpapers. Recorded each + time the wallpaper image changes and the color extraction is expected to be + expensive, e.g. image size > 100 pixels. This includes time spent + switching threads. + </summary> +</histogram> + <histogram name="Ash.Wallpaper.ColorExtractionResult" enum="BooleanSuccess"> <owner>bruthig@chromium.org</owner> <owner>tbuckley@chromium.org</owner> @@ -2321,11 +2341,17 @@ </histogram> <histogram name="Ash.Wallpaper.TimeSpentExtractingColors" units="ms"> + <obsolete> + Deprecated as of 04/2017 in favor of Ash.Wallpaper.ColorExtraction.Durations + and Ash.Wallpaper.ColorExtraction.UserDelay. + </obsolete> <owner>bruthig@chromium.org</owner> <owner>tbuckley@chromium.org</owner> <summary> The time taken to extract colors from wallpapers. Recorded each time the - wallpaper image changes. + wallpaper image changes. NOTE, this measure also included the time spent + jumping between threads, thus it was deprecated in favor of + Ash.Wallpaper.ColorExtraction.Durations. </summary> </histogram> @@ -92589,6 +92615,7 @@ <int value="364" label="DeviceLoginScreenLocales"/> <int value="365" label="DeviceLoginScreenInputMethods"/> <int value="366" label="EnableCommonNameFallbackForLocalAnchors"/> + <int value="367" label="InstantTetheringAllowed"/> </enum> <enum name="EnterprisePolicyInvalidations" type="int">
diff --git a/tools/perf/benchmarks/benchmark_unittest.py b/tools/perf/benchmarks/benchmark_unittest.py index d35d012..8226eaa 100644 --- a/tools/perf/benchmarks/benchmark_unittest.py +++ b/tools/perf/benchmarks/benchmark_unittest.py
@@ -11,6 +11,7 @@ from core import perf_benchmark from telemetry import benchmark as benchmark_module +from telemetry import decorators from telemetry.core import discover from telemetry.internal.browser import browser_options from telemetry.testing import progress_reporter @@ -45,6 +46,24 @@ 'Multiple benchmarks with the same name %s are ' 'found: %s' % (n, str(names_to_benchmarks[n]))) +class TestBenchmarkNamingMobile(unittest.TestCase): + + def runTest(self): + all_benchmarks = _GetAllPerfBenchmarks() + names_to_benchmarks = defaultdict(list) + for b in all_benchmarks: + names_to_benchmarks[b.Name()] = b + + for n, bench in names_to_benchmarks.items(): + if 'mobile' in n: + enabled_tags = decorators.GetEnabledAttributes(bench) + disabled_tags = decorators.GetDisabledAttributes(bench) + + self.assertTrue('all' in disabled_tags or 'android' in enabled_tags, + ','.join([ + str(bench), bench.Name(), + str(disabled_tags), str(enabled_tags)])) + class TestNoOverrideCustomizeBrowserOptions(unittest.TestCase):
diff --git a/tools/perf/benchmarks/rasterize_and_record_micro.py b/tools/perf/benchmarks/rasterize_and_record_micro.py index 103b06e0..caf9bd5 100644 --- a/tools/perf/benchmarks/rasterize_and_record_micro.py +++ b/tools/perf/benchmarks/rasterize_and_record_micro.py
@@ -60,7 +60,7 @@ return 'rasterize_and_record_micro.top_25' -@benchmark.Disabled('mac', 'win', 'android') # http://crbug.com/531597 +@benchmark.Disabled('all') # http://crbug.com/531597 class RasterizeAndRecordMicroKeyMobileSites(_RasterizeAndRecordMicro): """Measures rasterize and record performance on the key mobile sites.
diff --git a/tools/perf/benchmarks/v8_browsing.py b/tools/perf/benchmarks/v8_browsing.py index bf51f66..45322cdd 100644 --- a/tools/perf/benchmarks/v8_browsing.py +++ b/tools/perf/benchmarks/v8_browsing.py
@@ -142,27 +142,9 @@ return True -class _V8DesktopBrowsingBenchmark(_V8BrowsingBenchmark): - - @classmethod - def ShouldDisable(cls, possible_browser): - # http://crbug.com/628736 - if (possible_browser.platform.GetOSName() == 'mac' and - possible_browser.browser_type == 'reference'): - return True - - return possible_browser.platform.GetDeviceTypeName() != 'Desktop' - - -class _V8MobileBrowsingBenchmark(_V8BrowsingBenchmark): - - @classmethod - def ShouldDisable(cls, possible_browser): - return possible_browser.platform.GetDeviceTypeName() == 'Desktop' - - @benchmark.Owner(emails=['ulan@chromium.org']) -class V8DesktopBrowsingBenchmark(_V8DesktopBrowsingBenchmark): +@benchmark.Disabled('android') +class V8DesktopBrowsingBenchmark(_V8BrowsingBenchmark): PLATFORM = 'desktop' @classmethod @@ -171,8 +153,9 @@ @benchmark.Owner(emails=['ulan@chromium.org']) +@benchmark.Enabled('android') @benchmark.Disabled('reference') # http://crbug.com/628631 -class V8MobileBrowsingBenchmark(_V8MobileBrowsingBenchmark): +class V8MobileBrowsingBenchmark(_V8BrowsingBenchmark): PLATFORM = 'mobile' @classmethod @@ -181,9 +164,10 @@ @benchmark.Disabled('reference') # http://crbug.com/700390 +@benchmark.Disabled('android') @benchmark.Disabled('all') @benchmark.Owner(emails=['mvstaton@chromium.org']) -class V8DesktopTurboBrowsingBenchmark(_V8DesktopBrowsingBenchmark): +class V8DesktopTurboBrowsingBenchmark(_V8BrowsingBenchmark): PLATFORM = 'desktop' def SetExtraBrowserOptions(self, options): @@ -198,9 +182,10 @@ @benchmark.Disabled('reference') # http://crbug.com/628631 +@benchmark.Enabled('android') @benchmark.Disabled('all') @benchmark.Owner(emails=['mvstaton@chromium.org']) -class V8MobileTurboBrowsingBenchmark(_V8MobileBrowsingBenchmark): +class V8MobileTurboBrowsingBenchmark(_V8BrowsingBenchmark): PLATFORM = 'mobile' def SetExtraBrowserOptions(self, options): @@ -214,8 +199,9 @@ @benchmark.Disabled('reference') # http://crbug.com/700390 +@benchmark.Disabled('android') @benchmark.Owner(emails=['hablich@chromium.org']) -class V8DesktopClassicBrowsingBenchmark(_V8DesktopBrowsingBenchmark): +class V8DesktopClassicBrowsingBenchmark(_V8BrowsingBenchmark): PLATFORM = 'desktop' def SetExtraBrowserOptions(self, options): @@ -229,8 +215,9 @@ @benchmark.Disabled('reference') # http://crbug.com/628631 +@benchmark.Enabled('android') @benchmark.Owner(emails=['hablich@chromium.org']) -class V8MobileClassicBrowsingBenchmark(_V8MobileBrowsingBenchmark): +class V8MobileClassicBrowsingBenchmark(_V8BrowsingBenchmark): PLATFORM = 'mobile' def SetExtraBrowserOptions(self, options): @@ -245,20 +232,18 @@ @benchmark.Owner(emails=['mythria@chromium.org']) @benchmark.Disabled('win') # http://crbug.com/704197 +@benchmark.Disabled('android') class V8RuntimeStatsDesktopBrowsingBenchmark( _V8RuntimeStatsBrowsingBenchmark): PLATFORM = 'desktop' @classmethod - def ShouldDisable(cls, possible_browser): - return possible_browser.platform.GetDeviceTypeName() != 'Desktop' - - @classmethod def Name(cls): return 'v8.runtimestats.browsing_desktop' @benchmark.Disabled('reference') # http://crbug.com/700390 +@benchmark.Disabled('android') @benchmark.Disabled('all') @benchmark.Owner(emails=['mythria@chromium.org']) class V8RuntimeStatsDesktopTurboBrowsingBenchmark( @@ -271,16 +256,13 @@ v8_helper.EnableTurbo(options) @classmethod - def ShouldDisable(cls, possible_browser): - return possible_browser.platform.GetDeviceTypeName() != 'Desktop' - - @classmethod def Name(cls): return 'v8.runtimestats.browsing_desktop_turbo' @benchmark.Disabled('reference', # http://crbug.com/700390 'win') # http://crbug.com/704197 +@benchmark.Disabled('android') @benchmark.Owner(emails=['hablich@chromium.org']) class V8RuntimeStatsDesktopClassicBrowsingBenchmark( _V8RuntimeStatsBrowsingBenchmark): @@ -292,31 +274,25 @@ v8_helper.EnableClassic(options) @classmethod - def ShouldDisable(cls, possible_browser): - return possible_browser.platform.GetDeviceTypeName() != 'Desktop' - - @classmethod def Name(cls): return 'v8.runtimestats.browsing_desktop_classic' @benchmark.Disabled('reference') # http://crbug.com/694658 +@benchmark.Enabled('android') @benchmark.Owner(emails=['mythria@chromium.org']) class V8RuntimeStatsMobileBrowsingBenchmark( _V8RuntimeStatsBrowsingBenchmark): PLATFORM = 'mobile' @classmethod - def ShouldDisable(cls, possible_browser): - return possible_browser.platform.GetDeviceTypeName() == 'Desktop' - - @classmethod def Name(cls): return 'v8.runtimestats.browsing_mobile' @benchmark.Disabled('reference') # http://crbug.com/694658 +@benchmark.Enabled('android') @benchmark.Disabled('all') @benchmark.Owner(emails=['mythria@chromium.org']) class V8RuntimeStatsMobileTurboBrowsingBenchmark( @@ -329,15 +305,12 @@ v8_helper.EnableTurbo(options) @classmethod - def ShouldDisable(cls, possible_browser): - return possible_browser.platform.GetDeviceTypeName() == 'Desktop' - - @classmethod def Name(cls): return 'v8.runtimestats.browsing_mobile_turbo' @benchmark.Disabled('reference') # http://crbug.com/694658 +@benchmark.Enabled('android') @benchmark.Owner(emails=['hablich@chromium.org']) class V8RuntimeStatsMobileClassicBrowsingBenchmark( _V8RuntimeStatsBrowsingBenchmark): @@ -349,9 +322,5 @@ v8_helper.EnableClassic(options) @classmethod - def ShouldDisable(cls, possible_browser): - return possible_browser.platform.GetDeviceTypeName() == 'Desktop' - - @classmethod def Name(cls): return 'v8.runtimestats.browsing_mobile_classic'
diff --git a/ui/android/java/src/org/chromium/ui/base/EventForwarder.java b/ui/android/java/src/org/chromium/ui/base/EventForwarder.java index 1ffb77f..77189db2 100644 --- a/ui/android/java/src/org/chromium/ui/base/EventForwarder.java +++ b/ui/android/java/src/org/chromium/ui/base/EventForwarder.java
@@ -23,6 +23,8 @@ private float mCurrentTouchOffsetX; private float mCurrentTouchOffsetY; + private int mLastMouseButtonState; + @CalledByNative private static EventForwarder create(long nativeEventForwarder) { return new EventForwarder(nativeEventForwarder); @@ -154,12 +156,42 @@ try { int eventAction = event.getActionMasked(); + if (eventAction == MotionEvent.ACTION_BUTTON_PRESS + || eventAction == MotionEvent.ACTION_BUTTON_RELEASE) { + mLastMouseButtonState = event.getButtonState(); + } + // Work around Samsung Galaxy Tab 2 not sending ACTION_BUTTON_RELEASE on left-click: + // http://crbug.com/714230. On ACTION_HOVER, no button can be pressed, so send a + // synthetic ACTION_BUTTON_RELEASE if it was missing. Note that all + // ACTION_BUTTON_RELEASE are always fired before any hover events on a correctly + // behaving device, so mLastMouseButtonState is only nonzero on a buggy one. + if (eventAction == MotionEvent.ACTION_HOVER_ENTER) { + if (mLastMouseButtonState == MotionEvent.BUTTON_PRIMARY) { + sendMouseEvent(event.getEventTime(), MotionEvent.ACTION_BUTTON_RELEASE, + offsetEvent.getX(), offsetEvent.getY(), event.getPointerId(0), + event.getPressure(0), event.getOrientation(0), + event.getAxisValue(MotionEvent.AXIS_TILT, 0), + MotionEvent.BUTTON_PRIMARY, event.getButtonState(), + event.getMetaState(), event.getToolType(0)); + } + mLastMouseButtonState = 0; + } + + // Ignore ACTION_HOVER_ENTER & ACTION_HOVER_EXIT because every mouse-down on Android + // follows a hover-exit and is followed by a hover-enter. crbug.com/715114 filed on + // distinguishing actual hover enter/exit from these bogus ones. + if (eventAction == MotionEvent.ACTION_HOVER_ENTER + || eventAction == MotionEvent.ACTION_HOVER_EXIT) { + return false; + } + // For mousedown and mouseup events, we use ACTION_BUTTON_PRESS // and ACTION_BUTTON_RELEASE respectively because they provide // info about the changed-button. if (eventAction == MotionEvent.ACTION_DOWN || eventAction == MotionEvent.ACTION_UP) { return false; } + sendMouseEvent(event.getEventTime(), eventAction, offsetEvent.getX(), offsetEvent.getY(), event.getPointerId(0), event.getPressure(0), event.getOrientation(0), event.getAxisValue(MotionEvent.AXIS_TILT, 0),
diff --git a/ui/app_list/app_list_switches.cc b/ui/app_list/app_list_switches.cc index c583832..0f6d670 100644 --- a/ui/app_list/app_list_switches.cc +++ b/ui/app_list/app_list_switches.cc
@@ -26,6 +26,9 @@ // If set, the app list will be enabled as if enabled from CWS. const char kEnableAppList[] = "enable-app-list"; +// Enables the fullscreen app list. +extern const char kEnableFullscreenAppList[] = "enable-fullscreen-app-list"; + // Enable/disable syncing of the app list independent of extensions. const char kEnableSyncAppList[] = "enable-sync-app-list"; const char kDisableSyncAppList[] = "disable-sync-app-list"; @@ -87,5 +90,10 @@ return !AnswerServerUrl().empty(); } +bool IsFullscreenAppListEnabled() { + return base::CommandLine::ForCurrentProcess()->HasSwitch( + kEnableFullscreenAppList); +} + } // namespace switches } // namespace app_list
diff --git a/ui/app_list/app_list_switches.h b/ui/app_list/app_list_switches.h index d4fc5fb..b3cc9a9 100644 --- a/ui/app_list/app_list_switches.h +++ b/ui/app_list/app_list_switches.h
@@ -18,6 +18,7 @@ APP_LIST_EXPORT extern const char kCustomLauncherPage[]; APP_LIST_EXPORT extern const char kDisableAppListDismissOnBlur[]; APP_LIST_EXPORT extern const char kEnableAppList[]; +APP_LIST_EXPORT extern const char kEnableFullscreenAppList[]; APP_LIST_EXPORT extern const char kEnableSyncAppList[]; APP_LIST_EXPORT extern const char kDisableSyncAppList[]; APP_LIST_EXPORT extern const char kEnableDriveSearchInChromeLauncher[]; @@ -41,6 +42,8 @@ bool APP_LIST_EXPORT IsAnswerCardEnabled(); +bool APP_LIST_EXPORT IsFullscreenAppListEnabled(); + } // namespace switches } // namespace app_list
diff --git a/ui/app_list/demo/app_list_demo_views.cc b/ui/app_list/demo/app_list_demo_views.cc index d21cdaf..8f0a806b 100644 --- a/ui/app_list/demo/app_list_demo_views.cc +++ b/ui/app_list/demo/app_list_demo_views.cc
@@ -60,8 +60,8 @@ gfx::NativeView container = window_context; view_ = new app_list::AppListView(this); - view_->InitAsBubble(container, 0); - view_->SetAnchorPoint(gfx::Point(300, 300)); + view_->Initialize(container, 0); + view_->MaybeSetAnchorPoint(gfx::Point(300, 300)); // Populate some apps. GetTestModel()->PopulateApps(kInitialItems);
diff --git a/ui/app_list/presenter/app_list_presenter_impl_unittest.cc b/ui/app_list/presenter/app_list_presenter_impl_unittest.cc index 372b8d16..6edb9875 100644 --- a/ui/app_list/presenter/app_list_presenter_impl_unittest.cc +++ b/ui/app_list/presenter/app_list_presenter_impl_unittest.cc
@@ -44,7 +44,7 @@ int current_apps_page) override { init_called_ = true; view_ = view; - view->InitAsBubble(container_, current_apps_page); + view->Initialize(container_, current_apps_page); } void OnShown(int64_t display_id) override { on_shown_called_ = true; } void OnDismissed() override { on_dismissed_called_ = true; }
diff --git a/ui/app_list/views/app_list_view.cc b/ui/app_list/views/app_list_view.cc index 2a1be91f..1278828 100644 --- a/ui/app_list/views/app_list_view.cc +++ b/ui/app_list/views/app_list_view.cc
@@ -31,6 +31,8 @@ #include "ui/compositor/layer.h" #include "ui/compositor/layer_animation_observer.h" #include "ui/compositor/scoped_layer_animation_settings.h" +#include "ui/display/display.h" +#include "ui/display/screen.h" #include "ui/gfx/canvas.h" #include "ui/gfx/geometry/insets.h" #include "ui/gfx/image/image_skia.h" @@ -129,10 +131,7 @@ // An animation observer to hide the view at the end of the animation. class HideViewAnimationObserver : public ui::ImplicitAnimationObserver { public: - HideViewAnimationObserver() - : frame_(NULL), - target_(NULL) { - } + HideViewAnimationObserver() : frame_(NULL), target_(NULL) {} ~HideViewAnimationObserver() override { if (target_) @@ -190,37 +189,22 @@ RemoveAllChildViews(true); } -void AppListView::InitAsBubble(gfx::NativeView parent, int initial_apps_page) { +void AppListView::Initialize(gfx::NativeView parent, int initial_apps_page) { base::Time start_time = base::Time::Now(); - InitContents(parent, initial_apps_page); - AddAccelerator(ui::Accelerator(ui::VKEY_ESCAPE, ui::EF_NONE)); - set_margins(gfx::Insets()); - set_parent_window(parent); - set_close_on_deactivate(false); - set_shadow(views::BubbleBorder::NO_ASSETS); set_color(kContentsBackgroundColor); - // This creates the app list widget. (Before this, child widgets cannot be - // created.) - views::BubbleDialogDelegateView::CreateBubble(this); + set_parent_window(parent); - SetBubbleArrow(views::BubbleBorder::FLOAT); - // We can now create the internal widgets. + if (switches::IsFullscreenAppListEnabled()) + InitializeFullscreen(parent, initial_apps_page); + else + InitializeBubble(parent, initial_apps_page); + InitChildWidgets(); - - aura::Window* window = GetWidget()->GetNativeWindow(); - window->SetEventTargeter(base::MakeUnique<views::BubbleWindowTargeter>(this)); - - const int kOverlayCornerRadius = - GetBubbleFrameView()->bubble_border()->GetBorderCornerRadius(); - overlay_view_ = new AppListOverlayView(kOverlayCornerRadius); - overlay_view_->SetBoundsRect(GetContentsBounds()); AddChildView(overlay_view_); - if (delegate_) delegate_->ViewInitialized(); - UMA_HISTOGRAM_TIMES("Apps.AppListCreationTime", base::Time::Now() - start_time); } @@ -231,8 +215,10 @@ GetBubbleFrameView()->SchedulePaint(); } -void AppListView::SetAnchorPoint(const gfx::Point& anchor_point) { - SetAnchorRect(gfx::Rect(anchor_point, gfx::Size())); +void AppListView::MaybeSetAnchorPoint(const gfx::Point& anchor_point) { + // if the AppListView is a bubble + if (!switches::IsFullscreenAppListEnabled()) + SetAnchorRect(gfx::Rect(anchor_point, gfx::Size())); } void AppListView::SetDragAndDropHostOfCurrentAppList( @@ -250,7 +236,9 @@ } void AppListView::UpdateBounds() { - SizeToContents(); + // if the AppListView is a bubble + if (!switches::IsFullscreenAppListEnabled()) + SizeToContents(); } void AppListView::SetAppListOverlayVisible(bool visible) { @@ -304,6 +292,10 @@ } } +const char* AppListView::GetClassName() const { + return "AppListView"; +} + bool AppListView::ShouldHandleSystemCommands() const { return true; } @@ -343,7 +335,6 @@ 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_); @@ -410,9 +401,49 @@ app_list_main_view_->contents_view()->Layout(); } -void AppListView::OnBeforeBubbleWidgetInit( - views::Widget::InitParams* params, - views::Widget* widget) const { +void AppListView::InitializeFullscreen(gfx::NativeView parent, + int initial_apps_page) { + const gfx::Rect& display_work_area_bounds = + display::Screen::GetScreen()->GetDisplayNearestView(parent).work_area(); + 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.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 = display_work_area_bounds; + widget->Init(app_list_overlay_view_params); + widget->GetLayer()->SetBackgroundBlur(10); + + overlay_view_ = new AppListOverlayView(0 /* no corners */); +} + +void AppListView::InitializeBubble(gfx::NativeView parent, + int initial_apps_page) { + set_margins(gfx::Insets()); + set_close_on_deactivate(false); + set_shadow(views::BubbleBorder::NO_ASSETS); + + // This creates the app list widget. (Before this, child widgets cannot be + // created.) + views::BubbleDialogDelegateView::CreateBubble(this); + + SetBubbleArrow(views::BubbleBorder::FLOAT); + // We can now create the internal widgets. + + aura::Window* window = GetWidget()->GetNativeWindow(); + window->SetEventTargeter(base::MakeUnique<views::BubbleWindowTargeter>(this)); + + const int kOverlayCornerRadius = + GetBubbleFrameView()->bubble_border()->GetBorderCornerRadius(); + overlay_view_ = new AppListOverlayView(kOverlayCornerRadius); + overlay_view_->SetBoundsRect(GetContentsBounds()); +} + +void AppListView::OnBeforeBubbleWidgetInit(views::Widget::InitParams* params, + views::Widget* widget) const { if (!params->native_widget) { views::ViewsDelegate* views_delegate = views::ViewsDelegate::GetInstance(); if (views_delegate && !views_delegate->native_widget_factory().is_null()) { @@ -441,8 +472,7 @@ DCHECK(mask); DCHECK(GetBubbleFrameView()); - mask->addRect(gfx::RectToSkRect( - GetBubbleFrameView()->GetContentsBounds())); + mask->addRect(gfx::RectToSkRect(GetBubbleFrameView()->GetContentsBounds())); } bool AppListView::AcceleratorPressed(const ui::Accelerator& accelerator) { @@ -475,8 +505,8 @@ gfx::Rect speech_bounds = centered_bounds; int preferred_height = speech_view_->GetPreferredSize().height(); speech_bounds.Inset(kSpeechUIMargin, kSpeechUIMargin); - speech_bounds.set_height(std::min(speech_bounds.height(), - preferred_height)); + speech_bounds.set_height( + std::min(speech_bounds.height(), preferred_height)); speech_bounds.Inset(-speech_view_->GetInsets()); speech_view_->SetBoundsRect(speech_bounds); } @@ -522,8 +552,7 @@ animation_observer_->set_frame(GetBubbleFrameView()); gfx::Transform speech_transform; - speech_transform.Translate( - 0, SkFloatToMScalar(kSpeechUIAppearingPosition)); + speech_transform.Translate(0, SkFloatToMScalar(kSpeechUIAppearingPosition)); if (will_appear) speech_view_->layer()->SetTransform(speech_transform);
diff --git a/ui/app_list/views/app_list_view.h b/ui/app_list/views/app_list_view.h index fb3b061e..cbdb1d89 100644 --- a/ui/app_list/views/app_list_view.h +++ b/ui/app_list/views/app_list_view.h
@@ -38,16 +38,18 @@ explicit AppListView(AppListViewDelegate* delegate); ~AppListView() override; - // Initializes the widget. - void InitAsBubble(gfx::NativeView parent, int initial_apps_page); + // 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); - void SetAnchorPoint(const gfx::Point& anchor_point); + void MaybeSetAnchorPoint(const gfx::Point& anchor_point); // If |drag_and_drop_host| is not NULL it will be called upon drag and drop // operations outside the application list. This has to be called after - // InitAsBubble was called since the app list object needs to exist so that + // Initialize was called since the app list object needs to exist so that // it can set the host. void SetDragAndDropHostOfCurrentAppList( ApplicationDragAndDropHost* drag_and_drop_host); @@ -69,6 +71,7 @@ // Overridden from views::View: gfx::Size GetPreferredSize() const override; void OnPaint(gfx::Canvas* canvas) override; + const char* GetClassName() const override; // WidgetDelegate overrides: bool ShouldHandleSystemCommands() const override; @@ -93,6 +96,12 @@ void InitChildWidgets(); + // Initializes the widget for fullscreen mode. + void InitializeFullscreen(gfx::NativeView parent, int initial_apps_page); + + // Initializes the widget as a bubble. + void InitializeBubble(gfx::NativeView parent, int initial_apps_page); + // Overridden from views::BubbleDialogDelegateView: void OnBeforeBubbleWidgetInit(views::Widget::InitParams* params, views::Widget* widget) const override; @@ -117,8 +126,8 @@ SpeechView* speech_view_; 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_|. + views::Widget* search_box_widget_; // Owned by the app list's widget. + SearchBoxView* search_box_view_; // Owned by |search_box_widget_|. // A semi-transparent white overlay that covers the app list while dialogs are // open.
diff --git a/ui/app_list/views/app_list_view_unittest.cc b/ui/app_list/views/app_list_view_unittest.cc index a93a966..56e2bdd 100644 --- a/ui/app_list/views/app_list_view_unittest.cc +++ b/ui/app_list/views/app_list_view_unittest.cc
@@ -172,8 +172,8 @@ view_ = new app_list::AppListView(delegate_.get()); // Initialize centered around a point that ensures the window is wholly shown. - view_->InitAsBubble(parent, 0); - view_->SetAnchorPoint(gfx::Point(300, 300)); + view_->Initialize(parent, 0); + view_->MaybeSetAnchorPoint(gfx::Point(300, 300)); } AppListViewTestContext::~AppListViewTestContext() {
diff --git a/ui/aura/window.h b/ui/aura/window.h index 2996584..c50ccd0d 100644 --- a/ui/aura/window.h +++ b/ui/aura/window.h
@@ -175,7 +175,7 @@ // LayoutManager may adjust the bounds. void SetBounds(const gfx::Rect& new_bounds); - // Changes the bounds of the window in the screen coordintates. + // Changes the bounds of the window in the screen coordinates. // If present, the window's parent's LayoutManager may adjust the bounds. void SetBoundsInScreen(const gfx::Rect& new_bounds_in_screen_coords, const display::Display& dst_display);